Browse Source

js-executor kafka add oauthbearer provider

pull/15098/head
Jonas Koch 5 months ago
parent
commit
f7e356cd36
No known key found for this signature in database GPG Key ID: F85C2585710855CE
  1. 5
      msa/js-executor/config/custom-environment-variables.yml
  2. 2
      msa/js-executor/package.json
  3. 25
      msa/js-executor/queue/kafkaTemplate.ts
  4. 67
      msa/js-executor/queue/oAuthBearerProvider.ts
  5. 88
      msa/js-executor/yarn.lock

5
msa/js-executor/config/custom-environment-variables.yml

@ -54,6 +54,11 @@ kafka:
mechanism: "TB_QUEUE_KAFKA_CONFLUENT_SASL_MECHANISM"
username: "TB_QUEUE_KAFKA_CONFLUENT_USERNAME"
password: "TB_QUEUE_KAFKA_CONFLUENT_PASSWORD"
oauth:
client_id: "TB_QUEUE_KAFKA_CONFLUENT_OAUTH_CLIENT_ID"
client_secret: "TB_QUEUE_KAFKA_CONFLUENT_OAUTH_CLIENT_SECRET"
endpoint_url: "TB_QUEUE_KAFKA_CONFLUENT_OAUTH_ENDPOINT_URL"
refresh_threshold: "TB_QUEUE_KAFKA_CONFLUENT_OAUTH_REFRESH_THRESHOLD"
logger:
level: "LOGGER_LEVEL"

2
msa/js-executor/package.json

