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,17 +46,17 @@ import java.util.concurrent.atomic.AtomicInteger;
46 @Service 46 @Service
47 public class RemoteJsInvokeService extends AbstractJsInvokeService { 47 public class RemoteJsInvokeService extends AbstractJsInvokeService {
48 48
49 - @Value("${js.remote.max_requests_timeout}") 49 + @Value("${queue.js.max_requests_timeout}")
50 private long maxRequestsTimeout; 50 private long maxRequestsTimeout;
51 51
52 @Getter 52 @Getter
53 - @Value("${js.remote.max_errors}") 53 +// @Value("${queue.js.max_errors}")
54 private int maxErrors; 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 private int maxBlackListDurationSec; 57 private int maxBlackListDurationSec;
58 58
59 - @Value("${js.remote.stats.enabled:false}") 59 + @Value("${queue.js.stats.enabled:false}")
60 private boolean statsEnabled; 60 private boolean statsEnabled;
61 61
62 private final AtomicInteger kafkaPushedMsgs = new AtomicInteger(0); 62 private final AtomicInteger kafkaPushedMsgs = new AtomicInteger(0);
@@ -65,7 +65,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService { @@ -65,7 +65,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
65 private final AtomicInteger kafkaFailedMsgs = new AtomicInteger(0); 65 private final AtomicInteger kafkaFailedMsgs = new AtomicInteger(0);
66 private final AtomicInteger kafkaTimeoutMsgs = new AtomicInteger(0); 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 public void printStats() { 69 public void printStats() {
70 if (statsEnabled) { 70 if (statsEnabled) {
71 int pushedMsgs = kafkaPushedMsgs.getAndSet(0); 71 int pushedMsgs = kafkaPushedMsgs.getAndSet(0);
@@ -415,7 +415,7 @@ state: @@ -415,7 +415,7 @@ state:
415 persistToTelemetry: "${PERSIST_STATE_TO_TELEMETRY:false}" 415 persistToTelemetry: "${PERSIST_STATE_TO_TELEMETRY:false}"
416 416
417 js: 417 js:
418 - evaluator: "${JS_EVALUATOR:local}" # local/remote 418 + evaluator: "${JS_EVALUATOR:remote}" # local/remote
419 # Built-in JVM JavaScript environment properties 419 # Built-in JVM JavaScript environment properties
420 local: 420 local:
421 # Use Sandboxed (secured) JVM JavaScript environment 421 # Use Sandboxed (secured) JVM JavaScript environment
@@ -582,9 +582,9 @@ queue: @@ -582,9 +582,9 @@ queue:
582 print-interval-ms: "${TB_QUEUE_CORE_STATS_PRINT_INTERVAL_MS:10000}" 582 print-interval-ms: "${TB_QUEUE_CORE_STATS_PRINT_INTERVAL_MS:10000}"
583 js: 583 js:
584 # JS Eval request topic 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 # JS Eval responses topic prefix that is combined with node id 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 # JS Eval max pending requests 588 # JS Eval max pending requests
589 max_pending_requests: "${REMOTE_JS_MAX_PENDING_REQUESTS:10000}" 589 max_pending_requests: "${REMOTE_JS_MAX_PENDING_REQUESTS:10000}"
590 # JS Eval max request timeout 590 # JS Eval max request timeout
@@ -31,6 +31,7 @@ const useSandbox = config.get('script.use_sandbox') === 'true'; @@ -31,6 +31,7 @@ const useSandbox = config.get('script.use_sandbox') === 'true';
31 const maxActiveScripts = Number(config.get('script.max_active_scripts')); 31 const maxActiveScripts = Number(config.get('script.max_active_scripts'));
32 32
33 function JsInvokeMessageProcessor(producer) { 33 function JsInvokeMessageProcessor(producer) {
  34 + console.log("Kafka Producer:", producer);
34 this.producer = producer; 35 this.producer = producer;
35 this.executor = new JsExecutor(useSandbox); 36 this.executor = new JsExecutor(useSandbox);
36 this.scriptMap = {}; 37 this.scriptMap = {};
@@ -144,17 +145,17 @@ JsInvokeMessageProcessor.prototype.processReleaseRequest = function(requestId, r @@ -144,17 +145,17 @@ JsInvokeMessageProcessor.prototype.processReleaseRequest = function(requestId, r
144 JsInvokeMessageProcessor.prototype.sendResponse = function (requestId, responseTopic, scriptId, compileResponse, invokeResponse, releaseResponse) { 145 JsInvokeMessageProcessor.prototype.sendResponse = function (requestId, responseTopic, scriptId, compileResponse, invokeResponse, releaseResponse) {
145 var remoteResponse = createRemoteResponse(requestId, compileResponse, invokeResponse, releaseResponse); 146 var remoteResponse = createRemoteResponse(requestId, compileResponse, invokeResponse, releaseResponse);
146 var rawResponse = Buffer.from(JSON.stringify(remoteResponse), 'utf8'); 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 ).then( 159 ).then(
159 () => {}, 160 () => {},
160 (err) => { 161 (err) => {
@@ -14,6 +14,8 @@ @@ -14,6 +14,8 @@
14 # limitations under the License. 14 # limitations under the License.
15 # 15 #
16 16
  17 +service-type: "TB_SERVICE_TYPE"
  18 +
17 kafka: 19 kafka:
18 request_topic: "REMOTE_JS_EVAL_REQUEST_TOPIC" 20 request_topic: "REMOTE_JS_EVAL_REQUEST_TOPIC"
19 bootstrap: 21 bootstrap:
@@ -14,6 +14,8 @@ @@ -14,6 +14,8 @@
14 # limitations under the License. 14 # limitations under the License.
15 # 15 #
16 16
  17 +service-type: "kafka"
  18 +
17 kafka: 19 kafka:
18 request_topic: "js.eval.requests" 20 request_topic: "js.eval.requests"
19 bootstrap: 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,89 +13,17 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 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 -}