Commit 4fb309c37ea5854b1c7650c73b48db2bd86d5d56

Authored by YevhenBondarenko
1 parent 12973cec

moved kafka from service.js to own module

... ... @@ -46,17 +46,17 @@ import java.util.concurrent.atomic.AtomicInteger;
46 46 @Service
47 47 public class RemoteJsInvokeService extends AbstractJsInvokeService {
48 48
49   - @Value("${js.remote.max_requests_timeout}")
  49 + @Value("${queue.js.max_requests_timeout}")
50 50 private long maxRequestsTimeout;
51 51
52 52 @Getter
53   - @Value("${js.remote.max_errors}")
  53 +// @Value("${queue.js.max_errors}")
54 54 private int maxErrors;
55 55
56   - @Value("${js.remote.max_black_list_duration_sec:60}")
  56 + @Value("${queue.js.max_black_list_duration_sec:60}")
57 57 private int maxBlackListDurationSec;
58 58
59   - @Value("${js.remote.stats.enabled:false}")
  59 + @Value("${queue.js.stats.enabled:false}")
60 60 private boolean statsEnabled;
61 61
62 62 private final AtomicInteger kafkaPushedMsgs = new AtomicInteger(0);
... ... @@ -65,7 +65,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
65 65 private final AtomicInteger kafkaFailedMsgs = new AtomicInteger(0);
66 66 private final AtomicInteger kafkaTimeoutMsgs = new AtomicInteger(0);
67 67
68   - @Scheduled(fixedDelayString = "${js.remote.stats.print_interval_ms}")
  68 +// @Scheduled(fixedDelayString = "${queue.js.stats.print_interval_ms}")
69 69 public void printStats() {
70 70 if (statsEnabled) {
71 71 int pushedMsgs = kafkaPushedMsgs.getAndSet(0);
... ...
... ... @@ -415,7 +415,7 @@ state:
415 415 persistToTelemetry: "${PERSIST_STATE_TO_TELEMETRY:false}"
416 416
417 417 js:
418   - evaluator: "${JS_EVALUATOR:local}" # local/remote
  418 + evaluator: "${JS_EVALUATOR:remote}" # local/remote
419 419 # Built-in JVM JavaScript environment properties
420 420 local:
421 421 # Use Sandboxed (secured) JVM JavaScript environment
... ... @@ -582,9 +582,9 @@ queue:
582 582 print-interval-ms: "${TB_QUEUE_CORE_STATS_PRINT_INTERVAL_MS:10000}"
583 583 js:
584 584 # JS Eval request topic
585   - request_topic: "${REMOTE_JS_EVAL_REQUEST_TOPIC:js_eval.requests}"
  585 + request_topic: "${REMOTE_JS_EVAL_REQUEST_TOPIC:js.eval.requests}"
586 586 # JS Eval responses topic prefix that is combined with node id
587   - response_topic_prefix: "${REMOTE_JS_EVAL_RESPONSE_TOPIC:js_eval.responses}"
  587 + response_topic_prefix: "${REMOTE_JS_EVAL_RESPONSE_TOPIC:js.eval.responses}"
588 588 # JS Eval max pending requests
589 589 max_pending_requests: "${REMOTE_JS_MAX_PENDING_REQUESTS:10000}"
590 590 # JS Eval max request timeout
... ...
... ... @@ -31,6 +31,7 @@ const useSandbox = config.get('script.use_sandbox') === 'true';
31 31 const maxActiveScripts = Number(config.get('script.max_active_scripts'));
32 32
33 33 function JsInvokeMessageProcessor(producer) {
  34 + console.log("Kafka Producer:", producer);
34 35 this.producer = producer;
35 36 this.executor = new JsExecutor(useSandbox);
36 37 this.scriptMap = {};
... ... @@ -144,17 +145,17 @@ JsInvokeMessageProcessor.prototype.processReleaseRequest = function(requestId, r
144 145 JsInvokeMessageProcessor.prototype.sendResponse = function (requestId, responseTopic, scriptId, compileResponse, invokeResponse, releaseResponse) {
145 146 var remoteResponse = createRemoteResponse(requestId, compileResponse, invokeResponse, releaseResponse);
146 147 var rawResponse = Buffer.from(JSON.stringify(remoteResponse), 'utf8');
147   - this.producer.send(
148   - {
149   - topic: responseTopic,
150   - messages: [
151   - {
152   - key: scriptId,
153   - value: rawResponse,
154   - headers: headers
155   - }
156   - ]
157   - }
  148 + this.producer.send(responseTopic, scriptId, rawResponse, headers
  149 + // {
  150 + // topic: responseTopic,
  151 + // messages: [
  152 + // {
  153 + // key: scriptId,
  154 + // value: rawResponse,
  155 + // headers: headers
  156 + // }
  157 + // ]
  158 + // }
158 159 ).then(
159 160 () => {},
160 161 (err) => {
... ...
... ... @@ -14,6 +14,8 @@
14 14 # limitations under the License.
15 15 #
16 16
  17 +service-type: "TB_SERVICE_TYPE"
  18 +
17 19 kafka:
18 20 request_topic: "REMOTE_JS_EVAL_REQUEST_TOPIC"
19 21 bootstrap:
... ...
... ... @@ -14,6 +14,8 @@
14 14 # limitations under the License.
15 15 #
16 16
  17 +service-type: "kafka"
  18 +
17 19 kafka:
18 20 request_topic: "js.eval.requests"
19 21 bootstrap:
... ...
  1 +/*
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +const { logLevel, Kafka } = require('kafkajs');
  17 +
  18 +const config = require('config'),
  19 + JsInvokeMessageProcessor = require('../../api/jsInvokeMessageProcessor'),
  20 + logger = require('../../config/logger')._logger('main'),
  21 + KafkaJsWinstonLogCreator = require('../../config/logger').KafkaJsWinstonLogCreator;
  22 +
  23 +var kafkaClient;
  24 +var consumer;
  25 +var producer;
  26 +
  27 +function KafkaProducer() {
  28 + this.send = async (responseTopic, scriptId, rawResponse, headers) => {
  29 + return producer.send(
  30 + {
  31 + topic: responseTopic,
  32 + messages: [
  33 + {
  34 + key: scriptId,
  35 + value: rawResponse,
  36 + headers: headers
  37 + }
  38 + ]
  39 + });
  40 + }
  41 +}
  42 +
  43 +(async() => {
  44 + try {
  45 + logger.info('Starting ThingsBoard JavaScript Executor Microservice...');
  46 +
  47 + const kafkaBootstrapServers = config.get('kafka.bootstrap.servers');
  48 + const kafkaRequestTopic = config.get('kafka.request_topic');
  49 +
  50 + logger.info('Kafka Bootstrap Servers: %s', kafkaBootstrapServers);
  51 + logger.info('Kafka Requests Topic: %s', kafkaRequestTopic);
  52 +
  53 + kafkaClient = new Kafka({
  54 + brokers: kafkaBootstrapServers.split(','),
  55 + logLevel: logLevel.INFO,
  56 + logCreator: KafkaJsWinstonLogCreator
  57 + });
  58 +
  59 + consumer = kafkaClient.consumer({ groupId: 'js-executor-group' });
  60 + producer = kafkaClient.producer();
  61 + const messageProcessor = new JsInvokeMessageProcessor(new KafkaProducer());
  62 + await consumer.connect();
  63 + await producer.connect();
  64 + await consumer.subscribe({ topic: kafkaRequestTopic});
  65 +
  66 + logger.info('Started ThingsBoard JavaScript Executor Microservice.');
  67 + await consumer.run({
  68 + eachMessage: async ({ topic, partition, message }) => {
  69 + messageProcessor.onJsInvokeMessage(message);
  70 + },
  71 + });
  72 +
  73 + } catch (e) {
  74 + logger.error('Failed to start ThingsBoard JavaScript Executor Microservice: %s', e.message);
  75 + logger.error(e.stack);
  76 + exit(-1);
  77 + }
  78 +})();
  79 +
  80 +process.on('exit', () => {
  81 + exit(0);
  82 +});
  83 +
  84 +async function exit(status) {
  85 + logger.info('Exiting with status: %d ...', status);
  86 + if (consumer) {
  87 + logger.info('Stopping Kafka Consumer...');
  88 + var _consumer = consumer;
  89 + consumer = null;
  90 + try {
  91 + await _consumer.disconnect();
  92 + logger.info('Kafka Consumer stopped.');
  93 + await disconnectProducer();
  94 + process.exit(status);
  95 + } catch (e) {
  96 + logger.info('Kafka Consumer stop error.');
  97 + await disconnectProducer();
  98 + process.exit(status);
  99 + }
  100 + } else {
  101 + process.exit(status);
  102 + }
  103 +}
  104 +
  105 +async function disconnectProducer() {
  106 + if (producer) {
  107 + logger.info('Stopping Kafka Producer...');
  108 + var _producer = producer;
  109 + producer = null;
  110 + try {
  111 + await _producer.disconnect();
  112 + logger.info('Kafka Producer stopped.');
  113 + } catch (e) {
  114 + logger.info('Kafka Producer stop error.');
  115 + }
  116 + }
  117 +}
... ...
... ... @@ -13,89 +13,17 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -const { logLevel, Kafka } = require('kafkajs');
17 16
18   -const config = require('config'),
19   - JsInvokeMessageProcessor = require('./api/jsInvokeMessageProcessor'),
20   - logger = require('./config/logger')._logger('main'),
21   - KafkaJsWinstonLogCreator = require('./config/logger').KafkaJsWinstonLogCreator;
22   -
23   -var kafkaClient;
24   -var consumer;
25   -var producer;
26   -
27   -(async() => {
28   - try {
29   - logger.info('Starting ThingsBoard JavaScript Executor Microservice...');
30   -
31   - const kafkaBootstrapServers = config.get('kafka.bootstrap.servers');
32   - const kafkaRequestTopic = config.get('kafka.request_topic');
33   -
34   - logger.info('Kafka Bootstrap Servers: %s', kafkaBootstrapServers);
35   - logger.info('Kafka Requests Topic: %s', kafkaRequestTopic);
36   -
37   - kafkaClient = new Kafka({
38   - brokers: kafkaBootstrapServers.split(','),
39   - logLevel: logLevel.INFO,
40   - logCreator: KafkaJsWinstonLogCreator
41   - });
42   -
43   - consumer = kafkaClient.consumer({ groupId: 'js-executor-group' });
44   - producer = kafkaClient.producer();
45   - const messageProcessor = new JsInvokeMessageProcessor(producer);
46   - await consumer.connect();
47   - await producer.connect();
48   - await consumer.subscribe({ topic: kafkaRequestTopic});
49   -
50   - logger.info('Started ThingsBoard JavaScript Executor Microservice.');
51   - await consumer.run({
52   - eachMessage: async ({ topic, partition, message }) => {
53   - messageProcessor.onJsInvokeMessage(message);
54   - },
55   - });
56   -
57   - } catch (e) {
58   - logger.error('Failed to start ThingsBoard JavaScript Executor Microservice: %s', e.message);
59   - logger.error(e.stack);
60   - exit(-1);
61   - }
62   -})();
63   -
64   -process.on('exit', () => {
65   - exit(0);
66   -});
67   -
68   -async function exit(status) {
69   - logger.info('Exiting with status: %d ...', status);
70   - if (consumer) {
71   - logger.info('Stopping Kafka Consumer...');
72   - var _consumer = consumer;
73   - consumer = null;
74   - try {
75   - await _consumer.disconnect();
76   - logger.info('Kafka Consumer stopped.');
77   - await disconnectProducer();
78   - process.exit(status);
79   - } catch (e) {
80   - logger.info('Kafka Consumer stop error.');
81   - await disconnectProducer();
82   - process.exit(status);
83   - }
84   - } else {
85   - process.exit(status);
86   - }
  17 +const config = require('config');
  18 +
  19 +const serviceType = config.get('service-type');
  20 +switch (serviceType) {
  21 + case 'kafka':
  22 + require('./queue/kafka/kafkaTemplate');
  23 + console.log('Used kafka template.');
  24 + break;
  25 + default:
  26 + console.error('Unknown service type: ', serviceType);
  27 + process.exit(-1);
87 28 }
88 29
89   -async function disconnectProducer() {
90   - if (producer) {
91   - logger.info('Stopping Kafka Producer...');
92   - var _producer = producer;
93   - producer = null;
94   - try {
95   - await _producer.disconnect();
96   - logger.info('Kafka Producer stopped.');
97   - } catch (e) {
98   - logger.info('Kafka Producer stop error.');
99   - }
100   - }
101   -}
... ...