@ -13,11 +13,13 @@
"build": "tsc"
},
"dependencies": {
"@types/simple-oauth2": "^5.0.8",
"config": "^4.1.1",
"express": "^5.1.0",
"js-yaml": "^4.1.1",
"kafkajs": "^2.2.4",
"long": "^5.3.2",
"simple-oauth2": "^5.1.0",
"uuid-parse": "^1.1.0",
"winston": "^3.17.0",
"winston-daily-rotate-file": "^5.0.0"

25
msa/js-executor/queue/kafkaTemplate.ts

@ -19,6 +19,7 @@ import fs from 'node:fs';
import { _logger, KafkaJsWinstonLogCreator } from '../config/logger';
import { JsInvokeMessageProcessor } from '../api/jsInvokeMessageProcessor'
import { IQueue } from './queue.models';
import {oauthBearerProvider} from './oAuthBearerProvider';
import {
Admin,
CompressionTypes,
@ -89,11 +90,25 @@ export class KafkaTemplate implements IQueue {
kafkaConfig['connectionTimeout'] = this.connectionTimeout;
if (useConfluent) {
kafkaConfig['sasl'] = {
mechanism: config.get('kafka.confluent.sasl.mechanism') as any,
username: config.get('kafka.confluent.username'),
password: config.get('kafka.confluent.password')
};
let saslMechanism = config.get('kafka.confluent.sasl.mechanism') as String
if(saslMechanism.toLowerCase() == "oauthbearer"){
kafkaConfig['sasl'] = {
mechanism: "oauthbearer",
oauthBearerProvider: oauthBearerProvider({
clientId: config.get('kafka.confluent.oauth.client_id'),
clientSecret: config.get('kafka.confluent.oauth.client_secret'),
host: config.get('kafka.confluent.oauth.endpoint_url'),
refreshThresholdMs: config.get('kafka.confluent.oauth.refresh_threshold'),
})
};
}
else{
kafkaConfig['sasl'] = {
mechanism: config.get('kafka.confluent.sasl.mechanism') as any,
username: config.get('kafka.confluent.username'),
password: config.get('kafka.confluent.password')
};
}
kafkaConfig['ssl'] = true;
}

67
msa/js-executor/queue/oAuthBearerProvider.ts

@ -0,0 +1,67 @@
///
/// Copyright © 2016-2026 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { AccessToken, ClientCredentials } from 'simple-oauth2'
interface OauthBearerProviderOptions {
clientId: string;
clientSecret: string;
host: string;
refreshThresholdMs: number;
}
export const oauthBearerProvider = (options: OauthBearerProviderOptions) => {
const client = new ClientCredentials({
client: {
id: options.clientId,
secret: options.clientSecret
},
auth: {
tokenHost: options.host
}
});
let tokenPromise: Promise<string>;
let accessToken: AccessToken;
async function refreshToken():Promise<string>{
try {
if (accessToken == null) {
accessToken = await client.getToken({})
}
if (accessToken.expired(options.refreshThresholdMs / 1000)) {
accessToken = await accessToken.refresh()
}
let expires_in = typeof accessToken.token.expires_in === "number" ? accessToken.token.expires_in : 0; //throw exception
const nextRefresh = expires_in * 1000 - options.refreshThresholdMs;
setTimeout(() => {
tokenPromise = refreshToken()
}, nextRefresh);
let access_token = typeof accessToken.token.access_token === "string" ? accessToken.token.access_token : ""; //throw exception
return access_token;
} catch (error) {
throw error;
}
}
tokenPromise = refreshToken();
return async function () {
return {
value: await tokenPromise
}
}
};

88
msa/js-executor/yarn.lock

@ -59,6 +59,44 @@
enabled "2.0.x"
kuler "^2.0.0"
"@hapi/boom@^10.0.1":
version "10.0.1"
resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-10.0.1.tgz#ebb14688275ae150aa6af788dbe482e6a6062685"
integrity sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA==
dependencies:
"@hapi/hoek" "^11.0.2"
"@hapi/bourne@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-3.0.0.tgz#f11fdf7dda62fe8e336fa7c6642d9041f30356d7"
integrity sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==
"@hapi/hoek@^11.0.2", "@hapi/hoek@^11.0.4":
version "11.0.7"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-11.0.7.tgz#56a920793e0a42d10e530da9a64cc0d3919c4002"
integrity sha512-HV5undWkKzcB4RZUusqOpcgxOaq6VOAH7zhhIr2g3G8NF/MlFO75SjOr2NfuSx0Mh40+1FqCkagKLJRykUWoFQ==
"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0":
version "9.3.0"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb"
integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==
"@hapi/topo@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012"
integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==
dependencies:
"@hapi/hoek" "^9.0.0"
"@hapi/wreck@^18.0.0":
version "18.1.0"
resolved "https://registry.yarnpkg.com/@hapi/wreck/-/wreck-18.1.0.tgz#68e631fc7568ebefc6252d5b86cb804466c8dbe6"
integrity sha512-0z6ZRCmFEfV/MQqkQomJ7sl/hyxvcZM7LtuVqN3vdAO4vM9eBbowl0kaqQj9EJJQab+3Uuh1GxbGIBFy4NfJ4w==
dependencies:
"@hapi/boom" "^10.0.1"
"@hapi/bourne" "^3.0.0"
"@hapi/hoek" "^11.0.2"
"@isaacs/fs-minipass@^4.0.0":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz#2d59ae3ab4b38fb4270bfa23d30f8e2e86c7fe32"
@ -100,6 +138,23 @@
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
"@sideway/address@^4.1.5":
version "4.1.5"
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5"
integrity sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==
dependencies:
"@hapi/hoek" "^9.0.0"
"@sideway/formula@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f"
integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==
"@sideway/pinpoint@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df"
integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==
"@tsconfig/node10@^1.0.7":
version "1.0.11"
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2"
@ -210,6 +265,11 @@
"@types/node" "*"
"@types/send" "*"
"@types/simple-oauth2@^5.0.8":
version "5.0.8"
resolved "https://registry.yarnpkg.com/@types/simple-oauth2/-/simple-oauth2-5.0.8.tgz#ec0c51a7df267e5d41b0b063aecdd34a312e9310"
integrity sha512-TehQqoOGdy3/rmFsCEGgnt1f4JhUCA0joWemGGCTbVYvoZvfBjkRsBFYmz8k0V/sn2XQZHe33L4lWxqMhIO3tQ==
"@types/triple-beam@^1.3.2":
version "1.3.5"
resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c"
@ -539,6 +599,13 @@ debug@4, debug@^4, debug@^4.3.5, debug@^4.4.0:
dependencies:
ms "^2.1.3"
debug@^4.3.4:
version "4.4.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
dependencies:
ms "^2.1.3"
decompress-response@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
@ -945,6 +1012,17 @@ isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
joi@^17.6.4:
version "17.13.3"
resolved "https://registry.yarnpkg.com/joi/-/joi-17.13.3.tgz#0f5cc1169c999b30d344366d384b12d92558bcec"
integrity sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==
dependencies:
"@hapi/hoek" "^9.3.0"
"@hapi/topo" "^5.1.0"
"@sideway/address" "^4.1.5"
"@sideway/formula" "^3.0.1"
"@sideway/pinpoint" "^2.0.0"
js-yaml@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b"
@ -1444,6 +1522,16 @@ simple-get@^4.0.0:
once "^1.3.1"
simple-concat "^1.0.0"
simple-oauth2@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/simple-oauth2/-/simple-oauth2-5.1.0.tgz#1398fe2b8f4b4066298d63c155501b31b42238f2"
integrity sha512-gWDa38Ccm4MwlG5U7AlcJxPv3lvr80dU7ARJWrGdgvOKyzSj1gr3GBPN1rABTedAYvC/LsGYoFuFxwDBPtGEbw==
dependencies:
"@hapi/hoek" "^11.0.4"
"@hapi/wreck" "^18.0.0"
debug "^4.3.4"
joi "^17.6.4"
simple-swizzle@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"

Loading…
Cancel
Save