Showing
47 changed files
with
787 additions
and
160 deletions
Too many changes to show.
To preserve performance only 47 of 76 files are displayed.
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard</groupId> | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>thingsboard</artifactId> | 24 | <artifactId>thingsboard</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <artifactId>application</artifactId> | 26 | <artifactId>application</artifactId> |
@@ -309,6 +309,18 @@ | @@ -309,6 +309,18 @@ | ||
309 | <artifactId>Java-WebSocket</artifactId> | 309 | <artifactId>Java-WebSocket</artifactId> |
310 | <scope>test</scope> | 310 | <scope>test</scope> |
311 | </dependency> | 311 | </dependency> |
312 | + <dependency> | ||
313 | + <groupId>org.springframework.boot</groupId> | ||
314 | + <artifactId>spring-boot-starter-actuator</artifactId> | ||
315 | + </dependency> | ||
316 | + <dependency> | ||
317 | + <groupId>io.micrometer</groupId> | ||
318 | + <artifactId>micrometer-core</artifactId> | ||
319 | + </dependency> | ||
320 | + <dependency> | ||
321 | + <groupId>io.micrometer</groupId> | ||
322 | + <artifactId>micrometer-registry-prometheus</artifactId> | ||
323 | + </dependency> | ||
312 | </dependencies> | 324 | </dependencies> |
313 | 325 | ||
314 | <build> | 326 | <build> |
@@ -220,6 +220,10 @@ public class ActorSystemContext { | @@ -220,6 +220,10 @@ public class ActorSystemContext { | ||
220 | @Getter | 220 | @Getter |
221 | private ClaimDevicesService claimDevicesService; | 221 | private ClaimDevicesService claimDevicesService; |
222 | 222 | ||
223 | + @Autowired | ||
224 | + @Getter | ||
225 | + private JsInvokeStats jsInvokeStats; | ||
226 | + | ||
223 | //TODO: separate context for TbCore and TbRuleEngine | 227 | //TODO: separate context for TbCore and TbRuleEngine |
224 | @Autowired(required = false) | 228 | @Autowired(required = false) |
225 | @Getter | 229 | @Getter |
@@ -273,19 +277,14 @@ public class ActorSystemContext { | @@ -273,19 +277,14 @@ public class ActorSystemContext { | ||
273 | @Getter | 277 | @Getter |
274 | private long statisticsPersistFrequency; | 278 | private long statisticsPersistFrequency; |
275 | 279 | ||
276 | - @Getter | ||
277 | - private final AtomicInteger jsInvokeRequestsCount = new AtomicInteger(0); | ||
278 | - @Getter | ||
279 | - private final AtomicInteger jsInvokeResponsesCount = new AtomicInteger(0); | ||
280 | - @Getter | ||
281 | - private final AtomicInteger jsInvokeFailuresCount = new AtomicInteger(0); | ||
282 | 280 | ||
283 | @Scheduled(fixedDelayString = "${actors.statistics.js_print_interval_ms}") | 281 | @Scheduled(fixedDelayString = "${actors.statistics.js_print_interval_ms}") |
284 | public void printStats() { | 282 | public void printStats() { |
285 | if (statisticsEnabled) { | 283 | if (statisticsEnabled) { |
286 | - if (jsInvokeRequestsCount.get() > 0 || jsInvokeResponsesCount.get() > 0 || jsInvokeFailuresCount.get() > 0) { | 284 | + if (jsInvokeStats.getRequests() > 0 || jsInvokeStats.getResponses() > 0 || jsInvokeStats.getFailures() > 0) { |
287 | log.info("Rule Engine JS Invoke Stats: requests [{}] responses [{}] failures [{}]", | 285 | log.info("Rule Engine JS Invoke Stats: requests [{}] responses [{}] failures [{}]", |
288 | - jsInvokeRequestsCount.getAndSet(0), jsInvokeResponsesCount.getAndSet(0), jsInvokeFailuresCount.getAndSet(0)); | 286 | + jsInvokeStats.getRequests(), jsInvokeStats.getResponses(), jsInvokeStats.getFailures()); |
287 | + jsInvokeStats.reset(); | ||
289 | } | 288 | } |
290 | } | 289 | } |
291 | } | 290 | } |
@@ -293,21 +293,21 @@ class DefaultTbContext implements TbContext { | @@ -293,21 +293,21 @@ class DefaultTbContext implements TbContext { | ||
293 | @Override | 293 | @Override |
294 | public void logJsEvalRequest() { | 294 | public void logJsEvalRequest() { |
295 | if (mainCtx.isStatisticsEnabled()) { | 295 | if (mainCtx.isStatisticsEnabled()) { |
296 | - mainCtx.getJsInvokeRequestsCount().incrementAndGet(); | 296 | + mainCtx.getJsInvokeStats().incrementRequests(); |
297 | } | 297 | } |
298 | } | 298 | } |
299 | 299 | ||
300 | @Override | 300 | @Override |
301 | public void logJsEvalResponse() { | 301 | public void logJsEvalResponse() { |
302 | if (mainCtx.isStatisticsEnabled()) { | 302 | if (mainCtx.isStatisticsEnabled()) { |
303 | - mainCtx.getJsInvokeResponsesCount().incrementAndGet(); | 303 | + mainCtx.getJsInvokeStats().incrementResponses(); |
304 | } | 304 | } |
305 | } | 305 | } |
306 | 306 | ||
307 | @Override | 307 | @Override |
308 | public void logJsEvalFailure() { | 308 | public void logJsEvalFailure() { |
309 | if (mainCtx.isStatisticsEnabled()) { | 309 | if (mainCtx.isStatisticsEnabled()) { |
310 | - mainCtx.getJsInvokeFailuresCount().incrementAndGet(); | 310 | + mainCtx.getJsInvokeStats().incrementFailures(); |
311 | } | 311 | } |
312 | } | 312 | } |
313 | 313 |
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 | +package org.thingsboard.server.service.metrics; | ||
17 | + | ||
18 | +import io.micrometer.core.instrument.Counter; | ||
19 | + | ||
20 | +public class StubCounter implements Counter { | ||
21 | + @Override | ||
22 | + public void increment(double amount) {} | ||
23 | + | ||
24 | + @Override | ||
25 | + public double count() { | ||
26 | + return 0; | ||
27 | + } | ||
28 | + | ||
29 | + @Override | ||
30 | + public Id getId() { | ||
31 | + return null; | ||
32 | + } | ||
33 | +} |
@@ -53,6 +53,7 @@ import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | @@ -53,6 +53,7 @@ import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | ||
53 | import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; | 53 | import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; |
54 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; | 54 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; |
55 | import org.thingsboard.server.service.state.DeviceStateService; | 55 | import org.thingsboard.server.service.state.DeviceStateService; |
56 | +import org.thingsboard.server.service.stats.StatsCounterFactory; | ||
56 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; | 57 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; |
57 | import org.thingsboard.server.service.subscription.TbLocalSubscriptionService; | 58 | import org.thingsboard.server.service.subscription.TbLocalSubscriptionService; |
58 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; | 59 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; |
@@ -88,18 +89,19 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -88,18 +89,19 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
88 | private final TbLocalSubscriptionService localSubscriptionService; | 89 | private final TbLocalSubscriptionService localSubscriptionService; |
89 | private final SubscriptionManagerService subscriptionManagerService; | 90 | private final SubscriptionManagerService subscriptionManagerService; |
90 | private final TbCoreDeviceRpcService tbCoreDeviceRpcService; | 91 | private final TbCoreDeviceRpcService tbCoreDeviceRpcService; |
91 | - private final TbCoreConsumerStats stats = new TbCoreConsumerStats(); | 92 | + private final TbCoreConsumerStats stats; |
92 | 93 | ||
93 | public DefaultTbCoreConsumerService(TbCoreQueueFactory tbCoreQueueFactory, ActorSystemContext actorContext, | 94 | public DefaultTbCoreConsumerService(TbCoreQueueFactory tbCoreQueueFactory, ActorSystemContext actorContext, |
94 | DeviceStateService stateService, TbLocalSubscriptionService localSubscriptionService, | 95 | DeviceStateService stateService, TbLocalSubscriptionService localSubscriptionService, |
95 | SubscriptionManagerService subscriptionManagerService, DataDecodingEncodingService encodingService, | 96 | SubscriptionManagerService subscriptionManagerService, DataDecodingEncodingService encodingService, |
96 | - TbCoreDeviceRpcService tbCoreDeviceRpcService) { | 97 | + TbCoreDeviceRpcService tbCoreDeviceRpcService, StatsCounterFactory counterFactory) { |
97 | super(actorContext, encodingService, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer()); | 98 | super(actorContext, encodingService, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer()); |
98 | this.mainConsumer = tbCoreQueueFactory.createToCoreMsgConsumer(); | 99 | this.mainConsumer = tbCoreQueueFactory.createToCoreMsgConsumer(); |
99 | this.stateService = stateService; | 100 | this.stateService = stateService; |
100 | this.localSubscriptionService = localSubscriptionService; | 101 | this.localSubscriptionService = localSubscriptionService; |
101 | this.subscriptionManagerService = subscriptionManagerService; | 102 | this.subscriptionManagerService = subscriptionManagerService; |
102 | this.tbCoreDeviceRpcService = tbCoreDeviceRpcService; | 103 | this.tbCoreDeviceRpcService = tbCoreDeviceRpcService; |
104 | + this.stats = new TbCoreConsumerStats(counterFactory); | ||
103 | } | 105 | } |
104 | 106 | ||
105 | @PostConstruct | 107 | @PostConstruct |
@@ -235,6 +237,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -235,6 +237,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
235 | public void printStats() { | 237 | public void printStats() { |
236 | if (statsEnabled) { | 238 | if (statsEnabled) { |
237 | stats.printStats(); | 239 | stats.printStats(); |
240 | + stats.reset(); | ||
238 | } | 241 | } |
239 | } | 242 | } |
240 | 243 |
@@ -52,6 +52,7 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrateg | @@ -52,6 +52,7 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrateg | ||
52 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | 52 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; |
53 | import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; | 53 | import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; |
54 | import org.thingsboard.server.service.stats.RuleEngineStatisticsService; | 54 | import org.thingsboard.server.service.stats.RuleEngineStatisticsService; |
55 | +import org.thingsboard.server.service.stats.StatsCounterFactory; | ||
55 | 56 | ||
56 | import javax.annotation.PostConstruct; | 57 | import javax.annotation.PostConstruct; |
57 | import javax.annotation.PreDestroy; | 58 | import javax.annotation.PreDestroy; |
@@ -79,6 +80,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -79,6 +80,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
79 | @Value("${queue.rule-engine.stats.enabled:true}") | 80 | @Value("${queue.rule-engine.stats.enabled:true}") |
80 | private boolean statsEnabled; | 81 | private boolean statsEnabled; |
81 | 82 | ||
83 | + private final StatsCounterFactory counterFactory; | ||
82 | private final TbRuleEngineSubmitStrategyFactory submitStrategyFactory; | 84 | private final TbRuleEngineSubmitStrategyFactory submitStrategyFactory; |
83 | private final TbRuleEngineProcessingStrategyFactory processingStrategyFactory; | 85 | private final TbRuleEngineProcessingStrategyFactory processingStrategyFactory; |
84 | private final TbRuleEngineQueueFactory tbRuleEngineQueueFactory; | 86 | private final TbRuleEngineQueueFactory tbRuleEngineQueueFactory; |
@@ -95,7 +97,8 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -95,7 +97,8 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
95 | TbQueueRuleEngineSettings ruleEngineSettings, | 97 | TbQueueRuleEngineSettings ruleEngineSettings, |
96 | TbRuleEngineQueueFactory tbRuleEngineQueueFactory, RuleEngineStatisticsService statisticsService, | 98 | TbRuleEngineQueueFactory tbRuleEngineQueueFactory, RuleEngineStatisticsService statisticsService, |
97 | ActorSystemContext actorContext, DataDecodingEncodingService encodingService, | 99 | ActorSystemContext actorContext, DataDecodingEncodingService encodingService, |
98 | - TbRuleEngineDeviceRpcService tbDeviceRpcService) { | 100 | + TbRuleEngineDeviceRpcService tbDeviceRpcService, |
101 | + StatsCounterFactory counterFactory) { | ||
99 | super(actorContext, encodingService, tbRuleEngineQueueFactory.createToRuleEngineNotificationsMsgConsumer()); | 102 | super(actorContext, encodingService, tbRuleEngineQueueFactory.createToRuleEngineNotificationsMsgConsumer()); |
100 | this.statisticsService = statisticsService; | 103 | this.statisticsService = statisticsService; |
101 | this.ruleEngineSettings = ruleEngineSettings; | 104 | this.ruleEngineSettings = ruleEngineSettings; |
@@ -103,6 +106,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -103,6 +106,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
103 | this.submitStrategyFactory = submitStrategyFactory; | 106 | this.submitStrategyFactory = submitStrategyFactory; |
104 | this.processingStrategyFactory = processingStrategyFactory; | 107 | this.processingStrategyFactory = processingStrategyFactory; |
105 | this.tbDeviceRpcService = tbDeviceRpcService; | 108 | this.tbDeviceRpcService = tbDeviceRpcService; |
109 | + this.counterFactory = counterFactory; | ||
106 | } | 110 | } |
107 | 111 | ||
108 | @PostConstruct | 112 | @PostConstruct |
@@ -111,7 +115,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -111,7 +115,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
111 | for (TbRuleEngineQueueConfiguration configuration : ruleEngineSettings.getQueues()) { | 115 | for (TbRuleEngineQueueConfiguration configuration : ruleEngineSettings.getQueues()) { |
112 | consumerConfigurations.putIfAbsent(configuration.getName(), configuration); | 116 | consumerConfigurations.putIfAbsent(configuration.getName(), configuration); |
113 | consumers.computeIfAbsent(configuration.getName(), queueName -> tbRuleEngineQueueFactory.createToRuleEngineMsgConsumer(configuration)); | 117 | consumers.computeIfAbsent(configuration.getName(), queueName -> tbRuleEngineQueueFactory.createToRuleEngineMsgConsumer(configuration)); |
114 | - consumerStats.put(configuration.getName(), new TbRuleEngineConsumerStats(configuration.getName())); | 118 | + consumerStats.put(configuration.getName(), new TbRuleEngineConsumerStats(configuration.getName(), counterFactory)); |
115 | } | 119 | } |
116 | submitExecutor = Executors.newSingleThreadExecutor(); | 120 | submitExecutor = Executors.newSingleThreadExecutor(); |
117 | } | 121 | } |
@@ -269,6 +273,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -269,6 +273,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
269 | consumerStats.forEach((queue, stats) -> { | 273 | consumerStats.forEach((queue, stats) -> { |
270 | stats.printStats(); | 274 | stats.printStats(); |
271 | statisticsService.reportQueueStats(ts, stats); | 275 | statisticsService.reportQueueStats(ts, stats); |
276 | + stats.reset(); | ||
272 | }); | 277 | }); |
273 | } | 278 | } |
274 | } | 279 | } |
@@ -17,76 +17,124 @@ package org.thingsboard.server.service.queue; | @@ -17,76 +17,124 @@ package org.thingsboard.server.service.queue; | ||
17 | 17 | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | import org.thingsboard.server.gen.transport.TransportProtos; | 19 | import org.thingsboard.server.gen.transport.TransportProtos; |
20 | +import org.thingsboard.server.service.stats.StatsCounter; | ||
21 | +import org.thingsboard.server.service.stats.StatsCounterFactory; | ||
22 | +import org.thingsboard.server.service.stats.StatsType; | ||
20 | 23 | ||
24 | +import java.util.*; | ||
21 | import java.util.concurrent.atomic.AtomicInteger; | 25 | import java.util.concurrent.atomic.AtomicInteger; |
22 | 26 | ||
23 | @Slf4j | 27 | @Slf4j |
24 | public class TbCoreConsumerStats { | 28 | public class TbCoreConsumerStats { |
29 | + public static final String TOTAL_MSGS = "totalMsgs"; | ||
30 | + public static final String SESSION_EVENTS = "sessionEvents"; | ||
31 | + public static final String GET_ATTRIBUTE = "getAttr"; | ||
32 | + public static final String ATTRIBUTE_SUBSCRIBES = "subToAttr"; | ||
33 | + public static final String RPC_SUBSCRIBES = "subToRpc"; | ||
34 | + public static final String TO_DEVICE_RPC_CALL_RESPONSES = "toDevRpc"; | ||
35 | + public static final String SUBSCRIPTION_INFO = "subInfo"; | ||
36 | + public static final String DEVICE_CLAIMS = "claimDevice"; | ||
37 | + public static final String DEVICE_STATES = "deviceState"; | ||
38 | + public static final String SUBSCRIPTION_MSGS = "subMsgs"; | ||
39 | + public static final String TO_CORE_NOTIFICATIONS = "coreNfs"; | ||
25 | 40 | ||
26 | - private final AtomicInteger totalCounter = new AtomicInteger(0); | ||
27 | - private final AtomicInteger sessionEventCounter = new AtomicInteger(0); | ||
28 | - private final AtomicInteger getAttributesCounter = new AtomicInteger(0); | ||
29 | - private final AtomicInteger subscribeToAttributesCounter = new AtomicInteger(0); | ||
30 | - private final AtomicInteger subscribeToRPCCounter = new AtomicInteger(0); | ||
31 | - private final AtomicInteger toDeviceRPCCallResponseCounter = new AtomicInteger(0); | ||
32 | - private final AtomicInteger subscriptionInfoCounter = new AtomicInteger(0); | ||
33 | - private final AtomicInteger claimDeviceCounter = new AtomicInteger(0); | 41 | + private final StatsCounter totalCounter; |
42 | + private final StatsCounter sessionEventCounter; | ||
43 | + private final StatsCounter getAttributesCounter; | ||
44 | + private final StatsCounter subscribeToAttributesCounter; | ||
45 | + private final StatsCounter subscribeToRPCCounter; | ||
46 | + private final StatsCounter toDeviceRPCCallResponseCounter; | ||
47 | + private final StatsCounter subscriptionInfoCounter; | ||
48 | + private final StatsCounter claimDeviceCounter; | ||
34 | 49 | ||
35 | - private final AtomicInteger deviceStateCounter = new AtomicInteger(0); | ||
36 | - private final AtomicInteger subscriptionMsgCounter = new AtomicInteger(0); | ||
37 | - private final AtomicInteger toCoreNotificationsCounter = new AtomicInteger(0); | 50 | + private final StatsCounter deviceStateCounter; |
51 | + private final StatsCounter subscriptionMsgCounter; | ||
52 | + private final StatsCounter toCoreNotificationsCounter; | ||
53 | + | ||
54 | + private final List<StatsCounter> counters = new ArrayList<>(); | ||
55 | + | ||
56 | + public TbCoreConsumerStats(StatsCounterFactory counterFactory) { | ||
57 | + String statsKey = StatsType.CORE.getName(); | ||
58 | + | ||
59 | + this.totalCounter = counterFactory.createStatsCounter(statsKey, TOTAL_MSGS); | ||
60 | + this.sessionEventCounter = counterFactory.createStatsCounter(statsKey, SESSION_EVENTS); | ||
61 | + this.getAttributesCounter = counterFactory.createStatsCounter(statsKey, GET_ATTRIBUTE); | ||
62 | + this.subscribeToAttributesCounter = counterFactory.createStatsCounter(statsKey, ATTRIBUTE_SUBSCRIBES); | ||
63 | + this.subscribeToRPCCounter = counterFactory.createStatsCounter(statsKey, RPC_SUBSCRIBES); | ||
64 | + this.toDeviceRPCCallResponseCounter = counterFactory.createStatsCounter(statsKey, TO_DEVICE_RPC_CALL_RESPONSES); | ||
65 | + this.subscriptionInfoCounter = counterFactory.createStatsCounter(statsKey, SUBSCRIPTION_INFO); | ||
66 | + this.claimDeviceCounter = counterFactory.createStatsCounter(statsKey, DEVICE_CLAIMS); | ||
67 | + this.deviceStateCounter = counterFactory.createStatsCounter(statsKey, DEVICE_STATES); | ||
68 | + this.subscriptionMsgCounter = counterFactory.createStatsCounter(statsKey, SUBSCRIPTION_MSGS); | ||
69 | + this.toCoreNotificationsCounter = counterFactory.createStatsCounter(statsKey, TO_CORE_NOTIFICATIONS); | ||
70 | + | ||
71 | + | ||
72 | + counters.add(totalCounter); | ||
73 | + counters.add(sessionEventCounter); | ||
74 | + counters.add(getAttributesCounter); | ||
75 | + counters.add(subscribeToAttributesCounter); | ||
76 | + counters.add(subscribeToRPCCounter); | ||
77 | + counters.add(toDeviceRPCCallResponseCounter); | ||
78 | + counters.add(subscriptionInfoCounter); | ||
79 | + counters.add(claimDeviceCounter); | ||
80 | + | ||
81 | + counters.add(deviceStateCounter); | ||
82 | + counters.add(subscriptionMsgCounter); | ||
83 | + counters.add(toCoreNotificationsCounter); | ||
84 | + } | ||
38 | 85 | ||
39 | public void log(TransportProtos.TransportToDeviceActorMsg msg) { | 86 | public void log(TransportProtos.TransportToDeviceActorMsg msg) { |
40 | - totalCounter.incrementAndGet(); | 87 | + totalCounter.increment(); |
41 | if (msg.hasSessionEvent()) { | 88 | if (msg.hasSessionEvent()) { |
42 | - sessionEventCounter.incrementAndGet(); | 89 | + sessionEventCounter.increment(); |
43 | } | 90 | } |
44 | if (msg.hasGetAttributes()) { | 91 | if (msg.hasGetAttributes()) { |
45 | - getAttributesCounter.incrementAndGet(); | 92 | + getAttributesCounter.increment(); |
46 | } | 93 | } |
47 | if (msg.hasSubscribeToAttributes()) { | 94 | if (msg.hasSubscribeToAttributes()) { |
48 | - subscribeToAttributesCounter.incrementAndGet(); | 95 | + subscribeToAttributesCounter.increment(); |
49 | } | 96 | } |
50 | if (msg.hasSubscribeToRPC()) { | 97 | if (msg.hasSubscribeToRPC()) { |
51 | - subscribeToRPCCounter.incrementAndGet(); | 98 | + subscribeToRPCCounter.increment(); |
52 | } | 99 | } |
53 | if (msg.hasToDeviceRPCCallResponse()) { | 100 | if (msg.hasToDeviceRPCCallResponse()) { |
54 | - toDeviceRPCCallResponseCounter.incrementAndGet(); | 101 | + toDeviceRPCCallResponseCounter.increment(); |
55 | } | 102 | } |
56 | if (msg.hasSubscriptionInfo()) { | 103 | if (msg.hasSubscriptionInfo()) { |
57 | - subscriptionInfoCounter.incrementAndGet(); | 104 | + subscriptionInfoCounter.increment(); |
58 | } | 105 | } |
59 | if (msg.hasClaimDevice()) { | 106 | if (msg.hasClaimDevice()) { |
60 | - claimDeviceCounter.incrementAndGet(); | 107 | + claimDeviceCounter.increment(); |
61 | } | 108 | } |
62 | } | 109 | } |
63 | 110 | ||
64 | public void log(TransportProtos.DeviceStateServiceMsgProto msg) { | 111 | public void log(TransportProtos.DeviceStateServiceMsgProto msg) { |
65 | - totalCounter.incrementAndGet(); | ||
66 | - deviceStateCounter.incrementAndGet(); | 112 | + totalCounter.increment(); |
113 | + deviceStateCounter.increment(); | ||
67 | } | 114 | } |
68 | 115 | ||
69 | public void log(TransportProtos.SubscriptionMgrMsgProto msg) { | 116 | public void log(TransportProtos.SubscriptionMgrMsgProto msg) { |
70 | - totalCounter.incrementAndGet(); | ||
71 | - subscriptionMsgCounter.incrementAndGet(); | 117 | + totalCounter.increment(); |
118 | + subscriptionMsgCounter.increment(); | ||
72 | } | 119 | } |
73 | 120 | ||
74 | public void log(TransportProtos.ToCoreNotificationMsg msg) { | 121 | public void log(TransportProtos.ToCoreNotificationMsg msg) { |
75 | - totalCounter.incrementAndGet(); | ||
76 | - toCoreNotificationsCounter.incrementAndGet(); | 122 | + totalCounter.increment(); |
123 | + toCoreNotificationsCounter.increment(); | ||
77 | } | 124 | } |
78 | 125 | ||
79 | public void printStats() { | 126 | public void printStats() { |
80 | - int total = totalCounter.getAndSet(0); | 127 | + int total = totalCounter.get(); |
81 | if (total > 0) { | 128 | if (total > 0) { |
82 | - log.info("Total [{}] sessionEvents [{}] getAttr [{}] subToAttr [{}] subToRpc [{}] toDevRpc [{}] subInfo [{}] claimDevice [{}]" + | ||
83 | - " deviceState [{}] subMgr [{}] coreNfs [{}]", | ||
84 | - total, sessionEventCounter.getAndSet(0), | ||
85 | - getAttributesCounter.getAndSet(0), subscribeToAttributesCounter.getAndSet(0), | ||
86 | - subscribeToRPCCounter.getAndSet(0), toDeviceRPCCallResponseCounter.getAndSet(0), | ||
87 | - subscriptionInfoCounter.getAndSet(0), claimDeviceCounter.getAndSet(0) | ||
88 | - , deviceStateCounter.getAndSet(0), subscriptionMsgCounter.getAndSet(0), toCoreNotificationsCounter.getAndSet(0)); | 129 | + StringBuilder stats = new StringBuilder(); |
130 | + counters.forEach(counter -> { | ||
131 | + stats.append(counter.getName()).append(" = [").append(counter.get()).append("] "); | ||
132 | + }); | ||
133 | + log.info("Core Stats: {}", stats); | ||
89 | } | 134 | } |
90 | } | 135 | } |
91 | 136 | ||
137 | + public void reset() { | ||
138 | + counters.forEach(StatsCounter::clear); | ||
139 | + } | ||
92 | } | 140 | } |
@@ -22,16 +22,16 @@ import org.thingsboard.server.common.msg.queue.RuleEngineException; | @@ -22,16 +22,16 @@ import org.thingsboard.server.common.msg.queue.RuleEngineException; | ||
22 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; | 22 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; |
23 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 23 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
24 | import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingResult; | 24 | import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingResult; |
25 | +import org.thingsboard.server.service.stats.StatsCounter; | ||
26 | +import org.thingsboard.server.service.stats.StatsCounterFactory; | ||
27 | +import org.thingsboard.server.service.stats.StatsType; | ||
25 | 28 | ||
26 | -import java.util.HashMap; | ||
27 | -import java.util.Map; | ||
28 | -import java.util.UUID; | 29 | +import java.util.*; |
29 | import java.util.concurrent.ConcurrentHashMap; | 30 | import java.util.concurrent.ConcurrentHashMap; |
30 | import java.util.concurrent.ConcurrentMap; | 31 | import java.util.concurrent.ConcurrentMap; |
31 | import java.util.concurrent.atomic.AtomicInteger; | 32 | import java.util.concurrent.atomic.AtomicInteger; |
32 | 33 | ||
33 | @Slf4j | 34 | @Slf4j |
34 | -@Data | ||
35 | public class TbRuleEngineConsumerStats { | 35 | public class TbRuleEngineConsumerStats { |
36 | 36 | ||
37 | public static final String TOTAL_MSGS = "totalMsgs"; | 37 | public static final String TOTAL_MSGS = "totalMsgs"; |
@@ -43,61 +43,72 @@ public class TbRuleEngineConsumerStats { | @@ -43,61 +43,72 @@ public class TbRuleEngineConsumerStats { | ||
43 | public static final String SUCCESSFUL_ITERATIONS = "successfulIterations"; | 43 | public static final String SUCCESSFUL_ITERATIONS = "successfulIterations"; |
44 | public static final String FAILED_ITERATIONS = "failedIterations"; | 44 | public static final String FAILED_ITERATIONS = "failedIterations"; |
45 | 45 | ||
46 | - private final AtomicInteger totalMsgCounter = new AtomicInteger(0); | ||
47 | - private final AtomicInteger successMsgCounter = new AtomicInteger(0); | ||
48 | - private final AtomicInteger tmpTimeoutMsgCounter = new AtomicInteger(0); | ||
49 | - private final AtomicInteger tmpFailedMsgCounter = new AtomicInteger(0); | 46 | + private final StatsCounter totalMsgCounter; |
47 | + private final StatsCounter successMsgCounter; | ||
48 | + private final StatsCounter tmpTimeoutMsgCounter; | ||
49 | + private final StatsCounter tmpFailedMsgCounter; | ||
50 | 50 | ||
51 | - private final AtomicInteger timeoutMsgCounter = new AtomicInteger(0); | ||
52 | - private final AtomicInteger failedMsgCounter = new AtomicInteger(0); | 51 | + private final StatsCounter timeoutMsgCounter; |
52 | + private final StatsCounter failedMsgCounter; | ||
53 | 53 | ||
54 | - private final AtomicInteger successIterationsCounter = new AtomicInteger(0); | ||
55 | - private final AtomicInteger failedIterationsCounter = new AtomicInteger(0); | 54 | + private final StatsCounter successIterationsCounter; |
55 | + private final StatsCounter failedIterationsCounter; | ||
56 | 56 | ||
57 | - private final Map<String, AtomicInteger> counters = new HashMap<>(); | 57 | + private final List<StatsCounter> counters = new ArrayList<>(); |
58 | private final ConcurrentMap<UUID, TbTenantRuleEngineStats> tenantStats = new ConcurrentHashMap<>(); | 58 | private final ConcurrentMap<UUID, TbTenantRuleEngineStats> tenantStats = new ConcurrentHashMap<>(); |
59 | private final ConcurrentMap<TenantId, RuleEngineException> tenantExceptions = new ConcurrentHashMap<>(); | 59 | private final ConcurrentMap<TenantId, RuleEngineException> tenantExceptions = new ConcurrentHashMap<>(); |
60 | 60 | ||
61 | private final String queueName; | 61 | private final String queueName; |
62 | 62 | ||
63 | - public TbRuleEngineConsumerStats(String queueName) { | 63 | + public TbRuleEngineConsumerStats(String queueName, StatsCounterFactory counterFactory) { |
64 | this.queueName = queueName; | 64 | this.queueName = queueName; |
65 | - counters.put(TOTAL_MSGS, totalMsgCounter); | ||
66 | - counters.put(SUCCESSFUL_MSGS, successMsgCounter); | ||
67 | - counters.put(TIMEOUT_MSGS, timeoutMsgCounter); | ||
68 | - counters.put(FAILED_MSGS, failedMsgCounter); | ||
69 | - | ||
70 | - counters.put(TMP_TIMEOUT, tmpTimeoutMsgCounter); | ||
71 | - counters.put(TMP_FAILED, tmpFailedMsgCounter); | ||
72 | - counters.put(SUCCESSFUL_ITERATIONS, successIterationsCounter); | ||
73 | - counters.put(FAILED_ITERATIONS, failedIterationsCounter); | 65 | + |
66 | + String statsKey = StatsType.RULE_ENGINE.getName() + "." + queueName; | ||
67 | + this.totalMsgCounter = counterFactory.createStatsCounter(statsKey, TOTAL_MSGS); | ||
68 | + this.successMsgCounter = counterFactory.createStatsCounter(statsKey, SUCCESSFUL_MSGS); | ||
69 | + this.timeoutMsgCounter = counterFactory.createStatsCounter(statsKey, TIMEOUT_MSGS); | ||
70 | + this.failedMsgCounter = counterFactory.createStatsCounter(statsKey, FAILED_MSGS); | ||
71 | + this.tmpTimeoutMsgCounter = counterFactory.createStatsCounter(statsKey, TMP_TIMEOUT); | ||
72 | + this.tmpFailedMsgCounter = counterFactory.createStatsCounter(statsKey, TMP_FAILED); | ||
73 | + this.successIterationsCounter = counterFactory.createStatsCounter(statsKey, SUCCESSFUL_ITERATIONS); | ||
74 | + this.failedIterationsCounter = counterFactory.createStatsCounter(statsKey, FAILED_ITERATIONS); | ||
75 | + | ||
76 | + counters.add(totalMsgCounter); | ||
77 | + counters.add(successMsgCounter); | ||
78 | + counters.add(timeoutMsgCounter); | ||
79 | + counters.add(failedMsgCounter); | ||
80 | + | ||
81 | + counters.add(tmpTimeoutMsgCounter); | ||
82 | + counters.add(tmpFailedMsgCounter); | ||
83 | + counters.add(successIterationsCounter); | ||
84 | + counters.add(failedIterationsCounter); | ||
74 | } | 85 | } |
75 | 86 | ||
76 | public void log(TbRuleEngineProcessingResult msg, boolean finalIterationForPack) { | 87 | public void log(TbRuleEngineProcessingResult msg, boolean finalIterationForPack) { |
77 | int success = msg.getSuccessMap().size(); | 88 | int success = msg.getSuccessMap().size(); |
78 | int pending = msg.getPendingMap().size(); | 89 | int pending = msg.getPendingMap().size(); |
79 | int failed = msg.getFailedMap().size(); | 90 | int failed = msg.getFailedMap().size(); |
80 | - totalMsgCounter.addAndGet(success + pending + failed); | ||
81 | - successMsgCounter.addAndGet(success); | 91 | + totalMsgCounter.add(success + pending + failed); |
92 | + successMsgCounter.add(success); | ||
82 | msg.getSuccessMap().values().forEach(m -> getTenantStats(m).logSuccess()); | 93 | msg.getSuccessMap().values().forEach(m -> getTenantStats(m).logSuccess()); |
83 | if (finalIterationForPack) { | 94 | if (finalIterationForPack) { |
84 | if (pending > 0 || failed > 0) { | 95 | if (pending > 0 || failed > 0) { |
85 | - timeoutMsgCounter.addAndGet(pending); | ||
86 | - failedMsgCounter.addAndGet(failed); | 96 | + timeoutMsgCounter.add(pending); |
97 | + failedMsgCounter.add(failed); | ||
87 | if (pending > 0) { | 98 | if (pending > 0) { |
88 | msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTimeout()); | 99 | msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTimeout()); |
89 | } | 100 | } |
90 | if (failed > 0) { | 101 | if (failed > 0) { |
91 | msg.getFailedMap().values().forEach(m -> getTenantStats(m).logFailed()); | 102 | msg.getFailedMap().values().forEach(m -> getTenantStats(m).logFailed()); |
92 | } | 103 | } |
93 | - failedIterationsCounter.incrementAndGet(); | 104 | + failedIterationsCounter.increment(); |
94 | } else { | 105 | } else { |
95 | - successIterationsCounter.incrementAndGet(); | 106 | + successIterationsCounter.increment(); |
96 | } | 107 | } |
97 | } else { | 108 | } else { |
98 | - failedIterationsCounter.incrementAndGet(); | ||
99 | - tmpTimeoutMsgCounter.addAndGet(pending); | ||
100 | - tmpFailedMsgCounter.addAndGet(failed); | 109 | + failedIterationsCounter.increment(); |
110 | + tmpTimeoutMsgCounter.add(pending); | ||
111 | + tmpFailedMsgCounter.add(failed); | ||
101 | if (pending > 0) { | 112 | if (pending > 0) { |
102 | msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTmpTimeout()); | 113 | msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTmpTimeout()); |
103 | } | 114 | } |
@@ -113,19 +124,31 @@ public class TbRuleEngineConsumerStats { | @@ -113,19 +124,31 @@ public class TbRuleEngineConsumerStats { | ||
113 | return tenantStats.computeIfAbsent(new UUID(reMsg.getTenantIdMSB(), reMsg.getTenantIdLSB()), TbTenantRuleEngineStats::new); | 124 | return tenantStats.computeIfAbsent(new UUID(reMsg.getTenantIdMSB(), reMsg.getTenantIdLSB()), TbTenantRuleEngineStats::new); |
114 | } | 125 | } |
115 | 126 | ||
127 | + public ConcurrentMap<UUID, TbTenantRuleEngineStats> getTenantStats() { | ||
128 | + return tenantStats; | ||
129 | + } | ||
130 | + | ||
131 | + public String getQueueName() { | ||
132 | + return queueName; | ||
133 | + } | ||
134 | + | ||
135 | + public ConcurrentMap<TenantId, RuleEngineException> getTenantExceptions() { | ||
136 | + return tenantExceptions; | ||
137 | + } | ||
138 | + | ||
116 | public void printStats() { | 139 | public void printStats() { |
117 | int total = totalMsgCounter.get(); | 140 | int total = totalMsgCounter.get(); |
118 | if (total > 0) { | 141 | if (total > 0) { |
119 | StringBuilder stats = new StringBuilder(); | 142 | StringBuilder stats = new StringBuilder(); |
120 | - counters.forEach((label, value) -> { | ||
121 | - stats.append(label).append(" = [").append(value.get()).append("] "); | 143 | + counters.forEach(counter -> { |
144 | + stats.append(counter.getName()).append(" = [").append(counter.get()).append("] "); | ||
122 | }); | 145 | }); |
123 | log.info("[{}] Stats: {}", queueName, stats); | 146 | log.info("[{}] Stats: {}", queueName, stats); |
124 | } | 147 | } |
125 | } | 148 | } |
126 | 149 | ||
127 | public void reset() { | 150 | public void reset() { |
128 | - counters.values().forEach(counter -> counter.set(0)); | 151 | + counters.forEach(StatsCounter::clear); |
129 | tenantStats.clear(); | 152 | tenantStats.clear(); |
130 | tenantExceptions.clear(); | 153 | tenantExceptions.clear(); |
131 | } | 154 | } |
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 | +package org.thingsboard.server.service.stats; | ||
17 | + | ||
18 | +import org.springframework.beans.factory.annotation.Autowired; | ||
19 | +import org.springframework.stereotype.Service; | ||
20 | +import org.thingsboard.server.actors.JsInvokeStats; | ||
21 | + | ||
22 | +import javax.annotation.PostConstruct; | ||
23 | + | ||
24 | +@Service | ||
25 | +public class DefaultJsInvokeStats implements JsInvokeStats { | ||
26 | + private static final String REQUESTS = "requests"; | ||
27 | + private static final String RESPONSES = "responses"; | ||
28 | + private static final String FAILURES = "failures"; | ||
29 | + | ||
30 | + private StatsCounter requestsCounter; | ||
31 | + private StatsCounter responsesCounter; | ||
32 | + private StatsCounter failuresCounter; | ||
33 | + | ||
34 | + @Autowired | ||
35 | + private StatsCounterFactory counterFactory; | ||
36 | + | ||
37 | + @PostConstruct | ||
38 | + public void init() { | ||
39 | + String key = StatsType.JS_INVOKE.getName(); | ||
40 | + this.requestsCounter = counterFactory.createStatsCounter(key, REQUESTS); | ||
41 | + this.responsesCounter = counterFactory.createStatsCounter(key, RESPONSES); | ||
42 | + this.failuresCounter = counterFactory.createStatsCounter(key, FAILURES); | ||
43 | + } | ||
44 | + | ||
45 | + @Override | ||
46 | + public void incrementRequests(int amount) { | ||
47 | + requestsCounter.add(amount); | ||
48 | + } | ||
49 | + | ||
50 | + @Override | ||
51 | + public void incrementResponses(int amount) { | ||
52 | + responsesCounter.add(amount); | ||
53 | + } | ||
54 | + | ||
55 | + @Override | ||
56 | + public void incrementFailures(int amount) { | ||
57 | + failuresCounter.add(amount); | ||
58 | + } | ||
59 | + | ||
60 | + @Override | ||
61 | + public int getRequests() { | ||
62 | + return requestsCounter.get(); | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
66 | + public int getResponses() { | ||
67 | + return responsesCounter.get(); | ||
68 | + } | ||
69 | + | ||
70 | + @Override | ||
71 | + public int getFailures() { | ||
72 | + return failuresCounter.get(); | ||
73 | + } | ||
74 | + | ||
75 | + @Override | ||
76 | + public void reset() { | ||
77 | + requestsCounter.clear(); | ||
78 | + responsesCounter.clear(); | ||
79 | + failuresCounter.clear(); | ||
80 | + } | ||
81 | +} |
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 | +package org.thingsboard.server.service.stats; | ||
17 | + | ||
18 | +import org.thingsboard.server.queue.stats.QueueStats; | ||
19 | + | ||
20 | +public class DefaultQueueStats implements QueueStats { | ||
21 | + private final StatsCounter totalCounter; | ||
22 | + private final StatsCounter successfulCounter; | ||
23 | + private final StatsCounter failedCounter; | ||
24 | + | ||
25 | + public DefaultQueueStats(StatsCounter totalCounter, StatsCounter successfulCounter, StatsCounter failedCounter) { | ||
26 | + this.totalCounter = totalCounter; | ||
27 | + this.successfulCounter = successfulCounter; | ||
28 | + this.failedCounter = failedCounter; | ||
29 | + } | ||
30 | + | ||
31 | + @Override | ||
32 | + public void incrementTotal(int amount) { | ||
33 | + totalCounter.add(amount); | ||
34 | + } | ||
35 | + | ||
36 | + @Override | ||
37 | + public void incrementSuccessful(int amount) { | ||
38 | + successfulCounter.add(amount); | ||
39 | + } | ||
40 | + | ||
41 | + @Override | ||
42 | + public void incrementFailed(int amount) { | ||
43 | + failedCounter.add(amount); | ||
44 | + } | ||
45 | +} |
@@ -104,7 +104,6 @@ public class DefaultRuleEngineStatisticsService implements RuleEngineStatisticsS | @@ -104,7 +104,6 @@ public class DefaultRuleEngineStatisticsService implements RuleEngineStatisticsS | ||
104 | } | 104 | } |
105 | } | 105 | } |
106 | }); | 106 | }); |
107 | - ruleEngineStats.reset(); | ||
108 | } | 107 | } |
109 | 108 | ||
110 | private AssetId getServiceAssetId(TenantId tenantId, String queueName) { | 109 | private AssetId getServiceAssetId(TenantId tenantId, String queueName) { |
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 | +package org.thingsboard.server.service.stats; | ||
17 | + | ||
18 | +import io.micrometer.core.instrument.Counter; | ||
19 | + | ||
20 | +import java.util.concurrent.atomic.AtomicInteger; | ||
21 | + | ||
22 | +public class StatsCounter { | ||
23 | + private final AtomicInteger aiCounter; | ||
24 | + private final Counter micrometerCounter; | ||
25 | + private final String name; | ||
26 | + | ||
27 | + public StatsCounter(AtomicInteger aiCounter, Counter micrometerCounter, String name) { | ||
28 | + this.aiCounter = aiCounter; | ||
29 | + this.micrometerCounter = micrometerCounter; | ||
30 | + this.name = name; | ||
31 | + } | ||
32 | + | ||
33 | + public void increment() { | ||
34 | + aiCounter.incrementAndGet(); | ||
35 | + micrometerCounter.increment(); | ||
36 | + } | ||
37 | + | ||
38 | + public void clear() { | ||
39 | + aiCounter.set(0); | ||
40 | + } | ||
41 | + | ||
42 | + public int get() { | ||
43 | + return aiCounter.get(); | ||
44 | + } | ||
45 | + | ||
46 | + public void add(int delta){ | ||
47 | + aiCounter.addAndGet(delta); | ||
48 | + micrometerCounter.increment(delta); | ||
49 | + } | ||
50 | + | ||
51 | + public String getName() { | ||
52 | + return name; | ||
53 | + } | ||
54 | +} |
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 | +package org.thingsboard.server.service.stats; | ||
17 | + | ||
18 | +import io.micrometer.core.instrument.Counter; | ||
19 | +import io.micrometer.core.instrument.MeterRegistry; | ||
20 | +import org.springframework.beans.factory.annotation.Autowired; | ||
21 | +import org.springframework.beans.factory.annotation.Value; | ||
22 | +import org.springframework.stereotype.Service; | ||
23 | +import org.thingsboard.server.service.metrics.StubCounter; | ||
24 | + | ||
25 | +import java.util.concurrent.atomic.AtomicInteger; | ||
26 | + | ||
27 | +@Service | ||
28 | +public class StatsCounterFactory { | ||
29 | + private static final String STATS_NAME_TAG = "statsName"; | ||
30 | + | ||
31 | + private static final Counter STUB_COUNTER = new StubCounter(); | ||
32 | + | ||
33 | + @Autowired | ||
34 | + private MeterRegistry meterRegistry; | ||
35 | + | ||
36 | + @Value("${metrics.enabled}") | ||
37 | + private Boolean metricsEnabled; | ||
38 | + | ||
39 | + public StatsCounter createStatsCounter(String key, String statsName) { | ||
40 | + return new StatsCounter( | ||
41 | + new AtomicInteger(0), | ||
42 | + metricsEnabled ? | ||
43 | + meterRegistry.counter(key, STATS_NAME_TAG, statsName) | ||
44 | + : STUB_COUNTER, | ||
45 | + statsName | ||
46 | + ); | ||
47 | + } | ||
48 | +} |
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 | +package org.thingsboard.server.service.stats; | ||
17 | + | ||
18 | +public enum StatsType { | ||
19 | + RULE_ENGINE("ruleEngine"), CORE("core"), TRANSPORT("transport"), JS_INVOKE("jsInvoke"); | ||
20 | + | ||
21 | + private String name; | ||
22 | + | ||
23 | + StatsType(String name) { | ||
24 | + this.name = name; | ||
25 | + } | ||
26 | + | ||
27 | + public String getName() { | ||
28 | + return name; | ||
29 | + } | ||
30 | +} |
@@ -29,6 +29,10 @@ import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestM | @@ -29,6 +29,10 @@ import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestM | ||
29 | import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg; | 29 | import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg; |
30 | import org.thingsboard.server.queue.provider.TbCoreQueueFactory; | 30 | import org.thingsboard.server.queue.provider.TbCoreQueueFactory; |
31 | import org.thingsboard.server.queue.util.TbCoreComponent; | 31 | import org.thingsboard.server.queue.util.TbCoreComponent; |
32 | +import org.thingsboard.server.service.stats.DefaultQueueStats; | ||
33 | +import org.thingsboard.server.service.stats.StatsCounter; | ||
34 | +import org.thingsboard.server.service.stats.StatsCounterFactory; | ||
35 | +import org.thingsboard.server.service.stats.StatsType; | ||
32 | 36 | ||
33 | import javax.annotation.PostConstruct; | 37 | import javax.annotation.PostConstruct; |
34 | import javax.annotation.PreDestroy; | 38 | import javax.annotation.PreDestroy; |
@@ -41,9 +45,13 @@ import java.util.concurrent.*; | @@ -41,9 +45,13 @@ import java.util.concurrent.*; | ||
41 | @Service | 45 | @Service |
42 | @TbCoreComponent | 46 | @TbCoreComponent |
43 | public class TbCoreTransportApiService { | 47 | public class TbCoreTransportApiService { |
48 | + private static final String TOTAL_MSGS = "totalMsgs"; | ||
49 | + private static final String SUCCESSFUL_MSGS = "successfulMsgs"; | ||
50 | + private static final String FAILED_MSGS = "failedMsgs"; | ||
44 | 51 | ||
45 | private final TbCoreQueueFactory tbCoreQueueFactory; | 52 | private final TbCoreQueueFactory tbCoreQueueFactory; |
46 | private final TransportApiService transportApiService; | 53 | private final TransportApiService transportApiService; |
54 | + private final StatsCounterFactory counterFactory; | ||
47 | 55 | ||
48 | @Value("${queue.transport_api.max_pending_requests:10000}") | 56 | @Value("${queue.transport_api.max_pending_requests:10000}") |
49 | private int maxPendingRequests; | 57 | private int maxPendingRequests; |
@@ -58,9 +66,10 @@ public class TbCoreTransportApiService { | @@ -58,9 +66,10 @@ public class TbCoreTransportApiService { | ||
58 | private TbQueueResponseTemplate<TbProtoQueueMsg<TransportApiRequestMsg>, | 66 | private TbQueueResponseTemplate<TbProtoQueueMsg<TransportApiRequestMsg>, |
59 | TbProtoQueueMsg<TransportApiResponseMsg>> transportApiTemplate; | 67 | TbProtoQueueMsg<TransportApiResponseMsg>> transportApiTemplate; |
60 | 68 | ||
61 | - public TbCoreTransportApiService(TbCoreQueueFactory tbCoreQueueFactory, TransportApiService transportApiService) { | 69 | + public TbCoreTransportApiService(TbCoreQueueFactory tbCoreQueueFactory, TransportApiService transportApiService, StatsCounterFactory counterFactory) { |
62 | this.tbCoreQueueFactory = tbCoreQueueFactory; | 70 | this.tbCoreQueueFactory = tbCoreQueueFactory; |
63 | this.transportApiService = transportApiService; | 71 | this.transportApiService = transportApiService; |
72 | + this.counterFactory = counterFactory; | ||
64 | } | 73 | } |
65 | 74 | ||
66 | @PostConstruct | 75 | @PostConstruct |
@@ -69,6 +78,12 @@ public class TbCoreTransportApiService { | @@ -69,6 +78,12 @@ public class TbCoreTransportApiService { | ||
69 | TbQueueProducer<TbProtoQueueMsg<TransportApiResponseMsg>> producer = tbCoreQueueFactory.createTransportApiResponseProducer(); | 78 | TbQueueProducer<TbProtoQueueMsg<TransportApiResponseMsg>> producer = tbCoreQueueFactory.createTransportApiResponseProducer(); |
70 | TbQueueConsumer<TbProtoQueueMsg<TransportApiRequestMsg>> consumer = tbCoreQueueFactory.createTransportApiRequestConsumer(); | 79 | TbQueueConsumer<TbProtoQueueMsg<TransportApiRequestMsg>> consumer = tbCoreQueueFactory.createTransportApiRequestConsumer(); |
71 | 80 | ||
81 | + String key = StatsType.TRANSPORT.getName(); | ||
82 | + StatsCounter totalCounter = counterFactory.createStatsCounter(key, TOTAL_MSGS); | ||
83 | + StatsCounter successfulCounter = counterFactory.createStatsCounter(key, SUCCESSFUL_MSGS); | ||
84 | + StatsCounter failedCounter = counterFactory.createStatsCounter(key, FAILED_MSGS); | ||
85 | + DefaultQueueStats queueStats = new DefaultQueueStats(totalCounter, successfulCounter, failedCounter); | ||
86 | + | ||
72 | DefaultTbQueueResponseTemplate.DefaultTbQueueResponseTemplateBuilder | 87 | DefaultTbQueueResponseTemplate.DefaultTbQueueResponseTemplateBuilder |
73 | <TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> builder = DefaultTbQueueResponseTemplate.builder(); | 88 | <TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> builder = DefaultTbQueueResponseTemplate.builder(); |
74 | builder.requestTemplate(consumer); | 89 | builder.requestTemplate(consumer); |
@@ -78,6 +93,7 @@ public class TbCoreTransportApiService { | @@ -78,6 +93,7 @@ public class TbCoreTransportApiService { | ||
78 | builder.pollInterval(responsePollDuration); | 93 | builder.pollInterval(responsePollDuration); |
79 | builder.executor(transportCallbackExecutor); | 94 | builder.executor(transportCallbackExecutor); |
80 | builder.handler(transportApiService); | 95 | builder.handler(transportApiService); |
96 | + builder.stats(queueStats); | ||
81 | transportApiTemplate = builder.build(); | 97 | transportApiTemplate = builder.build(); |
82 | } | 98 | } |
83 | 99 |
@@ -27,7 +27,6 @@ import java.sql.Statement; | @@ -27,7 +27,6 @@ import java.sql.Statement; | ||
27 | 27 | ||
28 | 28 | ||
29 | @Slf4j | 29 | @Slf4j |
30 | -@PsqlDao | ||
31 | public abstract class AbstractCleanUpService { | 30 | public abstract class AbstractCleanUpService { |
32 | 31 | ||
33 | @Value("${spring.datasource.url}") | 32 | @Value("${spring.datasource.url}") |
@@ -20,6 +20,7 @@ import org.springframework.beans.factory.annotation.Value; | @@ -20,6 +20,7 @@ import org.springframework.beans.factory.annotation.Value; | ||
20 | import org.springframework.scheduling.annotation.Scheduled; | 20 | import org.springframework.scheduling.annotation.Scheduled; |
21 | import org.springframework.stereotype.Service; | 21 | import org.springframework.stereotype.Service; |
22 | import org.thingsboard.server.dao.util.PsqlDao; | 22 | import org.thingsboard.server.dao.util.PsqlDao; |
23 | +import org.thingsboard.server.dao.util.SqlDao; | ||
23 | import org.thingsboard.server.service.ttl.AbstractCleanUpService; | 24 | import org.thingsboard.server.service.ttl.AbstractCleanUpService; |
24 | 25 | ||
25 | import java.sql.Connection; | 26 | import java.sql.Connection; |
@@ -27,6 +28,7 @@ import java.sql.DriverManager; | @@ -27,6 +28,7 @@ import java.sql.DriverManager; | ||
27 | import java.sql.SQLException; | 28 | import java.sql.SQLException; |
28 | 29 | ||
29 | @PsqlDao | 30 | @PsqlDao |
31 | +@SqlDao | ||
30 | @Slf4j | 32 | @Slf4j |
31 | @Service | 33 | @Service |
32 | public class EventsCleanUpService extends AbstractCleanUpService { | 34 | public class EventsCleanUpService extends AbstractCleanUpService { |
@@ -18,14 +18,12 @@ package org.thingsboard.server.service.ttl.timeseries; | @@ -18,14 +18,12 @@ package org.thingsboard.server.service.ttl.timeseries; | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | import org.springframework.beans.factory.annotation.Value; | 19 | import org.springframework.beans.factory.annotation.Value; |
20 | import org.springframework.scheduling.annotation.Scheduled; | 20 | import org.springframework.scheduling.annotation.Scheduled; |
21 | -import org.thingsboard.server.dao.util.PsqlTsAnyDao; | ||
22 | import org.thingsboard.server.service.ttl.AbstractCleanUpService; | 21 | import org.thingsboard.server.service.ttl.AbstractCleanUpService; |
23 | 22 | ||
24 | import java.sql.Connection; | 23 | import java.sql.Connection; |
25 | import java.sql.DriverManager; | 24 | import java.sql.DriverManager; |
26 | import java.sql.SQLException; | 25 | import java.sql.SQLException; |
27 | 26 | ||
28 | -@PsqlTsAnyDao | ||
29 | @Slf4j | 27 | @Slf4j |
30 | public abstract class AbstractTimeseriesCleanUpService extends AbstractCleanUpService { | 28 | public abstract class AbstractTimeseriesCleanUpService extends AbstractCleanUpService { |
31 | 29 |
@@ -257,14 +257,17 @@ sql: | @@ -257,14 +257,17 @@ sql: | ||
257 | batch_size: "${SQL_ATTRIBUTES_BATCH_SIZE:10000}" | 257 | batch_size: "${SQL_ATTRIBUTES_BATCH_SIZE:10000}" |
258 | batch_max_delay: "${SQL_ATTRIBUTES_BATCH_MAX_DELAY_MS:100}" | 258 | batch_max_delay: "${SQL_ATTRIBUTES_BATCH_MAX_DELAY_MS:100}" |
259 | stats_print_interval_ms: "${SQL_ATTRIBUTES_BATCH_STATS_PRINT_MS:10000}" | 259 | stats_print_interval_ms: "${SQL_ATTRIBUTES_BATCH_STATS_PRINT_MS:10000}" |
260 | + batch_threads: "${SQL_ATTRIBUTES_BATCH_THREADS:4}" | ||
260 | ts: | 261 | ts: |
261 | batch_size: "${SQL_TS_BATCH_SIZE:10000}" | 262 | batch_size: "${SQL_TS_BATCH_SIZE:10000}" |
262 | batch_max_delay: "${SQL_TS_BATCH_MAX_DELAY_MS:100}" | 263 | batch_max_delay: "${SQL_TS_BATCH_MAX_DELAY_MS:100}" |
263 | stats_print_interval_ms: "${SQL_TS_BATCH_STATS_PRINT_MS:10000}" | 264 | stats_print_interval_ms: "${SQL_TS_BATCH_STATS_PRINT_MS:10000}" |
265 | + batch_threads: "${SQL_TS_BATCH_THREADS:4}" | ||
264 | ts_latest: | 266 | ts_latest: |
265 | batch_size: "${SQL_TS_LATEST_BATCH_SIZE:10000}" | 267 | batch_size: "${SQL_TS_LATEST_BATCH_SIZE:10000}" |
266 | batch_max_delay: "${SQL_TS_LATEST_BATCH_MAX_DELAY_MS:100}" | 268 | batch_max_delay: "${SQL_TS_LATEST_BATCH_MAX_DELAY_MS:100}" |
267 | stats_print_interval_ms: "${SQL_TS_LATEST_BATCH_STATS_PRINT_MS:10000}" | 269 | stats_print_interval_ms: "${SQL_TS_LATEST_BATCH_STATS_PRINT_MS:10000}" |
270 | + batch_threads: "${SQL_TS_LATEST_BATCH_THREADS:4}" | ||
268 | # Specify whether to remove null characters from strValue of attributes and timeseries before insert | 271 | # Specify whether to remove null characters from strValue of attributes and timeseries before insert |
269 | remove_null_chars: "${SQL_REMOVE_NULL_CHARS:true}" | 272 | remove_null_chars: "${SQL_REMOVE_NULL_CHARS:true}" |
270 | postgres: | 273 | postgres: |
@@ -273,6 +276,7 @@ sql: | @@ -273,6 +276,7 @@ sql: | ||
273 | timescale: | 276 | timescale: |
274 | # Specify Interval size for new data chunks storage. | 277 | # Specify Interval size for new data chunks storage. |
275 | chunk_time_interval: "${SQL_TIMESCALE_CHUNK_TIME_INTERVAL:604800000}" | 278 | chunk_time_interval: "${SQL_TIMESCALE_CHUNK_TIME_INTERVAL:604800000}" |
279 | + batch_threads: "${SQL_TIMESCALE_BATCH_THREADS:4}" | ||
276 | ttl: | 280 | ttl: |
277 | ts: | 281 | ts: |
278 | enabled: "${SQL_TTL_TS_ENABLED:true}" | 282 | enabled: "${SQL_TTL_TS_ENABLED:true}" |
@@ -451,7 +455,7 @@ spring: | @@ -451,7 +455,7 @@ spring: | ||
451 | username: "${SPRING_DATASOURCE_USERNAME:postgres}" | 455 | username: "${SPRING_DATASOURCE_USERNAME:postgres}" |
452 | password: "${SPRING_DATASOURCE_PASSWORD:postgres}" | 456 | password: "${SPRING_DATASOURCE_PASSWORD:postgres}" |
453 | hikari: | 457 | hikari: |
454 | - maximumPoolSize: "${SPRING_DATASOURCE_MAXIMUM_POOL_SIZE:5}" | 458 | + maximumPoolSize: "${SPRING_DATASOURCE_MAXIMUM_POOL_SIZE:16}" |
455 | 459 | ||
456 | # Audit log parameters | 460 | # Audit log parameters |
457 | audit-log: | 461 | audit-log: |
@@ -760,3 +764,13 @@ service: | @@ -760,3 +764,13 @@ service: | ||
760 | id: "${TB_SERVICE_ID:}" | 764 | id: "${TB_SERVICE_ID:}" |
761 | tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id. | 765 | tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id. |
762 | 766 | ||
767 | +metrics: | ||
768 | + # Enable/disable actuator metrics. | ||
769 | + enabled: "${METRICS_ENABLED:false}" | ||
770 | + | ||
771 | +management: | ||
772 | + endpoints: | ||
773 | + web: | ||
774 | + exposure: | ||
775 | + # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). | ||
776 | + include: '${METRICS_ENDPOINTS_EXPOSE:info}' |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard</groupId> | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>common</artifactId> | 24 | <artifactId>common</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <groupId>org.thingsboard.common</groupId> | 26 | <groupId>org.thingsboard.common</groupId> |
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 | +package org.thingsboard.server.actors; | ||
17 | + | ||
18 | +public interface JsInvokeStats { | ||
19 | + default void incrementRequests() { | ||
20 | + incrementRequests(1); | ||
21 | + } | ||
22 | + | ||
23 | + void incrementRequests(int amount); | ||
24 | + | ||
25 | + default void incrementResponses() { | ||
26 | + incrementResponses(1); | ||
27 | + } | ||
28 | + | ||
29 | + void incrementResponses(int amount); | ||
30 | + | ||
31 | + default void incrementFailures() { | ||
32 | + incrementFailures(1); | ||
33 | + } | ||
34 | + | ||
35 | + void incrementFailures(int amount); | ||
36 | + | ||
37 | + int getRequests(); | ||
38 | + | ||
39 | + int getResponses(); | ||
40 | + | ||
41 | + int getFailures(); | ||
42 | + | ||
43 | + void reset(); | ||
44 | +} |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard</groupId> | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>common</artifactId> | 24 | <artifactId>common</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <groupId>org.thingsboard.common</groupId> | 26 | <groupId>org.thingsboard.common</groupId> |
@@ -17,5 +17,9 @@ package org.thingsboard.server.dao.util; | @@ -17,5 +17,9 @@ package org.thingsboard.server.dao.util; | ||
17 | 17 | ||
18 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | 18 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
19 | 19 | ||
20 | +import java.lang.annotation.Retention; | ||
21 | +import java.lang.annotation.RetentionPolicy; | ||
22 | + | ||
23 | +@Retention(RetentionPolicy.RUNTIME) | ||
20 | @ConditionalOnExpression("'${database.ts.type}'=='sql' && '${spring.jpa.database-platform}'=='org.hibernate.dialect.PostgreSQLDialect'") | 24 | @ConditionalOnExpression("'${database.ts.type}'=='sql' && '${spring.jpa.database-platform}'=='org.hibernate.dialect.PostgreSQLDialect'") |
21 | public @interface PsqlTsDao { } | 25 | public @interface PsqlTsDao { } |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard</groupId> | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>common</artifactId> | 24 | <artifactId>common</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <groupId>org.thingsboard.common</groupId> | 26 | <groupId>org.thingsboard.common</groupId> |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard</groupId> | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>common</artifactId> | 24 | <artifactId>common</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <groupId>org.thingsboard.common</groupId> | 26 | <groupId>org.thingsboard.common</groupId> |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard</groupId> | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>thingsboard</artifactId> | 24 | <artifactId>thingsboard</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <artifactId>common</artifactId> | 26 | <artifactId>common</artifactId> |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard</groupId> | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>common</artifactId> | 24 | <artifactId>common</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <groupId>org.thingsboard.common</groupId> | 26 | <groupId>org.thingsboard.common</groupId> |
@@ -91,8 +91,6 @@ public class DefaultTbQueueRequestTemplate<Request extends TbQueueMsg, Response | @@ -91,8 +91,6 @@ public class DefaultTbQueueRequestTemplate<Request extends TbQueueMsg, Response | ||
91 | List<Response> responses = responseTemplate.poll(pollInterval); | 91 | List<Response> responses = responseTemplate.poll(pollInterval); |
92 | if (responses.size() > 0) { | 92 | if (responses.size() > 0) { |
93 | log.trace("Polling responses completed, consumer records count [{}]", responses.size()); | 93 | log.trace("Polling responses completed, consumer records count [{}]", responses.size()); |
94 | - } else { | ||
95 | - continue; | ||
96 | } | 94 | } |
97 | responses.forEach(response -> { | 95 | responses.forEach(response -> { |
98 | byte[] requestIdHeader = response.getHeaders().get(REQUEST_ID_HEADER); | 96 | byte[] requestIdHeader = response.getHeaders().get(REQUEST_ID_HEADER); |
@@ -23,6 +23,7 @@ import org.thingsboard.server.queue.TbQueueHandler; | @@ -23,6 +23,7 @@ import org.thingsboard.server.queue.TbQueueHandler; | ||
23 | import org.thingsboard.server.queue.TbQueueMsg; | 23 | import org.thingsboard.server.queue.TbQueueMsg; |
24 | import org.thingsboard.server.queue.TbQueueProducer; | 24 | import org.thingsboard.server.queue.TbQueueProducer; |
25 | import org.thingsboard.server.queue.TbQueueResponseTemplate; | 25 | import org.thingsboard.server.queue.TbQueueResponseTemplate; |
26 | +import org.thingsboard.server.queue.stats.QueueStats; | ||
26 | 27 | ||
27 | import java.util.List; | 28 | import java.util.List; |
28 | import java.util.UUID; | 29 | import java.util.UUID; |
@@ -44,6 +45,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | @@ -44,6 +45,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | ||
44 | private final ExecutorService loopExecutor; | 45 | private final ExecutorService loopExecutor; |
45 | private final ScheduledExecutorService timeoutExecutor; | 46 | private final ScheduledExecutorService timeoutExecutor; |
46 | private final ExecutorService callbackExecutor; | 47 | private final ExecutorService callbackExecutor; |
48 | + private final QueueStats stats; | ||
47 | private final int maxPendingRequests; | 49 | private final int maxPendingRequests; |
48 | private final long requestTimeout; | 50 | private final long requestTimeout; |
49 | 51 | ||
@@ -58,7 +60,8 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | @@ -58,7 +60,8 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | ||
58 | long pollInterval, | 60 | long pollInterval, |
59 | long requestTimeout, | 61 | long requestTimeout, |
60 | int maxPendingRequests, | 62 | int maxPendingRequests, |
61 | - ExecutorService executor) { | 63 | + ExecutorService executor, |
64 | + QueueStats stats) { | ||
62 | this.requestTemplate = requestTemplate; | 65 | this.requestTemplate = requestTemplate; |
63 | this.responseTemplate = responseTemplate; | 66 | this.responseTemplate = responseTemplate; |
64 | this.pendingRequests = new ConcurrentHashMap<>(); | 67 | this.pendingRequests = new ConcurrentHashMap<>(); |
@@ -66,6 +69,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | @@ -66,6 +69,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | ||
66 | this.pollInterval = pollInterval; | 69 | this.pollInterval = pollInterval; |
67 | this.requestTimeout = requestTimeout; | 70 | this.requestTimeout = requestTimeout; |
68 | this.callbackExecutor = executor; | 71 | this.callbackExecutor = executor; |
72 | + this.stats = stats; | ||
69 | this.timeoutExecutor = Executors.newSingleThreadScheduledExecutor(); | 73 | this.timeoutExecutor = Executors.newSingleThreadScheduledExecutor(); |
70 | this.loopExecutor = Executors.newSingleThreadExecutor(); | 74 | this.loopExecutor = Executors.newSingleThreadExecutor(); |
71 | } | 75 | } |
@@ -108,11 +112,13 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | @@ -108,11 +112,13 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | ||
108 | String responseTopic = bytesToString(responseTopicHeader); | 112 | String responseTopic = bytesToString(responseTopicHeader); |
109 | try { | 113 | try { |
110 | pendingRequestCount.getAndIncrement(); | 114 | pendingRequestCount.getAndIncrement(); |
115 | + stats.incrementTotal(); | ||
111 | AsyncCallbackTemplate.withCallbackAndTimeout(handler.handle(request), | 116 | AsyncCallbackTemplate.withCallbackAndTimeout(handler.handle(request), |
112 | response -> { | 117 | response -> { |
113 | pendingRequestCount.decrementAndGet(); | 118 | pendingRequestCount.decrementAndGet(); |
114 | response.getHeaders().put(REQUEST_ID_HEADER, uuidToBytes(requestId)); | 119 | response.getHeaders().put(REQUEST_ID_HEADER, uuidToBytes(requestId)); |
115 | responseTemplate.send(TopicPartitionInfo.builder().topic(responseTopic).build(), response, null); | 120 | responseTemplate.send(TopicPartitionInfo.builder().topic(responseTopic).build(), response, null); |
121 | + stats.incrementSuccessful(); | ||
116 | }, | 122 | }, |
117 | e -> { | 123 | e -> { |
118 | pendingRequestCount.decrementAndGet(); | 124 | pendingRequestCount.decrementAndGet(); |
@@ -121,6 +127,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | @@ -121,6 +127,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | ||
121 | } else { | 127 | } else { |
122 | log.trace("[{}] Failed to process the request: {}", requestId, request, e); | 128 | log.trace("[{}] Failed to process the request: {}", requestId, request, e); |
123 | } | 129 | } |
130 | + stats.incrementFailed(); | ||
124 | }, | 131 | }, |
125 | requestTimeout, | 132 | requestTimeout, |
126 | timeoutExecutor, | 133 | timeoutExecutor, |
@@ -128,6 +135,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | @@ -128,6 +135,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | ||
128 | } catch (Throwable e) { | 135 | } catch (Throwable e) { |
129 | pendingRequestCount.decrementAndGet(); | 136 | pendingRequestCount.decrementAndGet(); |
130 | log.warn("[{}] Failed to process the request: {}", requestId, request, e); | 137 | log.warn("[{}] Failed to process the request: {}", requestId, request, e); |
138 | + stats.incrementFailed(); | ||
131 | } | 139 | } |
132 | } | 140 | } |
133 | }); | 141 | }); |
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 | +package org.thingsboard.server.queue.stats; | ||
17 | + | ||
18 | +public interface QueueStats { | ||
19 | + default void incrementTotal() { | ||
20 | + incrementTotal(1); | ||
21 | + } | ||
22 | + | ||
23 | + void incrementTotal(int amount); | ||
24 | + | ||
25 | + default void incrementSuccessful() { | ||
26 | + incrementSuccessful(1); | ||
27 | + } | ||
28 | + | ||
29 | + void incrementSuccessful(int amount); | ||
30 | + | ||
31 | + | ||
32 | + default void incrementFailed() { | ||
33 | + incrementFailed(1); | ||
34 | + } | ||
35 | + | ||
36 | + void incrementFailed(int amount); | ||
37 | +} |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard.common</groupId> | 22 | <groupId>org.thingsboard.common</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>transport</artifactId> | 24 | <artifactId>transport</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <groupId>org.thingsboard.common.transport</groupId> | 26 | <groupId>org.thingsboard.common.transport</groupId> |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard.common</groupId> | 22 | <groupId>org.thingsboard.common</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>transport</artifactId> | 24 | <artifactId>transport</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <groupId>org.thingsboard.common.transport</groupId> | 26 | <groupId>org.thingsboard.common.transport</groupId> |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard.common</groupId> | 22 | <groupId>org.thingsboard.common</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>transport</artifactId> | 24 | <artifactId>transport</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <groupId>org.thingsboard.common.transport</groupId> | 26 | <groupId>org.thingsboard.common.transport</groupId> |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard</groupId> | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>common</artifactId> | 24 | <artifactId>common</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <groupId>org.thingsboard.common</groupId> | 26 | <groupId>org.thingsboard.common</groupId> |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard.common</groupId> | 22 | <groupId>org.thingsboard.common</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>transport</artifactId> | 24 | <artifactId>transport</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <groupId>org.thingsboard.common.transport</groupId> | 26 | <groupId>org.thingsboard.common.transport</groupId> |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard</groupId> | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>common</artifactId> | 24 | <artifactId>common</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <groupId>org.thingsboard.common</groupId> | 26 | <groupId>org.thingsboard.common</groupId> |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <modelVersion>4.0.0</modelVersion> | 20 | <modelVersion>4.0.0</modelVersion> |
21 | <parent> | 21 | <parent> |
22 | <groupId>org.thingsboard</groupId> | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>2.5.3-SNAPSHOT</version> | 23 | + <version>3.1.0-SNAPSHOT</version> |
24 | <artifactId>thingsboard</artifactId> | 24 | <artifactId>thingsboard</artifactId> |
25 | </parent> | 25 | </parent> |
26 | <artifactId>dao</artifactId> | 26 | <artifactId>dao</artifactId> |
@@ -91,26 +91,26 @@ | @@ -91,26 +91,26 @@ | ||
91 | <artifactId>mockito-all</artifactId> | 91 | <artifactId>mockito-all</artifactId> |
92 | <scope>test</scope> | 92 | <scope>test</scope> |
93 | </dependency> | 93 | </dependency> |
94 | - <dependency> | ||
95 | - <groupId>org.apache.commons</groupId> | ||
96 | - <artifactId>commons-lang3</artifactId> | ||
97 | - </dependency> | ||
98 | - <dependency> | ||
99 | - <groupId>commons-validator</groupId> | ||
100 | - <artifactId>commons-validator</artifactId> | ||
101 | - </dependency> | ||
102 | - <dependency> | ||
103 | - <groupId>com.fasterxml.jackson.core</groupId> | ||
104 | - <artifactId>jackson-databind</artifactId> | ||
105 | - </dependency> | 94 | + <dependency> |
95 | + <groupId>org.apache.commons</groupId> | ||
96 | + <artifactId>commons-lang3</artifactId> | ||
97 | + </dependency> | ||
98 | + <dependency> | ||
99 | + <groupId>commons-collections</groupId> | ||
100 | + <artifactId>commons-collections</artifactId> | ||
101 | + </dependency> | ||
102 | + <dependency> | ||
103 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
104 | + <artifactId>jackson-databind</artifactId> | ||
105 | + </dependency> | ||
106 | <dependency> | 106 | <dependency> |
107 | <groupId>org.springframework</groupId> | 107 | <groupId>org.springframework</groupId> |
108 | <artifactId>spring-context</artifactId> | 108 | <artifactId>spring-context</artifactId> |
109 | </dependency> | 109 | </dependency> |
110 | - <dependency> | ||
111 | - <groupId>org.springframework</groupId> | ||
112 | - <artifactId>spring-tx</artifactId> | ||
113 | - </dependency> | 110 | + <dependency> |
111 | + <groupId>org.springframework</groupId> | ||
112 | + <artifactId>spring-tx</artifactId> | ||
113 | + </dependency> | ||
114 | <dependency> | 114 | <dependency> |
115 | <groupId>org.springframework</groupId> | 115 | <groupId>org.springframework</groupId> |
116 | <artifactId>spring-web</artifactId> | 116 | <artifactId>spring-web</artifactId> |
@@ -136,8 +136,8 @@ | @@ -136,8 +136,8 @@ | ||
136 | <groupId>io.takari.junit</groupId> | 136 | <groupId>io.takari.junit</groupId> |
137 | <artifactId>takari-cpsuite</artifactId> | 137 | <artifactId>takari-cpsuite</artifactId> |
138 | <scope>test</scope> | 138 | <scope>test</scope> |
139 | - </dependency> | ||
140 | - <dependency> | 139 | + </dependency> |
140 | + <dependency> | ||
141 | <groupId>com.google.guava</groupId> | 141 | <groupId>com.google.guava</groupId> |
142 | <artifactId>guava</artifactId> | 142 | <artifactId>guava</artifactId> |
143 | </dependency> | 143 | </dependency> |
@@ -219,18 +219,18 @@ | @@ -219,18 +219,18 @@ | ||
219 | </includes> | 219 | </includes> |
220 | </configuration> | 220 | </configuration> |
221 | </plugin> | 221 | </plugin> |
222 | - <plugin> | ||
223 | - <groupId>org.apache.maven.plugins</groupId> | ||
224 | - <artifactId>maven-jar-plugin</artifactId> | 222 | + <plugin> |
223 | + <groupId>org.apache.maven.plugins</groupId> | ||
224 | + <artifactId>maven-jar-plugin</artifactId> | ||
225 | <version>${jar-plugin.version}</version> | 225 | <version>${jar-plugin.version}</version> |
226 | - <executions> | ||
227 | - <execution> | ||
228 | - <goals> | ||
229 | - <goal>test-jar</goal> | ||
230 | - </goals> | ||
231 | - </execution> | ||
232 | - </executions> | ||
233 | - </plugin> | 226 | + <executions> |
227 | + <execution> | ||
228 | + <goals> | ||
229 | + <goal>test-jar</goal> | ||
230 | + </goals> | ||
231 | + </execution> | ||
232 | + </executions> | ||
233 | + </plugin> | ||
234 | </plugins> | 234 | </plugins> |
235 | </build> | 235 | </build> |
236 | </project> | 236 | </project> |
@@ -17,7 +17,6 @@ package org.thingsboard.server.dao.service; | @@ -17,7 +17,6 @@ package org.thingsboard.server.dao.service; | ||
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
20 | -import org.apache.commons.validator.routines.EmailValidator; | ||
21 | import org.thingsboard.server.common.data.BaseData; | 20 | import org.thingsboard.server.common.data.BaseData; |
22 | import org.thingsboard.server.common.data.id.TenantId; | 21 | import org.thingsboard.server.common.data.id.TenantId; |
23 | import org.thingsboard.server.dao.exception.DataValidationException; | 22 | import org.thingsboard.server.dao.exception.DataValidationException; |
@@ -26,11 +25,13 @@ import java.util.HashSet; | @@ -26,11 +25,13 @@ import java.util.HashSet; | ||
26 | import java.util.Iterator; | 25 | import java.util.Iterator; |
27 | import java.util.Set; | 26 | import java.util.Set; |
28 | import java.util.function.Function; | 27 | import java.util.function.Function; |
28 | +import java.util.regex.Matcher; | ||
29 | +import java.util.regex.Pattern; | ||
29 | 30 | ||
30 | @Slf4j | 31 | @Slf4j |
31 | public abstract class DataValidator<D extends BaseData<?>> { | 32 | public abstract class DataValidator<D extends BaseData<?>> { |
32 | - | ||
33 | - private static EmailValidator emailValidator = EmailValidator.getInstance(); | 33 | + private static final Pattern EMAIL_PATTERN = |
34 | + Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$", Pattern.CASE_INSENSITIVE); | ||
34 | 35 | ||
35 | public void validate(D data, Function<D, TenantId> tenantIdFunction) { | 36 | public void validate(D data, Function<D, TenantId> tenantIdFunction) { |
36 | try { | 37 | try { |
@@ -63,12 +64,21 @@ public abstract class DataValidator<D extends BaseData<?>> { | @@ -63,12 +64,21 @@ public abstract class DataValidator<D extends BaseData<?>> { | ||
63 | return actualData.getId() != null && existentData.getId().equals(actualData.getId()); | 64 | return actualData.getId() != null && existentData.getId().equals(actualData.getId()); |
64 | } | 65 | } |
65 | 66 | ||
66 | - protected static void validateEmail(String email) { | ||
67 | - if (!emailValidator.isValid(email)) { | 67 | + public static void validateEmail(String email) { |
68 | + if (!doValidateEmail(email)) { | ||
68 | throw new DataValidationException("Invalid email address format '" + email + "'!"); | 69 | throw new DataValidationException("Invalid email address format '" + email + "'!"); |
69 | } | 70 | } |
70 | } | 71 | } |
71 | 72 | ||
73 | + private static boolean doValidateEmail(String email) { | ||
74 | + if (email == null) { | ||
75 | + return false; | ||
76 | + } | ||
77 | + | ||
78 | + Matcher emailMatcher = EMAIL_PATTERN.matcher(email); | ||
79 | + return emailMatcher.matches(); | ||
80 | + } | ||
81 | + | ||
72 | protected static void validateJsonStructure(JsonNode expectedNode, JsonNode actualNode) { | 82 | protected static void validateJsonStructure(JsonNode expectedNode, JsonNode actualNode) { |
73 | Set<String> expectedFields = new HashSet<>(); | 83 | Set<String> expectedFields = new HashSet<>(); |
74 | Iterator<String> fieldsIterator = expectedNode.fieldNames(); | 84 | Iterator<String> fieldsIterator = expectedNode.fieldNames(); |
@@ -41,16 +41,14 @@ public class TbSqlBlockingQueue<E> implements TbSqlQueue<E> { | @@ -41,16 +41,14 @@ public class TbSqlBlockingQueue<E> implements TbSqlQueue<E> { | ||
41 | private final TbSqlBlockingQueueParams params; | 41 | private final TbSqlBlockingQueueParams params; |
42 | 42 | ||
43 | private ExecutorService executor; | 43 | private ExecutorService executor; |
44 | - private ScheduledLogExecutorComponent logExecutor; | ||
45 | 44 | ||
46 | public TbSqlBlockingQueue(TbSqlBlockingQueueParams params) { | 45 | public TbSqlBlockingQueue(TbSqlBlockingQueueParams params) { |
47 | this.params = params; | 46 | this.params = params; |
48 | } | 47 | } |
49 | 48 | ||
50 | @Override | 49 | @Override |
51 | - public void init(ScheduledLogExecutorComponent logExecutor, Consumer<List<E>> saveFunction) { | ||
52 | - this.logExecutor = logExecutor; | ||
53 | - executor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("sql-queue-" + params.getLogName().toLowerCase())); | 50 | + public void init(ScheduledLogExecutorComponent logExecutor, Consumer<List<E>> saveFunction, int index) { |
51 | + executor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("sql-queue-" + index + "-" + params.getLogName().toLowerCase())); | ||
54 | executor.submit(() -> { | 52 | executor.submit(() -> { |
55 | String logName = params.getLogName(); | 53 | String logName = params.getLogName(); |
56 | int batchSize = params.getBatchSize(); | 54 | int batchSize = params.getBatchSize(); |
@@ -94,7 +92,7 @@ public class TbSqlBlockingQueue<E> implements TbSqlQueue<E> { | @@ -94,7 +92,7 @@ public class TbSqlBlockingQueue<E> implements TbSqlQueue<E> { | ||
94 | 92 | ||
95 | logExecutor.scheduleAtFixedRate(() -> { | 93 | logExecutor.scheduleAtFixedRate(() -> { |
96 | if (queue.size() > 0 || addedCount.get() > 0 || savedCount.get() > 0 || failedCount.get() > 0) { | 94 | if (queue.size() > 0 || addedCount.get() > 0 || savedCount.get() > 0 || failedCount.get() > 0) { |
97 | - log.info("[{}] queueSize [{}] totalAdded [{}] totalSaved [{}] totalFailed [{}]", | 95 | + log.info("Queue-{} [{}] queueSize [{}] totalAdded [{}] totalSaved [{}] totalFailed [{}]", index, |
98 | params.getLogName(), queue.size(), addedCount.getAndSet(0), savedCount.getAndSet(0), failedCount.getAndSet(0)); | 96 | params.getLogName(), queue.size(), addedCount.getAndSet(0), savedCount.getAndSet(0), failedCount.getAndSet(0)); |
99 | } | 97 | } |
100 | }, params.getStatsPrintIntervalMs(), params.getStatsPrintIntervalMs(), TimeUnit.MILLISECONDS); | 98 | }, params.getStatsPrintIntervalMs(), params.getStatsPrintIntervalMs(), TimeUnit.MILLISECONDS); |
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 | +package org.thingsboard.server.dao.sql; | ||
17 | + | ||
18 | +import com.google.common.util.concurrent.ListenableFuture; | ||
19 | +import lombok.Data; | ||
20 | +import lombok.extern.slf4j.Slf4j; | ||
21 | + | ||
22 | +import java.util.List; | ||
23 | +import java.util.concurrent.CopyOnWriteArrayList; | ||
24 | +import java.util.function.Consumer; | ||
25 | +import java.util.function.Function; | ||
26 | + | ||
27 | +@Slf4j | ||
28 | +@Data | ||
29 | +public class TbSqlBlockingQueueWrapper<E> { | ||
30 | + private final CopyOnWriteArrayList<TbSqlBlockingQueue<E>> queues = new CopyOnWriteArrayList<>(); | ||
31 | + private final TbSqlBlockingQueueParams params; | ||
32 | + private ScheduledLogExecutorComponent logExecutor; | ||
33 | + private final Function<E, Integer> hashCodeFunction; | ||
34 | + private final int maxThreads; | ||
35 | + | ||
36 | + public void init(ScheduledLogExecutorComponent logExecutor, Consumer<List<E>> saveFunction) { | ||
37 | + for (int i = 0; i < maxThreads; i++) { | ||
38 | + TbSqlBlockingQueue<E> queue = new TbSqlBlockingQueue<>(params); | ||
39 | + queues.add(queue); | ||
40 | + queue.init(logExecutor, saveFunction, i); | ||
41 | + } | ||
42 | + } | ||
43 | + | ||
44 | + public ListenableFuture<Void> add(E element) { | ||
45 | + int queueIndex = element != null ? (hashCodeFunction.apply(element) & 0x7FFFFFFF) % maxThreads : 0; | ||
46 | + return queues.get(queueIndex).add(element); | ||
47 | + } | ||
48 | + | ||
49 | + public void destroy() { | ||
50 | + queues.forEach(TbSqlBlockingQueue::destroy); | ||
51 | + } | ||
52 | +} |
@@ -22,7 +22,7 @@ import java.util.function.Consumer; | @@ -22,7 +22,7 @@ import java.util.function.Consumer; | ||
22 | 22 | ||
23 | public interface TbSqlQueue<E> { | 23 | public interface TbSqlQueue<E> { |
24 | 24 | ||
25 | - void init(ScheduledLogExecutorComponent logExecutor, Consumer<List<E>> saveFunction); | 25 | + void init(ScheduledLogExecutorComponent logExecutor, Consumer<List<E>> saveFunction, int queueIndex); |
26 | 26 | ||
27 | void destroy(); | 27 | void destroy(); |
28 | 28 |
@@ -31,8 +31,8 @@ import org.thingsboard.server.dao.model.sql.AttributeKvCompositeKey; | @@ -31,8 +31,8 @@ import org.thingsboard.server.dao.model.sql.AttributeKvCompositeKey; | ||
31 | import org.thingsboard.server.dao.model.sql.AttributeKvEntity; | 31 | import org.thingsboard.server.dao.model.sql.AttributeKvEntity; |
32 | import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; | 32 | import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; |
33 | import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; | 33 | import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; |
34 | -import org.thingsboard.server.dao.sql.TbSqlBlockingQueue; | ||
35 | import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; | 34 | import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; |
35 | +import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; | ||
36 | import org.thingsboard.server.dao.util.SqlDao; | 36 | import org.thingsboard.server.dao.util.SqlDao; |
37 | 37 | ||
38 | import javax.annotation.PostConstruct; | 38 | import javax.annotation.PostConstruct; |
@@ -40,6 +40,7 @@ import javax.annotation.PreDestroy; | @@ -40,6 +40,7 @@ import javax.annotation.PreDestroy; | ||
40 | import java.util.Collection; | 40 | import java.util.Collection; |
41 | import java.util.List; | 41 | import java.util.List; |
42 | import java.util.Optional; | 42 | import java.util.Optional; |
43 | +import java.util.function.Function; | ||
43 | import java.util.stream.Collectors; | 44 | import java.util.stream.Collectors; |
44 | 45 | ||
45 | @Component | 46 | @Component |
@@ -65,7 +66,10 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl | @@ -65,7 +66,10 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl | ||
65 | @Value("${sql.attributes.stats_print_interval_ms:1000}") | 66 | @Value("${sql.attributes.stats_print_interval_ms:1000}") |
66 | private long statsPrintIntervalMs; | 67 | private long statsPrintIntervalMs; |
67 | 68 | ||
68 | - private TbSqlBlockingQueue<AttributeKvEntity> queue; | 69 | + @Value("${sql.attributes.batch_threads:4}") |
70 | + private int batchThreads; | ||
71 | + | ||
72 | + private TbSqlBlockingQueueWrapper<AttributeKvEntity> queue; | ||
69 | 73 | ||
70 | @PostConstruct | 74 | @PostConstruct |
71 | private void init() { | 75 | private void init() { |
@@ -75,7 +79,9 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl | @@ -75,7 +79,9 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl | ||
75 | .maxDelay(maxDelay) | 79 | .maxDelay(maxDelay) |
76 | .statsPrintIntervalMs(statsPrintIntervalMs) | 80 | .statsPrintIntervalMs(statsPrintIntervalMs) |
77 | .build(); | 81 | .build(); |
78 | - queue = new TbSqlBlockingQueue<>(params); | 82 | + |
83 | + Function<AttributeKvEntity, Integer> hashcodeFunction = entity -> entity.getId().getEntityId().hashCode(); | ||
84 | + queue = new TbSqlBlockingQueueWrapper<>(params, hashcodeFunction, batchThreads); | ||
79 | queue.init(logExecutor, v -> attributeKvInsertRepository.saveOrUpdate(v)); | 85 | queue.init(logExecutor, v -> attributeKvInsertRepository.saveOrUpdate(v)); |
80 | } | 86 | } |
81 | 87 |
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.sqlts; | @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.sqlts; | ||
17 | 17 | ||
18 | import com.google.common.util.concurrent.Futures; | 18 | import com.google.common.util.concurrent.Futures; |
19 | import com.google.common.util.concurrent.ListenableFuture; | 19 | import com.google.common.util.concurrent.ListenableFuture; |
20 | +import com.google.common.util.concurrent.ListeningExecutorService; | ||
20 | import com.google.common.util.concurrent.MoreExecutors; | 21 | import com.google.common.util.concurrent.MoreExecutors; |
21 | import com.google.common.util.concurrent.SettableFuture; | 22 | import com.google.common.util.concurrent.SettableFuture; |
22 | import lombok.extern.slf4j.Slf4j; | 23 | import lombok.extern.slf4j.Slf4j; |
@@ -31,8 +32,8 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQuery; | @@ -31,8 +32,8 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQuery; | ||
31 | import org.thingsboard.server.common.data.kv.TsKvEntry; | 32 | import org.thingsboard.server.common.data.kv.TsKvEntry; |
32 | import org.thingsboard.server.dao.DaoUtil; | 33 | import org.thingsboard.server.dao.DaoUtil; |
33 | import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; | 34 | import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; |
34 | -import org.thingsboard.server.dao.sql.TbSqlBlockingQueue; | ||
35 | import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; | 35 | import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; |
36 | +import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; | ||
36 | import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; | 37 | import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; |
37 | import org.thingsboard.server.dao.sqlts.ts.TsKvRepository; | 38 | import org.thingsboard.server.dao.sqlts.ts.TsKvRepository; |
38 | import org.thingsboard.server.dao.timeseries.TimeseriesDao; | 39 | import org.thingsboard.server.dao.timeseries.TimeseriesDao; |
@@ -43,6 +44,7 @@ import java.util.ArrayList; | @@ -43,6 +44,7 @@ import java.util.ArrayList; | ||
43 | import java.util.List; | 44 | import java.util.List; |
44 | import java.util.Optional; | 45 | import java.util.Optional; |
45 | import java.util.concurrent.CompletableFuture; | 46 | import java.util.concurrent.CompletableFuture; |
47 | +import java.util.function.Function; | ||
46 | import java.util.stream.Collectors; | 48 | import java.util.stream.Collectors; |
47 | 49 | ||
48 | @Slf4j | 50 | @Slf4j |
@@ -54,7 +56,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq | @@ -54,7 +56,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq | ||
54 | @Autowired | 56 | @Autowired |
55 | protected InsertTsRepository<TsKvEntity> insertRepository; | 57 | protected InsertTsRepository<TsKvEntity> insertRepository; |
56 | 58 | ||
57 | - protected TbSqlBlockingQueue<TsKvEntity> tsQueue; | 59 | + protected TbSqlBlockingQueueWrapper<TsKvEntity> tsQueue; |
58 | 60 | ||
59 | @PostConstruct | 61 | @PostConstruct |
60 | protected void init() { | 62 | protected void init() { |
@@ -65,7 +67,9 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq | @@ -65,7 +67,9 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq | ||
65 | .maxDelay(tsMaxDelay) | 67 | .maxDelay(tsMaxDelay) |
66 | .statsPrintIntervalMs(tsStatsPrintIntervalMs) | 68 | .statsPrintIntervalMs(tsStatsPrintIntervalMs) |
67 | .build(); | 69 | .build(); |
68 | - tsQueue = new TbSqlBlockingQueue<>(tsParams); | 70 | + |
71 | + Function<TsKvEntity, Integer> hashcodeFunction = entity -> entity.getEntityId().hashCode(); | ||
72 | + tsQueue = new TbSqlBlockingQueueWrapper<>(tsParams, hashcodeFunction, tsBatchThreads); | ||
69 | tsQueue.init(logExecutor, v -> insertRepository.saveOrUpdate(v)); | 73 | tsQueue.init(logExecutor, v -> insertRepository.saveOrUpdate(v)); |
70 | } | 74 | } |
71 | 75 |
@@ -41,8 +41,8 @@ import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestCompositeKey; | @@ -41,8 +41,8 @@ import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestCompositeKey; | ||
41 | import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity; | 41 | import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity; |
42 | import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; | 42 | import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; |
43 | import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; | 43 | import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; |
44 | -import org.thingsboard.server.dao.sql.TbSqlBlockingQueue; | ||
45 | import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; | 44 | import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; |
45 | +import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; | ||
46 | import org.thingsboard.server.dao.sqlts.dictionary.TsKvDictionaryRepository; | 46 | import org.thingsboard.server.dao.sqlts.dictionary.TsKvDictionaryRepository; |
47 | import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository; | 47 | import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository; |
48 | import org.thingsboard.server.dao.sqlts.latest.SearchTsKvLatestRepository; | 48 | import org.thingsboard.server.dao.sqlts.latest.SearchTsKvLatestRepository; |
@@ -52,7 +52,10 @@ import org.thingsboard.server.dao.timeseries.SimpleListenableFuture; | @@ -52,7 +52,10 @@ import org.thingsboard.server.dao.timeseries.SimpleListenableFuture; | ||
52 | import javax.annotation.Nullable; | 52 | import javax.annotation.Nullable; |
53 | import javax.annotation.PostConstruct; | 53 | import javax.annotation.PostConstruct; |
54 | import javax.annotation.PreDestroy; | 54 | import javax.annotation.PreDestroy; |
55 | +import java.util.ArrayList; | ||
56 | +import java.util.HashMap; | ||
55 | import java.util.List; | 57 | import java.util.List; |
58 | +import java.util.Map; | ||
56 | import java.util.Objects; | 59 | import java.util.Objects; |
57 | import java.util.Optional; | 60 | import java.util.Optional; |
58 | import java.util.concurrent.ConcurrentHashMap; | 61 | import java.util.concurrent.ConcurrentHashMap; |
@@ -82,7 +85,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx | @@ -82,7 +85,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx | ||
82 | @Autowired | 85 | @Autowired |
83 | private TsKvDictionaryRepository dictionaryRepository; | 86 | private TsKvDictionaryRepository dictionaryRepository; |
84 | 87 | ||
85 | - private TbSqlBlockingQueue<TsKvLatestEntity> tsLatestQueue; | 88 | + private TbSqlBlockingQueueWrapper<TsKvLatestEntity> tsLatestQueue; |
86 | 89 | ||
87 | @Value("${sql.ts_latest.batch_size:1000}") | 90 | @Value("${sql.ts_latest.batch_size:1000}") |
88 | private int tsLatestBatchSize; | 91 | private int tsLatestBatchSize; |
@@ -93,6 +96,9 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx | @@ -93,6 +96,9 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx | ||
93 | @Value("${sql.ts_latest.stats_print_interval_ms:1000}") | 96 | @Value("${sql.ts_latest.stats_print_interval_ms:1000}") |
94 | private long tsLatestStatsPrintIntervalMs; | 97 | private long tsLatestStatsPrintIntervalMs; |
95 | 98 | ||
99 | + @Value("${sql.ts_latest.batch_threads:4}") | ||
100 | + private int tsLatestBatchThreads; | ||
101 | + | ||
96 | @Autowired | 102 | @Autowired |
97 | protected ScheduledLogExecutorComponent logExecutor; | 103 | protected ScheduledLogExecutorComponent logExecutor; |
98 | 104 | ||
@@ -105,6 +111,12 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx | @@ -105,6 +111,12 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx | ||
105 | @Value("${sql.ts.stats_print_interval_ms:1000}") | 111 | @Value("${sql.ts.stats_print_interval_ms:1000}") |
106 | protected long tsStatsPrintIntervalMs; | 112 | protected long tsStatsPrintIntervalMs; |
107 | 113 | ||
114 | + @Value("${sql.ts.batch_threads:4}") | ||
115 | + protected int tsBatchThreads; | ||
116 | + | ||
117 | + @Value("${sql.timescale.batch_threads:4}") | ||
118 | + protected int timescaleBatchThreads; | ||
119 | + | ||
108 | @PostConstruct | 120 | @PostConstruct |
109 | protected void init() { | 121 | protected void init() { |
110 | TbSqlBlockingQueueParams tsLatestParams = TbSqlBlockingQueueParams.builder() | 122 | TbSqlBlockingQueueParams tsLatestParams = TbSqlBlockingQueueParams.builder() |
@@ -113,8 +125,22 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx | @@ -113,8 +125,22 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx | ||
113 | .maxDelay(tsLatestMaxDelay) | 125 | .maxDelay(tsLatestMaxDelay) |
114 | .statsPrintIntervalMs(tsLatestStatsPrintIntervalMs) | 126 | .statsPrintIntervalMs(tsLatestStatsPrintIntervalMs) |
115 | .build(); | 127 | .build(); |
116 | - tsLatestQueue = new TbSqlBlockingQueue<>(tsLatestParams); | ||
117 | - tsLatestQueue.init(logExecutor, v -> insertLatestTsRepository.saveOrUpdate(v)); | 128 | + |
129 | + java.util.function.Function<TsKvLatestEntity, Integer> hashcodeFunction = entity -> entity.getEntityId().hashCode(); | ||
130 | + tsLatestQueue = new TbSqlBlockingQueueWrapper<>(tsLatestParams, hashcodeFunction, tsLatestBatchThreads); | ||
131 | + | ||
132 | + tsLatestQueue.init(logExecutor, v -> { | ||
133 | + Map<TsKey, TsKvLatestEntity> trueLatest = new HashMap<>(); | ||
134 | + v.forEach(ts -> { | ||
135 | + TsKey key = new TsKey(ts.getEntityId(), ts.getKey()); | ||
136 | + TsKvLatestEntity old = trueLatest.get(key); | ||
137 | + if (old == null || old.getTs() < ts.getTs()) { | ||
138 | + trueLatest.put(key, ts); | ||
139 | + } | ||
140 | + }); | ||
141 | + List<TsKvLatestEntity> latestEntities = new ArrayList<>(trueLatest.values()); | ||
142 | + insertLatestTsRepository.saveOrUpdate(latestEntities); | ||
143 | + }); | ||
118 | } | 144 | } |
119 | 145 | ||
120 | @PreDestroy | 146 | @PreDestroy |
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 | +package org.thingsboard.server.dao.sqlts; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +import java.util.UUID; | ||
21 | + | ||
22 | +@Data | ||
23 | +public class TsKey { | ||
24 | + private final UUID entityId; | ||
25 | + private final int key; | ||
26 | +} |
@@ -33,8 +33,8 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQuery; | @@ -33,8 +33,8 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQuery; | ||
33 | import org.thingsboard.server.common.data.kv.TsKvEntry; | 33 | import org.thingsboard.server.common.data.kv.TsKvEntry; |
34 | import org.thingsboard.server.dao.DaoUtil; | 34 | import org.thingsboard.server.dao.DaoUtil; |
35 | import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity; | 35 | import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity; |
36 | -import org.thingsboard.server.dao.sql.TbSqlBlockingQueue; | ||
37 | import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; | 36 | import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; |
37 | +import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; | ||
38 | import org.thingsboard.server.dao.sqlts.AbstractSqlTimeseriesDao; | 38 | import org.thingsboard.server.dao.sqlts.AbstractSqlTimeseriesDao; |
39 | import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; | 39 | import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; |
40 | import org.thingsboard.server.dao.timeseries.TimeseriesDao; | 40 | import org.thingsboard.server.dao.timeseries.TimeseriesDao; |
@@ -48,6 +48,7 @@ import java.util.List; | @@ -48,6 +48,7 @@ import java.util.List; | ||
48 | import java.util.Optional; | 48 | import java.util.Optional; |
49 | import java.util.UUID; | 49 | import java.util.UUID; |
50 | import java.util.concurrent.CompletableFuture; | 50 | import java.util.concurrent.CompletableFuture; |
51 | +import java.util.function.Function; | ||
51 | 52 | ||
52 | @Component | 53 | @Component |
53 | @Slf4j | 54 | @Slf4j |
@@ -63,7 +64,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements | @@ -63,7 +64,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements | ||
63 | @Autowired | 64 | @Autowired |
64 | protected InsertTsRepository<TimescaleTsKvEntity> insertRepository; | 65 | protected InsertTsRepository<TimescaleTsKvEntity> insertRepository; |
65 | 66 | ||
66 | - protected TbSqlBlockingQueue<TimescaleTsKvEntity> tsQueue; | 67 | + protected TbSqlBlockingQueueWrapper<TimescaleTsKvEntity> tsQueue; |
67 | 68 | ||
68 | @PostConstruct | 69 | @PostConstruct |
69 | protected void init() { | 70 | protected void init() { |
@@ -74,7 +75,10 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements | @@ -74,7 +75,10 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements | ||
74 | .maxDelay(tsMaxDelay) | 75 | .maxDelay(tsMaxDelay) |
75 | .statsPrintIntervalMs(tsStatsPrintIntervalMs) | 76 | .statsPrintIntervalMs(tsStatsPrintIntervalMs) |
76 | .build(); | 77 | .build(); |
77 | - tsQueue = new TbSqlBlockingQueue<>(tsParams); | 78 | + |
79 | + Function<TimescaleTsKvEntity, Integer> hashcodeFunction = entity -> entity.getEntityId().hashCode(); | ||
80 | + tsQueue = new TbSqlBlockingQueueWrapper<>(tsParams, hashcodeFunction, timescaleBatchThreads); | ||
81 | + | ||
78 | tsQueue.init(logExecutor, v -> insertRepository.saveOrUpdate(v)); | 82 | tsQueue.init(logExecutor, v -> insertRepository.saveOrUpdate(v)); |
79 | } | 83 | } |
80 | 84 | ||
@@ -277,4 +281,5 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements | @@ -277,4 +281,5 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements | ||
277 | startTs, | 281 | startTs, |
278 | endTs); | 282 | endTs); |
279 | } | 283 | } |
284 | + | ||
280 | } | 285 | } |
@@ -21,7 +21,7 @@ | @@ -21,7 +21,7 @@ | ||
21 | 21 | ||
22 | <parent> | 22 | <parent> |
23 | <groupId>org.thingsboard</groupId> | 23 | <groupId>org.thingsboard</groupId> |
24 | - <version>2.5.3-SNAPSHOT</version> | 24 | + <version>3.1.0-SNAPSHOT</version> |
25 | <artifactId>msa</artifactId> | 25 | <artifactId>msa</artifactId> |
26 | </parent> | 26 | </parent> |
27 | <groupId>org.thingsboard.msa</groupId> | 27 | <groupId>org.thingsboard.msa</groupId> |