Commit 8f2438d6ab57ca22b940a001e9a05e68225e6c69
Committed by
GitHub
1 parent
f673b094
SNMP devices balancing (#4254)
* Fix merge errors * Implement SNMP transports balancing * Refactor; implement transport device cache * Refactor * Finish up device lifecycle handling implementing; refactor * Refactor * Change base image to thingsboard/openjdk11 for msa snmp transport * Refactor * Change transport services names to upper-case
Showing
67 changed files
with
1831 additions
and
461 deletions
@@ -25,7 +25,6 @@ import org.springframework.stereotype.Service; | @@ -25,7 +25,6 @@ import org.springframework.stereotype.Service; | ||
25 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 25 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
26 | import org.thingsboard.server.actors.ActorSystemContext; | 26 | import org.thingsboard.server.actors.ActorSystemContext; |
27 | import org.thingsboard.server.actors.DefaultTbActorSystem; | 27 | import org.thingsboard.server.actors.DefaultTbActorSystem; |
28 | -import org.thingsboard.server.actors.TbActorId; | ||
29 | import org.thingsboard.server.actors.TbActorRef; | 28 | import org.thingsboard.server.actors.TbActorRef; |
30 | import org.thingsboard.server.actors.TbActorSystem; | 29 | import org.thingsboard.server.actors.TbActorSystem; |
31 | import org.thingsboard.server.actors.TbActorSystemSettings; | 30 | import org.thingsboard.server.actors.TbActorSystemSettings; |
@@ -33,14 +32,13 @@ import org.thingsboard.server.actors.app.AppActor; | @@ -33,14 +32,13 @@ import org.thingsboard.server.actors.app.AppActor; | ||
33 | import org.thingsboard.server.actors.app.AppInitMsg; | 32 | import org.thingsboard.server.actors.app.AppInitMsg; |
34 | import org.thingsboard.server.actors.stats.StatsActor; | 33 | import org.thingsboard.server.actors.stats.StatsActor; |
35 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; | 34 | import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; |
36 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | ||
37 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | 35 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; |
36 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; | ||
38 | 37 | ||
39 | import javax.annotation.PostConstruct; | 38 | import javax.annotation.PostConstruct; |
40 | import javax.annotation.PreDestroy; | 39 | import javax.annotation.PreDestroy; |
41 | import java.util.concurrent.ExecutorService; | 40 | import java.util.concurrent.ExecutorService; |
42 | import java.util.concurrent.Executors; | 41 | import java.util.concurrent.Executors; |
43 | -import java.util.concurrent.ScheduledExecutorService; | ||
44 | 42 | ||
45 | @Service | 43 | @Service |
46 | @Slf4j | 44 | @Slf4j |
application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java
@@ -52,7 +52,7 @@ import org.thingsboard.server.dao.usagerecord.ApiUsageStateService; | @@ -52,7 +52,7 @@ import org.thingsboard.server.dao.usagerecord.ApiUsageStateService; | ||
52 | import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; | 52 | import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; |
53 | import org.thingsboard.server.gen.transport.TransportProtos.UsageStatsKVProto; | 53 | import org.thingsboard.server.gen.transport.TransportProtos.UsageStatsKVProto; |
54 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 54 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
55 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 55 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
56 | import org.thingsboard.server.queue.discovery.PartitionService; | 56 | import org.thingsboard.server.queue.discovery.PartitionService; |
57 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | 57 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; |
58 | import org.thingsboard.server.queue.scheduler.SchedulerComponent; | 58 | import org.thingsboard.server.queue.scheduler.SchedulerComponent; |
@@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.id.TenantProfileId; | @@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.id.TenantProfileId; | ||
22 | import org.thingsboard.server.common.msg.queue.TbCallback; | 22 | import org.thingsboard.server.common.msg.queue.TbCallback; |
23 | import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; | 23 | import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; |
24 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 24 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
25 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 25 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
26 | 26 | ||
27 | public interface TbApiUsageStateService extends ApplicationListener<PartitionChangeEvent> { | 27 | public interface TbApiUsageStateService extends ApplicationListener<PartitionChangeEvent> { |
28 | 28 |
@@ -52,7 +52,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceM | @@ -52,7 +52,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceM | ||
52 | import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; | 52 | import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; |
53 | import org.thingsboard.server.queue.TbQueueConsumer; | 53 | import org.thingsboard.server.queue.TbQueueConsumer; |
54 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 54 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
55 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 55 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
56 | import org.thingsboard.server.queue.provider.TbCoreQueueFactory; | 56 | import org.thingsboard.server.queue.provider.TbCoreQueueFactory; |
57 | import org.thingsboard.server.queue.util.TbCoreComponent; | 57 | import org.thingsboard.server.queue.util.TbCoreComponent; |
58 | import org.thingsboard.server.service.apiusage.TbApiUsageStateService; | 58 | import org.thingsboard.server.service.apiusage.TbApiUsageStateService; |
@@ -38,7 +38,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; | @@ -38,7 +38,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; | ||
38 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; | 38 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; |
39 | import org.thingsboard.server.queue.TbQueueConsumer; | 39 | import org.thingsboard.server.queue.TbQueueConsumer; |
40 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 40 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
41 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 41 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
42 | import org.thingsboard.server.queue.provider.TbRuleEngineQueueFactory; | 42 | import org.thingsboard.server.queue.provider.TbRuleEngineQueueFactory; |
43 | import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; | 43 | import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; |
44 | import org.thingsboard.server.queue.settings.TbRuleEngineQueueConfiguration; | 44 | import org.thingsboard.server.queue.settings.TbRuleEngineQueueConfiguration; |
@@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
16 | package org.thingsboard.server.service.queue; | 16 | package org.thingsboard.server.service.queue; |
17 | 17 | ||
18 | import org.springframework.context.ApplicationListener; | 18 | import org.springframework.context.ApplicationListener; |
19 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 19 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
20 | 20 | ||
21 | public interface TbCoreConsumerService extends ApplicationListener<PartitionChangeEvent> { | 21 | public interface TbCoreConsumerService extends ApplicationListener<PartitionChangeEvent> { |
22 | 22 |
@@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
16 | package org.thingsboard.server.service.queue; | 16 | package org.thingsboard.server.service.queue; |
17 | 17 | ||
18 | import org.springframework.context.ApplicationListener; | 18 | import org.springframework.context.ApplicationListener; |
19 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 19 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
20 | 20 | ||
21 | public interface TbRuleEngineConsumerService extends ApplicationListener<PartitionChangeEvent> { | 21 | public interface TbRuleEngineConsumerService extends ApplicationListener<PartitionChangeEvent> { |
22 | 22 |
@@ -34,7 +34,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; | @@ -34,7 +34,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; | ||
34 | import org.thingsboard.server.common.msg.queue.TbCallback; | 34 | import org.thingsboard.server.common.msg.queue.TbCallback; |
35 | import org.thingsboard.server.queue.TbQueueConsumer; | 35 | import org.thingsboard.server.queue.TbQueueConsumer; |
36 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 36 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
37 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 37 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
38 | import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; | 38 | import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; |
39 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | 39 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; |
40 | import org.thingsboard.server.service.apiusage.TbApiUsageStateService; | 40 | import org.thingsboard.server.service.apiusage.TbApiUsageStateService; |
@@ -54,7 +54,7 @@ import org.thingsboard.server.dao.tenant.TenantService; | @@ -54,7 +54,7 @@ import org.thingsboard.server.dao.tenant.TenantService; | ||
54 | import org.thingsboard.server.dao.timeseries.TimeseriesService; | 54 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
55 | import org.thingsboard.common.util.JacksonUtil; | 55 | import org.thingsboard.common.util.JacksonUtil; |
56 | import org.thingsboard.server.gen.transport.TransportProtos; | 56 | import org.thingsboard.server.gen.transport.TransportProtos; |
57 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 57 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
58 | import org.thingsboard.server.queue.discovery.PartitionService; | 58 | import org.thingsboard.server.queue.discovery.PartitionService; |
59 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | 59 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; |
60 | import org.thingsboard.server.queue.util.TbCoreComponent; | 60 | import org.thingsboard.server.queue.util.TbCoreComponent; |
@@ -18,7 +18,7 @@ package org.thingsboard.server.service.state; | @@ -18,7 +18,7 @@ package org.thingsboard.server.service.state; | ||
18 | import org.springframework.context.ApplicationListener; | 18 | import org.springframework.context.ApplicationListener; |
19 | import org.thingsboard.server.common.data.Device; | 19 | import org.thingsboard.server.common.data.Device; |
20 | import org.thingsboard.server.common.data.id.DeviceId; | 20 | import org.thingsboard.server.common.data.id.DeviceId; |
21 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 21 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
22 | import org.thingsboard.server.gen.transport.TransportProtos; | 22 | import org.thingsboard.server.gen.transport.TransportProtos; |
23 | import org.thingsboard.server.common.msg.queue.TbCallback; | 23 | import org.thingsboard.server.common.msg.queue.TbCallback; |
24 | 24 |
@@ -46,7 +46,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionUpdate | @@ -46,7 +46,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionUpdate | ||
46 | import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionUpdateValueListProto; | 46 | import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionUpdateValueListProto; |
47 | import org.thingsboard.server.queue.TbQueueProducer; | 47 | import org.thingsboard.server.queue.TbQueueProducer; |
48 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 48 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
49 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 49 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
50 | import org.thingsboard.server.queue.discovery.PartitionService; | 50 | import org.thingsboard.server.queue.discovery.PartitionService; |
51 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | 51 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; |
52 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; | 52 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; |
@@ -20,10 +20,9 @@ import org.springframework.beans.factory.annotation.Autowired; | @@ -20,10 +20,9 @@ import org.springframework.beans.factory.annotation.Autowired; | ||
20 | import org.springframework.context.annotation.Lazy; | 20 | import org.springframework.context.annotation.Lazy; |
21 | import org.springframework.context.event.EventListener; | 21 | import org.springframework.context.event.EventListener; |
22 | import org.springframework.stereotype.Service; | 22 | import org.springframework.stereotype.Service; |
23 | -import org.thingsboard.common.util.ThingsBoardThreadFactory; | ||
24 | import org.thingsboard.server.gen.transport.TransportProtos; | 23 | import org.thingsboard.server.gen.transport.TransportProtos; |
25 | -import org.thingsboard.server.queue.discovery.ClusterTopologyChangeEvent; | ||
26 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 24 | +import org.thingsboard.server.queue.discovery.event.ClusterTopologyChangeEvent; |
25 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; | ||
27 | import org.thingsboard.server.queue.discovery.PartitionService; | 26 | import org.thingsboard.server.queue.discovery.PartitionService; |
28 | import org.thingsboard.server.common.msg.queue.ServiceType; | 27 | import org.thingsboard.server.common.msg.queue.ServiceType; |
29 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 28 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
@@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
22 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; | 22 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
23 | import org.thingsboard.server.common.data.kv.TsKvEntry; | 23 | import org.thingsboard.server.common.data.kv.TsKvEntry; |
24 | import org.thingsboard.server.common.msg.queue.TbCallback; | 24 | import org.thingsboard.server.common.msg.queue.TbCallback; |
25 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 25 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
26 | 26 | ||
27 | import java.util.List; | 27 | import java.util.List; |
28 | 28 |
@@ -15,8 +15,8 @@ | @@ -15,8 +15,8 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.service.subscription; | 16 | package org.thingsboard.server.service.subscription; |
17 | 17 | ||
18 | -import org.thingsboard.server.queue.discovery.ClusterTopologyChangeEvent; | ||
19 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 18 | +import org.thingsboard.server.queue.discovery.event.ClusterTopologyChangeEvent; |
19 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; | ||
20 | import org.thingsboard.server.common.msg.queue.TbCallback; | 20 | import org.thingsboard.server.common.msg.queue.TbCallback; |
21 | import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; | 21 | import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; |
22 | import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; | 22 | import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; |
@@ -22,35 +22,18 @@ import lombok.extern.slf4j.Slf4j; | @@ -22,35 +22,18 @@ import lombok.extern.slf4j.Slf4j; | ||
22 | import org.springframework.beans.factory.annotation.Autowired; | 22 | import org.springframework.beans.factory.annotation.Autowired; |
23 | import org.springframework.context.ApplicationListener; | 23 | import org.springframework.context.ApplicationListener; |
24 | import org.springframework.context.event.EventListener; | 24 | import org.springframework.context.event.EventListener; |
25 | -import org.springframework.stereotype.Service; | ||
26 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 25 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
27 | -import org.thingsboard.server.common.data.id.EntityId; | ||
28 | -import org.thingsboard.server.common.data.id.TenantId; | ||
29 | -import org.thingsboard.server.common.data.kv.AttributeKvEntry; | ||
30 | -import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; | ||
31 | -import org.thingsboard.server.common.data.kv.BooleanDataEntry; | ||
32 | -import org.thingsboard.server.common.data.kv.DoubleDataEntry; | ||
33 | -import org.thingsboard.server.common.data.kv.LongDataEntry; | ||
34 | -import org.thingsboard.server.common.data.kv.StringDataEntry; | ||
35 | -import org.thingsboard.server.common.data.kv.TsKvEntry; | ||
36 | import org.thingsboard.server.common.msg.queue.ServiceType; | 26 | import org.thingsboard.server.common.msg.queue.ServiceType; |
37 | -import org.thingsboard.server.common.msg.queue.TbCallback; | ||
38 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 27 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
39 | -import org.thingsboard.server.dao.attributes.AttributesService; | ||
40 | -import org.thingsboard.server.dao.timeseries.TimeseriesService; | ||
41 | -import org.thingsboard.server.gen.transport.TransportProtos; | ||
42 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 28 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
43 | import org.thingsboard.server.queue.discovery.PartitionService; | 29 | import org.thingsboard.server.queue.discovery.PartitionService; |
44 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | 30 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; |
45 | import org.thingsboard.server.service.queue.TbClusterService; | 31 | import org.thingsboard.server.service.queue.TbClusterService; |
46 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; | 32 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; |
47 | -import org.thingsboard.server.service.subscription.TbSubscriptionUtils; | ||
48 | 33 | ||
49 | import javax.annotation.Nullable; | 34 | import javax.annotation.Nullable; |
50 | import javax.annotation.PostConstruct; | 35 | import javax.annotation.PostConstruct; |
51 | import javax.annotation.PreDestroy; | 36 | import javax.annotation.PreDestroy; |
52 | -import java.util.Collections; | ||
53 | -import java.util.List; | ||
54 | import java.util.Optional; | 37 | import java.util.Optional; |
55 | import java.util.Set; | 38 | import java.util.Set; |
56 | import java.util.concurrent.ConcurrentHashMap; | 39 | import java.util.concurrent.ConcurrentHashMap; |
@@ -17,8 +17,7 @@ package org.thingsboard.server.service.telemetry; | @@ -17,8 +17,7 @@ package org.thingsboard.server.service.telemetry; | ||
17 | 17 | ||
18 | import org.springframework.context.ApplicationListener; | 18 | import org.springframework.context.ApplicationListener; |
19 | import org.thingsboard.rule.engine.api.RuleEngineAlarmService; | 19 | import org.thingsboard.rule.engine.api.RuleEngineAlarmService; |
20 | -import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; | ||
21 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 20 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
22 | 21 | ||
23 | /** | 22 | /** |
24 | * Created by ashvayka on 27.03.18. | 23 | * Created by ashvayka on 27.03.18. |
@@ -22,9 +22,7 @@ import com.google.common.util.concurrent.ListenableFuture; | @@ -22,9 +22,7 @@ import com.google.common.util.concurrent.ListenableFuture; | ||
22 | import lombok.extern.slf4j.Slf4j; | 22 | import lombok.extern.slf4j.Slf4j; |
23 | import org.checkerframework.checker.nullness.qual.Nullable; | 23 | import org.checkerframework.checker.nullness.qual.Nullable; |
24 | import org.springframework.beans.factory.annotation.Autowired; | 24 | import org.springframework.beans.factory.annotation.Autowired; |
25 | -import org.springframework.context.event.EventListener; | ||
26 | import org.springframework.stereotype.Service; | 25 | import org.springframework.stereotype.Service; |
27 | -import org.thingsboard.common.util.ThingsBoardThreadFactory; | ||
28 | import org.thingsboard.server.common.data.alarm.Alarm; | 26 | import org.thingsboard.server.common.data.alarm.Alarm; |
29 | import org.thingsboard.server.common.data.alarm.AlarmInfo; | 27 | import org.thingsboard.server.common.data.alarm.AlarmInfo; |
30 | import org.thingsboard.server.common.data.alarm.AlarmQuery; | 28 | import org.thingsboard.server.common.data.alarm.AlarmQuery; |
@@ -35,43 +33,22 @@ import org.thingsboard.server.common.data.id.AlarmId; | @@ -35,43 +33,22 @@ import org.thingsboard.server.common.data.id.AlarmId; | ||
35 | import org.thingsboard.server.common.data.id.CustomerId; | 33 | import org.thingsboard.server.common.data.id.CustomerId; |
36 | import org.thingsboard.server.common.data.id.EntityId; | 34 | import org.thingsboard.server.common.data.id.EntityId; |
37 | import org.thingsboard.server.common.data.id.TenantId; | 35 | import org.thingsboard.server.common.data.id.TenantId; |
38 | -import org.thingsboard.server.common.data.kv.AttributeKvEntry; | ||
39 | -import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; | ||
40 | -import org.thingsboard.server.common.data.kv.BooleanDataEntry; | ||
41 | -import org.thingsboard.server.common.data.kv.DoubleDataEntry; | ||
42 | -import org.thingsboard.server.common.data.kv.LongDataEntry; | ||
43 | -import org.thingsboard.server.common.data.kv.StringDataEntry; | ||
44 | -import org.thingsboard.server.common.data.kv.TsKvEntry; | ||
45 | import org.thingsboard.server.common.data.page.PageData; | 36 | import org.thingsboard.server.common.data.page.PageData; |
46 | import org.thingsboard.server.common.data.query.AlarmData; | 37 | import org.thingsboard.server.common.data.query.AlarmData; |
47 | -import org.thingsboard.server.common.data.query.AlarmDataPageLink; | ||
48 | import org.thingsboard.server.common.data.query.AlarmDataQuery; | 38 | import org.thingsboard.server.common.data.query.AlarmDataQuery; |
49 | import org.thingsboard.server.common.msg.queue.ServiceType; | 39 | import org.thingsboard.server.common.msg.queue.ServiceType; |
50 | import org.thingsboard.server.common.msg.queue.TbCallback; | 40 | import org.thingsboard.server.common.msg.queue.TbCallback; |
51 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 41 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
52 | import org.thingsboard.server.dao.alarm.AlarmOperationResult; | 42 | import org.thingsboard.server.dao.alarm.AlarmOperationResult; |
53 | import org.thingsboard.server.dao.alarm.AlarmService; | 43 | import org.thingsboard.server.dao.alarm.AlarmService; |
54 | -import org.thingsboard.server.dao.attributes.AttributesService; | ||
55 | -import org.thingsboard.server.dao.timeseries.TimeseriesService; | ||
56 | import org.thingsboard.server.gen.transport.TransportProtos; | 44 | import org.thingsboard.server.gen.transport.TransportProtos; |
57 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | ||
58 | import org.thingsboard.server.queue.discovery.PartitionService; | 45 | import org.thingsboard.server.queue.discovery.PartitionService; |
59 | import org.thingsboard.server.service.queue.TbClusterService; | 46 | import org.thingsboard.server.service.queue.TbClusterService; |
60 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; | 47 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; |
61 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; | 48 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; |
62 | -import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; | ||
63 | 49 | ||
64 | -import javax.annotation.PostConstruct; | ||
65 | -import javax.annotation.PreDestroy; | ||
66 | import java.util.Collection; | 50 | import java.util.Collection; |
67 | -import java.util.Collections; | ||
68 | -import java.util.List; | ||
69 | import java.util.Optional; | 51 | import java.util.Optional; |
70 | -import java.util.Set; | ||
71 | -import java.util.concurrent.ConcurrentHashMap; | ||
72 | -import java.util.concurrent.ExecutorService; | ||
73 | -import java.util.concurrent.Executors; | ||
74 | -import java.util.function.Consumer; | ||
75 | 52 | ||
76 | /** | 53 | /** |
77 | * Created by ashvayka on 27.03.18. | 54 | * Created by ashvayka on 27.03.18. |
application/src/main/java/org/thingsboard/server/service/telemetry/TelemetrySubscriptionService.java
@@ -16,8 +16,7 @@ | @@ -16,8 +16,7 @@ | ||
16 | package org.thingsboard.server.service.telemetry; | 16 | package org.thingsboard.server.service.telemetry; |
17 | 17 | ||
18 | import org.springframework.context.ApplicationListener; | 18 | import org.springframework.context.ApplicationListener; |
19 | -import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; | ||
20 | -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 19 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
21 | 20 | ||
22 | /** | 21 | /** |
23 | * Created by ashvayka on 27.03.18. | 22 | * Created by ashvayka on 27.03.18. |
@@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.ApiUsageState; | @@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.ApiUsageState; | ||
30 | import org.thingsboard.server.common.data.DataConstants; | 30 | import org.thingsboard.server.common.data.DataConstants; |
31 | import org.thingsboard.server.common.data.Device; | 31 | import org.thingsboard.server.common.data.Device; |
32 | import org.thingsboard.server.common.data.DeviceProfile; | 32 | import org.thingsboard.server.common.data.DeviceProfile; |
33 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
33 | import org.thingsboard.server.common.data.EntityType; | 34 | import org.thingsboard.server.common.data.EntityType; |
34 | import org.thingsboard.server.common.data.TenantProfile; | 35 | import org.thingsboard.server.common.data.TenantProfile; |
35 | import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; | 36 | import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; |
@@ -61,11 +62,15 @@ import org.thingsboard.server.dao.resource.ResourceService; | @@ -61,11 +62,15 @@ import org.thingsboard.server.dao.resource.ResourceService; | ||
61 | import org.thingsboard.server.dao.tenant.TbTenantProfileCache; | 62 | import org.thingsboard.server.dao.tenant.TbTenantProfileCache; |
62 | import org.thingsboard.server.gen.transport.TransportProtos; | 63 | import org.thingsboard.server.gen.transport.TransportProtos; |
63 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; | 64 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; |
65 | +import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceCredentialsRequestMsg; | ||
66 | +import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceRequestMsg; | ||
64 | import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg; | 67 | import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg; |
65 | import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg; | 68 | import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg; |
66 | import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; | 69 | import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; |
67 | import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayResponseMsg; | 70 | import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayResponseMsg; |
68 | import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesRequestMsg; | 71 | import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesRequestMsg; |
72 | +import org.thingsboard.server.gen.transport.TransportProtos.GetSnmpDevicesRequestMsg; | ||
73 | +import org.thingsboard.server.gen.transport.TransportProtos.GetSnmpDevicesResponseMsg; | ||
69 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; | 74 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; |
70 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionResponseStatus; | 75 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionResponseStatus; |
71 | import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg; | 76 | import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg; |
@@ -84,6 +89,7 @@ import org.thingsboard.server.service.state.DeviceStateService; | @@ -84,6 +89,7 @@ import org.thingsboard.server.service.state.DeviceStateService; | ||
84 | 89 | ||
85 | import java.util.Collections; | 90 | import java.util.Collections; |
86 | import java.util.List; | 91 | import java.util.List; |
92 | +import java.util.Optional; | ||
87 | import java.util.UUID; | 93 | import java.util.UUID; |
88 | import java.util.concurrent.ConcurrentHashMap; | 94 | import java.util.concurrent.ConcurrentHashMap; |
89 | import java.util.concurrent.ConcurrentMap; | 95 | import java.util.concurrent.ConcurrentMap; |
@@ -139,40 +145,41 @@ public class DefaultTransportApiService implements TransportApiService { | @@ -139,40 +145,41 @@ public class DefaultTransportApiService implements TransportApiService { | ||
139 | @Override | 145 | @Override |
140 | public ListenableFuture<TbProtoQueueMsg<TransportApiResponseMsg>> handle(TbProtoQueueMsg<TransportApiRequestMsg> tbProtoQueueMsg) { | 146 | public ListenableFuture<TbProtoQueueMsg<TransportApiResponseMsg>> handle(TbProtoQueueMsg<TransportApiRequestMsg> tbProtoQueueMsg) { |
141 | TransportApiRequestMsg transportApiRequestMsg = tbProtoQueueMsg.getValue(); | 147 | TransportApiRequestMsg transportApiRequestMsg = tbProtoQueueMsg.getValue(); |
148 | + ListenableFuture<TransportApiResponseMsg> result = null; | ||
149 | + | ||
142 | if (transportApiRequestMsg.hasValidateTokenRequestMsg()) { | 150 | if (transportApiRequestMsg.hasValidateTokenRequestMsg()) { |
143 | ValidateDeviceTokenRequestMsg msg = transportApiRequestMsg.getValidateTokenRequestMsg(); | 151 | ValidateDeviceTokenRequestMsg msg = transportApiRequestMsg.getValidateTokenRequestMsg(); |
144 | - return Futures.transform(validateCredentials(msg.getToken(), DeviceCredentialsType.ACCESS_TOKEN), | ||
145 | - value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); | 152 | + result = validateCredentials(msg.getToken(), DeviceCredentialsType.ACCESS_TOKEN); |
146 | } else if (transportApiRequestMsg.hasValidateBasicMqttCredRequestMsg()) { | 153 | } else if (transportApiRequestMsg.hasValidateBasicMqttCredRequestMsg()) { |
147 | TransportProtos.ValidateBasicMqttCredRequestMsg msg = transportApiRequestMsg.getValidateBasicMqttCredRequestMsg(); | 154 | TransportProtos.ValidateBasicMqttCredRequestMsg msg = transportApiRequestMsg.getValidateBasicMqttCredRequestMsg(); |
148 | - return Futures.transform(validateCredentials(msg), | ||
149 | - value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); | 155 | + result = validateCredentials(msg); |
150 | } else if (transportApiRequestMsg.hasValidateX509CertRequestMsg()) { | 156 | } else if (transportApiRequestMsg.hasValidateX509CertRequestMsg()) { |
151 | ValidateDeviceX509CertRequestMsg msg = transportApiRequestMsg.getValidateX509CertRequestMsg(); | 157 | ValidateDeviceX509CertRequestMsg msg = transportApiRequestMsg.getValidateX509CertRequestMsg(); |
152 | - return Futures.transform(validateCredentials(msg.getHash(), DeviceCredentialsType.X509_CERTIFICATE), | ||
153 | - value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); | 158 | + result = validateCredentials(msg.getHash(), DeviceCredentialsType.X509_CERTIFICATE); |
154 | } else if (transportApiRequestMsg.hasGetOrCreateDeviceRequestMsg()) { | 159 | } else if (transportApiRequestMsg.hasGetOrCreateDeviceRequestMsg()) { |
155 | - return Futures.transform(handle(transportApiRequestMsg.getGetOrCreateDeviceRequestMsg()), | ||
156 | - value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); | 160 | + result = handle(transportApiRequestMsg.getGetOrCreateDeviceRequestMsg()); |
157 | } else if (transportApiRequestMsg.hasEntityProfileRequestMsg()) { | 161 | } else if (transportApiRequestMsg.hasEntityProfileRequestMsg()) { |
158 | - return Futures.transform(handle(transportApiRequestMsg.getEntityProfileRequestMsg()), | ||
159 | - value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); | 162 | + result = handle(transportApiRequestMsg.getEntityProfileRequestMsg()); |
160 | } else if (transportApiRequestMsg.hasLwM2MRequestMsg()) { | 163 | } else if (transportApiRequestMsg.hasLwM2MRequestMsg()) { |
161 | - return Futures.transform(handle(transportApiRequestMsg.getLwM2MRequestMsg()), | ||
162 | - value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); | 164 | + result = handle(transportApiRequestMsg.getLwM2MRequestMsg()); |
163 | } else if (transportApiRequestMsg.hasValidateDeviceLwM2MCredentialsRequestMsg()) { | 165 | } else if (transportApiRequestMsg.hasValidateDeviceLwM2MCredentialsRequestMsg()) { |
164 | ValidateDeviceLwM2MCredentialsRequestMsg msg = transportApiRequestMsg.getValidateDeviceLwM2MCredentialsRequestMsg(); | 166 | ValidateDeviceLwM2MCredentialsRequestMsg msg = transportApiRequestMsg.getValidateDeviceLwM2MCredentialsRequestMsg(); |
165 | - return Futures.transform(validateCredentials(msg.getCredentialsId(), DeviceCredentialsType.LWM2M_CREDENTIALS), | ||
166 | - value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); | 167 | + result = validateCredentials(msg.getCredentialsId(), DeviceCredentialsType.LWM2M_CREDENTIALS); |
167 | } else if (transportApiRequestMsg.hasProvisionDeviceRequestMsg()) { | 168 | } else if (transportApiRequestMsg.hasProvisionDeviceRequestMsg()) { |
168 | - return Futures.transform(handle(transportApiRequestMsg.getProvisionDeviceRequestMsg()), | ||
169 | - value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); | 169 | + result = handle(transportApiRequestMsg.getProvisionDeviceRequestMsg()); |
170 | } else if (transportApiRequestMsg.hasResourcesRequestMsg()) { | 170 | } else if (transportApiRequestMsg.hasResourcesRequestMsg()) { |
171 | - return Futures.transform(handle(transportApiRequestMsg.getResourcesRequestMsg()), | ||
172 | - value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); | 171 | + result = handle(transportApiRequestMsg.getResourcesRequestMsg()); |
172 | + } else if (transportApiRequestMsg.hasSnmpDevicesRequestMsg()) { | ||
173 | + result = handle(transportApiRequestMsg.getSnmpDevicesRequestMsg()); | ||
174 | + } else if (transportApiRequestMsg.hasDeviceRequestMsg()) { | ||
175 | + result = handle(transportApiRequestMsg.getDeviceRequestMsg()); | ||
176 | + } else if (transportApiRequestMsg.hasDeviceCredentialsRequestMsg()) { | ||
177 | + result = handle(transportApiRequestMsg.getDeviceCredentialsRequestMsg()); | ||
173 | } | 178 | } |
174 | - return Futures.transform(getEmptyTransportApiResponseFuture(), | ||
175 | - value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); | 179 | + |
180 | + return Futures.transform(Optional.ofNullable(result).orElseGet(this::getEmptyTransportApiResponseFuture), | ||
181 | + value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), | ||
182 | + MoreExecutors.directExecutor()); | ||
176 | } | 183 | } |
177 | 184 | ||
178 | private ListenableFuture<TransportApiResponseMsg> validateCredentials(String credentialsId, DeviceCredentialsType credentialsType) { | 185 | private ListenableFuture<TransportApiResponseMsg> validateCredentials(String credentialsId, DeviceCredentialsType credentialsType) { |
@@ -366,6 +373,39 @@ public class DefaultTransportApiService implements TransportApiService { | @@ -366,6 +373,39 @@ public class DefaultTransportApiService implements TransportApiService { | ||
366 | return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setEntityProfileResponseMsg(builder).build()); | 373 | return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setEntityProfileResponseMsg(builder).build()); |
367 | } | 374 | } |
368 | 375 | ||
376 | + private ListenableFuture<TransportApiResponseMsg> handle(GetDeviceRequestMsg requestMsg) { | ||
377 | + DeviceId deviceId = new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB())); | ||
378 | + Device device = deviceService.findDeviceById(TenantId.SYS_TENANT_ID, deviceId); | ||
379 | + | ||
380 | + TransportApiResponseMsg responseMsg; | ||
381 | + if (device != null) { | ||
382 | + UUID deviceProfileId = device.getDeviceProfileId().getId(); | ||
383 | + responseMsg = TransportApiResponseMsg.newBuilder() | ||
384 | + .setDeviceResponseMsg(TransportProtos.GetDeviceResponseMsg.newBuilder() | ||
385 | + .setDeviceProfileIdMSB(deviceProfileId.getMostSignificantBits()) | ||
386 | + .setDeviceProfileIdLSB(deviceProfileId.getLeastSignificantBits()) | ||
387 | + .setDeviceTransportConfiguration(ByteString.copyFrom( | ||
388 | + dataDecodingEncodingService.encode(device.getDeviceData().getTransportConfiguration()) | ||
389 | + ))) | ||
390 | + .build(); | ||
391 | + } else { | ||
392 | + responseMsg = TransportApiResponseMsg.getDefaultInstance(); | ||
393 | + } | ||
394 | + | ||
395 | + return Futures.immediateFuture(responseMsg); | ||
396 | + } | ||
397 | + | ||
398 | + private ListenableFuture<TransportApiResponseMsg> handle(GetDeviceCredentialsRequestMsg requestMsg) { | ||
399 | + DeviceId deviceId = new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB())); | ||
400 | + DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(TenantId.SYS_TENANT_ID, deviceId); | ||
401 | + | ||
402 | + return Futures.immediateFuture(TransportApiResponseMsg.newBuilder() | ||
403 | + .setDeviceCredentialsResponseMsg(TransportProtos.GetDeviceCredentialsResponseMsg.newBuilder() | ||
404 | + .setDeviceCredentialsData(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceCredentials)))) | ||
405 | + .build()); | ||
406 | + } | ||
407 | + | ||
408 | + | ||
369 | private ListenableFuture<TransportApiResponseMsg> handle(GetResourcesRequestMsg requestMsg) { | 409 | private ListenableFuture<TransportApiResponseMsg> handle(GetResourcesRequestMsg requestMsg) { |
370 | TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); | 410 | TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); |
371 | TransportProtos.GetResourcesResponseMsg.Builder builder = TransportProtos.GetResourcesResponseMsg.newBuilder(); | 411 | TransportProtos.GetResourcesResponseMsg.Builder builder = TransportProtos.GetResourcesResponseMsg.newBuilder(); |
@@ -400,6 +440,20 @@ public class DefaultTransportApiService implements TransportApiService { | @@ -400,6 +440,20 @@ public class DefaultTransportApiService implements TransportApiService { | ||
400 | .build(); | 440 | .build(); |
401 | } | 441 | } |
402 | 442 | ||
443 | + // TODO: request snmp devices with pagination | ||
444 | + private ListenableFuture<TransportApiResponseMsg> handle(GetSnmpDevicesRequestMsg requestMsg) { | ||
445 | + List<UUID> result = deviceService.findDevicesIdsByDeviceProfileTransportType(DeviceTransportType.SNMP); | ||
446 | + GetSnmpDevicesResponseMsg responseMsg = GetSnmpDevicesResponseMsg.newBuilder() | ||
447 | + .addAllIds(result.stream() | ||
448 | + .map(UUID::toString) | ||
449 | + .collect(Collectors.toList())) | ||
450 | + .build(); | ||
451 | + | ||
452 | + return Futures.immediateFuture(TransportApiResponseMsg.newBuilder() | ||
453 | + .setSnmpDevicesResponseMsg(responseMsg) | ||
454 | + .build()); | ||
455 | + } | ||
456 | + | ||
403 | private ListenableFuture<TransportApiResponseMsg> getDeviceInfo(DeviceId deviceId, DeviceCredentials credentials) { | 457 | private ListenableFuture<TransportApiResponseMsg> getDeviceInfo(DeviceId deviceId, DeviceCredentials credentials) { |
404 | return Futures.transform(deviceService.findDeviceByIdAsync(TenantId.SYS_TENANT_ID, deviceId), device -> { | 458 | return Futures.transform(deviceService.findDeviceByIdAsync(TenantId.SYS_TENANT_ID, deviceId), device -> { |
405 | if (device == null) { | 459 | if (device == null) { |
@@ -19,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture; | @@ -19,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture; | ||
19 | import org.thingsboard.server.common.data.Device; | 19 | import org.thingsboard.server.common.data.Device; |
20 | import org.thingsboard.server.common.data.DeviceInfo; | 20 | import org.thingsboard.server.common.data.DeviceInfo; |
21 | import org.thingsboard.server.common.data.DeviceProfile; | 21 | import org.thingsboard.server.common.data.DeviceProfile; |
22 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
22 | import org.thingsboard.server.common.data.EntitySubtype; | 23 | import org.thingsboard.server.common.data.EntitySubtype; |
23 | import org.thingsboard.server.common.data.device.DeviceSearchQuery; | 24 | import org.thingsboard.server.common.data.device.DeviceSearchQuery; |
24 | import org.thingsboard.server.common.data.id.CustomerId; | 25 | import org.thingsboard.server.common.data.id.CustomerId; |
@@ -31,6 +32,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials; | @@ -31,6 +32,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials; | ||
31 | import org.thingsboard.server.dao.device.provision.ProvisionRequest; | 32 | import org.thingsboard.server.dao.device.provision.ProvisionRequest; |
32 | 33 | ||
33 | import java.util.List; | 34 | import java.util.List; |
35 | +import java.util.UUID; | ||
34 | 36 | ||
35 | public interface DeviceService { | 37 | public interface DeviceService { |
36 | 38 | ||
@@ -90,4 +92,5 @@ public interface DeviceService { | @@ -90,4 +92,5 @@ public interface DeviceService { | ||
90 | 92 | ||
91 | Device saveDevice(ProvisionRequest provisionRequest, DeviceProfile profile); | 93 | Device saveDevice(ProvisionRequest provisionRequest, DeviceProfile profile); |
92 | 94 | ||
95 | + List<UUID> findDevicesIdsByDeviceProfileTransportType(DeviceTransportType transportType); | ||
93 | } | 96 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2021 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.common.data; | ||
17 | + | ||
18 | +public interface TbTransportService { | ||
19 | + String getName(); | ||
20 | +} |
@@ -21,6 +21,8 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; | @@ -21,6 +21,8 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; | ||
21 | import com.fasterxml.jackson.annotation.JsonTypeInfo; | 21 | import com.fasterxml.jackson.annotation.JsonTypeInfo; |
22 | import org.thingsboard.server.common.data.DeviceTransportType; | 22 | import org.thingsboard.server.common.data.DeviceTransportType; |
23 | 23 | ||
24 | +import java.io.Serializable; | ||
25 | + | ||
24 | @JsonIgnoreProperties(ignoreUnknown = true) | 26 | @JsonIgnoreProperties(ignoreUnknown = true) |
25 | @JsonTypeInfo( | 27 | @JsonTypeInfo( |
26 | use = JsonTypeInfo.Id.NAME, | 28 | use = JsonTypeInfo.Id.NAME, |
@@ -31,7 +33,7 @@ import org.thingsboard.server.common.data.DeviceTransportType; | @@ -31,7 +33,7 @@ import org.thingsboard.server.common.data.DeviceTransportType; | ||
31 | @JsonSubTypes.Type(value = MqttDeviceTransportConfiguration.class, name = "MQTT"), | 33 | @JsonSubTypes.Type(value = MqttDeviceTransportConfiguration.class, name = "MQTT"), |
32 | @JsonSubTypes.Type(value = Lwm2mDeviceTransportConfiguration.class, name = "LWM2M"), | 34 | @JsonSubTypes.Type(value = Lwm2mDeviceTransportConfiguration.class, name = "LWM2M"), |
33 | @JsonSubTypes.Type(value = SnmpDeviceTransportConfiguration.class, name = "SNMP")}) | 35 | @JsonSubTypes.Type(value = SnmpDeviceTransportConfiguration.class, name = "SNMP")}) |
34 | -public interface DeviceTransportConfiguration { | 36 | +public interface DeviceTransportConfiguration extends Serializable { |
35 | 37 | ||
36 | @JsonIgnore | 38 | @JsonIgnore |
37 | DeviceTransportType getType(); | 39 | DeviceTransportType getType(); |
@@ -19,14 +19,14 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | @@ -19,14 +19,14 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | ||
19 | import lombok.Data; | 19 | import lombok.Data; |
20 | import org.thingsboard.server.common.data.DeviceTransportType; | 20 | import org.thingsboard.server.common.data.DeviceTransportType; |
21 | 21 | ||
22 | +import java.util.Collections; | ||
22 | import java.util.List; | 23 | import java.util.List; |
23 | import java.util.stream.Collectors; | 24 | import java.util.stream.Collectors; |
24 | import java.util.stream.Stream; | 25 | import java.util.stream.Stream; |
25 | 26 | ||
26 | @Data | 27 | @Data |
27 | public class SnmpProfileTransportConfiguration implements DeviceProfileTransportConfiguration { | 28 | public class SnmpProfileTransportConfiguration implements DeviceProfileTransportConfiguration { |
28 | - | ||
29 | - private int poolPeriodMs; | 29 | + private int pollPeriodMs; |
30 | private int timeoutMs; | 30 | private int timeoutMs; |
31 | private int retries; | 31 | private int retries; |
32 | private List<SnmpDeviceProfileKvMapping> attributes; | 32 | private List<SnmpDeviceProfileKvMapping> attributes; |
@@ -39,6 +39,10 @@ public class SnmpProfileTransportConfiguration implements DeviceProfileTransport | @@ -39,6 +39,10 @@ public class SnmpProfileTransportConfiguration implements DeviceProfileTransport | ||
39 | 39 | ||
40 | @JsonIgnore | 40 | @JsonIgnore |
41 | public List<SnmpDeviceProfileKvMapping> getKvMappings() { | 41 | public List<SnmpDeviceProfileKvMapping> getKvMappings() { |
42 | - return Stream.concat(attributes.stream(), telemetry.stream()).collect(Collectors.toList()); | 42 | + if (attributes != null && telemetry != null) { |
43 | + return Stream.concat(attributes.stream(), telemetry.stream()).collect(Collectors.toList()); | ||
44 | + } else { | ||
45 | + return Collections.emptyList(); | ||
46 | + } | ||
43 | } | 47 | } |
44 | } | 48 | } |
@@ -19,8 +19,12 @@ import lombok.Getter; | @@ -19,8 +19,12 @@ import lombok.Getter; | ||
19 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
20 | import org.springframework.beans.factory.annotation.Autowired; | 20 | import org.springframework.beans.factory.annotation.Autowired; |
21 | import org.springframework.beans.factory.annotation.Value; | 21 | import org.springframework.beans.factory.annotation.Value; |
22 | +import org.springframework.context.ApplicationContext; | ||
23 | +import org.springframework.context.event.ContextRefreshedEvent; | ||
24 | +import org.springframework.context.event.EventListener; | ||
22 | import org.springframework.stereotype.Component; | 25 | import org.springframework.stereotype.Component; |
23 | import org.springframework.util.StringUtils; | 26 | import org.springframework.util.StringUtils; |
27 | +import org.thingsboard.server.common.data.TbTransportService; | ||
24 | import org.thingsboard.server.common.data.id.TenantId; | 28 | import org.thingsboard.server.common.data.id.TenantId; |
25 | import org.thingsboard.server.common.msg.queue.ServiceType; | 29 | import org.thingsboard.server.common.msg.queue.ServiceType; |
26 | import org.thingsboard.server.gen.transport.TransportProtos; | 30 | import org.thingsboard.server.gen.transport.TransportProtos; |
@@ -32,6 +36,7 @@ import javax.annotation.PostConstruct; | @@ -32,6 +36,7 @@ import javax.annotation.PostConstruct; | ||
32 | import java.net.InetAddress; | 36 | import java.net.InetAddress; |
33 | import java.net.UnknownHostException; | 37 | import java.net.UnknownHostException; |
34 | import java.util.Arrays; | 38 | import java.util.Arrays; |
39 | +import java.util.Collection; | ||
35 | import java.util.Collections; | 40 | import java.util.Collections; |
36 | import java.util.List; | 41 | import java.util.List; |
37 | import java.util.Optional; | 42 | import java.util.Optional; |
@@ -56,6 +61,8 @@ public class DefaultTbServiceInfoProvider implements TbServiceInfoProvider { | @@ -56,6 +61,8 @@ public class DefaultTbServiceInfoProvider implements TbServiceInfoProvider { | ||
56 | 61 | ||
57 | @Autowired(required = false) | 62 | @Autowired(required = false) |
58 | private TbQueueRuleEngineSettings ruleEngineSettings; | 63 | private TbQueueRuleEngineSettings ruleEngineSettings; |
64 | + @Autowired | ||
65 | + private ApplicationContext applicationContext; | ||
59 | 66 | ||
60 | private List<ServiceType> serviceTypes; | 67 | private List<ServiceType> serviceTypes; |
61 | private ServiceInfo serviceInfo; | 68 | private ServiceInfo serviceInfo; |
@@ -102,6 +109,19 @@ public class DefaultTbServiceInfoProvider implements TbServiceInfoProvider { | @@ -102,6 +109,19 @@ public class DefaultTbServiceInfoProvider implements TbServiceInfoProvider { | ||
102 | serviceInfo = builder.build(); | 109 | serviceInfo = builder.build(); |
103 | } | 110 | } |
104 | 111 | ||
112 | + @EventListener(ContextRefreshedEvent.class) | ||
113 | + public void setTransports() { | ||
114 | + serviceInfo = ServiceInfo.newBuilder(serviceInfo) | ||
115 | + .addAllTransports(getTransportServices().stream() | ||
116 | + .map(TbTransportService::getName) | ||
117 | + .collect(Collectors.toSet())) | ||
118 | + .build(); | ||
119 | + } | ||
120 | + | ||
121 | + private Collection<TbTransportService> getTransportServices() { | ||
122 | + return applicationContext.getBeansOfType(TbTransportService.class).values(); | ||
123 | + } | ||
124 | + | ||
105 | @Override | 125 | @Override |
106 | public ServiceInfo getServiceInfo() { | 126 | public ServiceInfo getServiceInfo() { |
107 | return serviceInfo; | 127 | return serviceInfo; |
@@ -15,26 +15,27 @@ | @@ -15,26 +15,27 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.queue.discovery; | 16 | package org.thingsboard.server.queue.discovery; |
17 | 17 | ||
18 | -import com.google.common.hash.HashCode; | ||
19 | import com.google.common.hash.HashFunction; | 18 | import com.google.common.hash.HashFunction; |
19 | +import com.google.common.hash.Hasher; | ||
20 | import com.google.common.hash.Hashing; | 20 | import com.google.common.hash.Hashing; |
21 | -import lombok.Getter; | ||
22 | import lombok.extern.slf4j.Slf4j; | 21 | import lombok.extern.slf4j.Slf4j; |
23 | import org.springframework.beans.factory.annotation.Value; | 22 | import org.springframework.beans.factory.annotation.Value; |
24 | import org.springframework.context.ApplicationEventPublisher; | 23 | import org.springframework.context.ApplicationEventPublisher; |
25 | import org.springframework.stereotype.Service; | 24 | import org.springframework.stereotype.Service; |
26 | import org.thingsboard.server.common.data.id.EntityId; | 25 | import org.thingsboard.server.common.data.id.EntityId; |
27 | import org.thingsboard.server.common.data.id.TenantId; | 26 | import org.thingsboard.server.common.data.id.TenantId; |
28 | -import org.thingsboard.server.common.msg.queue.ServiceQueueKey; | ||
29 | import org.thingsboard.server.common.msg.queue.ServiceQueue; | 27 | import org.thingsboard.server.common.msg.queue.ServiceQueue; |
28 | +import org.thingsboard.server.common.msg.queue.ServiceQueueKey; | ||
30 | import org.thingsboard.server.common.msg.queue.ServiceType; | 29 | import org.thingsboard.server.common.msg.queue.ServiceType; |
31 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 30 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
32 | import org.thingsboard.server.gen.transport.TransportProtos; | 31 | import org.thingsboard.server.gen.transport.TransportProtos; |
33 | import org.thingsboard.server.gen.transport.TransportProtos.ServiceInfo; | 32 | import org.thingsboard.server.gen.transport.TransportProtos.ServiceInfo; |
33 | +import org.thingsboard.server.queue.discovery.event.ClusterTopologyChangeEvent; | ||
34 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; | ||
35 | +import org.thingsboard.server.queue.discovery.event.ServiceListChangedEvent; | ||
34 | import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; | 36 | import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; |
35 | 37 | ||
36 | import javax.annotation.PostConstruct; | 38 | import javax.annotation.PostConstruct; |
37 | -import java.nio.charset.StandardCharsets; | ||
38 | import java.util.ArrayList; | 39 | import java.util.ArrayList; |
39 | import java.util.Collections; | 40 | import java.util.Collections; |
40 | import java.util.Comparator; | 41 | import java.util.Comparator; |
@@ -46,7 +47,6 @@ import java.util.Set; | @@ -46,7 +47,6 @@ import java.util.Set; | ||
46 | import java.util.UUID; | 47 | import java.util.UUID; |
47 | import java.util.concurrent.ConcurrentHashMap; | 48 | import java.util.concurrent.ConcurrentHashMap; |
48 | import java.util.concurrent.ConcurrentMap; | 49 | import java.util.concurrent.ConcurrentMap; |
49 | -import java.util.concurrent.ConcurrentNavigableMap; | ||
50 | import java.util.stream.Collectors; | 50 | import java.util.stream.Collectors; |
51 | 51 | ||
52 | @Service | 52 | @Service |
@@ -186,6 +186,8 @@ public class HashPartitionService implements PartitionService { | @@ -186,6 +186,8 @@ public class HashPartitionService implements PartitionService { | ||
186 | applicationEventPublisher.publishEvent(new ClusterTopologyChangeEvent(this, changes)); | 186 | applicationEventPublisher.publishEvent(new ClusterTopologyChangeEvent(this, changes)); |
187 | } | 187 | } |
188 | } | 188 | } |
189 | + | ||
190 | + applicationEventPublisher.publishEvent(new ServiceListChangedEvent(otherServices, currentService)); | ||
189 | } | 191 | } |
190 | 192 | ||
191 | @Override | 193 | @Override |
@@ -219,6 +221,14 @@ public class HashPartitionService implements PartitionService { | @@ -219,6 +221,14 @@ public class HashPartitionService implements PartitionService { | ||
219 | } | 221 | } |
220 | } | 222 | } |
221 | 223 | ||
224 | + @Override | ||
225 | + public int resolvePartitionIndex(UUID entityId, int partitions) { | ||
226 | + int hash = hashFunction.newHasher() | ||
227 | + .putLong(entityId.getMostSignificantBits()) | ||
228 | + .putLong(entityId.getLeastSignificantBits()).hash().asInt(); | ||
229 | + return Math.abs(hash % partitions); | ||
230 | + } | ||
231 | + | ||
222 | private Map<ServiceQueueKey, List<ServiceInfo>> getServiceKeyListMap(List<ServiceInfo> services) { | 232 | private Map<ServiceQueueKey, List<ServiceInfo>> getServiceKeyListMap(List<ServiceInfo> services) { |
223 | final Map<ServiceQueueKey, List<ServiceInfo>> currentMap = new HashMap<>(); | 233 | final Map<ServiceQueueKey, List<ServiceInfo>> currentMap = new HashMap<>(); |
224 | services.forEach(serviceInfo -> { | 234 | services.forEach(serviceInfo -> { |
@@ -20,9 +20,11 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -20,9 +20,11 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
20 | import org.thingsboard.server.common.msg.queue.ServiceType; | 20 | import org.thingsboard.server.common.msg.queue.ServiceType; |
21 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 21 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
22 | import org.thingsboard.server.gen.transport.TransportProtos; | 22 | import org.thingsboard.server.gen.transport.TransportProtos; |
23 | +import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; | ||
23 | 24 | ||
24 | import java.util.List; | 25 | import java.util.List; |
25 | import java.util.Set; | 26 | import java.util.Set; |
27 | +import java.util.UUID; | ||
26 | 28 | ||
27 | /** | 29 | /** |
28 | * Once application is ready or cluster topology changes, this Service will produce {@link PartitionChangeEvent} | 30 | * Once application is ready or cluster topology changes, this Service will produce {@link PartitionChangeEvent} |
@@ -55,4 +57,6 @@ public interface PartitionService { | @@ -55,4 +57,6 @@ public interface PartitionService { | ||
55 | * @return | 57 | * @return |
56 | */ | 58 | */ |
57 | TopicPartitionInfo getNotificationsTopic(ServiceType serviceType, String serviceId); | 59 | TopicPartitionInfo getNotificationsTopic(ServiceType serviceType, String serviceId); |
60 | + | ||
61 | + int resolvePartitionIndex(UUID entityId, int partitions); | ||
58 | } | 62 | } |
@@ -17,6 +17,7 @@ package org.thingsboard.server.queue.discovery; | @@ -17,6 +17,7 @@ package org.thingsboard.server.queue.discovery; | ||
17 | 17 | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | import org.springframework.context.ApplicationListener; | 19 | import org.springframework.context.ApplicationListener; |
20 | +import org.thingsboard.server.queue.discovery.event.TbApplicationEvent; | ||
20 | 21 | ||
21 | import java.util.concurrent.locks.Lock; | 22 | import java.util.concurrent.locks.Lock; |
22 | import java.util.concurrent.locks.ReentrantLock; | 23 | import java.util.concurrent.locks.ReentrantLock; |
@@ -33,12 +33,14 @@ import org.apache.zookeeper.KeeperException; | @@ -33,12 +33,14 @@ import org.apache.zookeeper.KeeperException; | ||
33 | import org.springframework.beans.factory.annotation.Value; | 33 | import org.springframework.beans.factory.annotation.Value; |
34 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | 34 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
35 | import org.springframework.boot.context.event.ApplicationReadyEvent; | 35 | import org.springframework.boot.context.event.ApplicationReadyEvent; |
36 | +import org.springframework.context.ApplicationEventPublisher; | ||
36 | import org.springframework.context.event.EventListener; | 37 | import org.springframework.context.event.EventListener; |
37 | import org.springframework.core.annotation.Order; | 38 | import org.springframework.core.annotation.Order; |
38 | import org.springframework.stereotype.Service; | 39 | import org.springframework.stereotype.Service; |
39 | import org.springframework.util.Assert; | 40 | import org.springframework.util.Assert; |
40 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 41 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
41 | import org.thingsboard.server.gen.transport.TransportProtos; | 42 | import org.thingsboard.server.gen.transport.TransportProtos; |
43 | +import org.thingsboard.server.queue.discovery.event.ServiceListChangedEvent; | ||
42 | 44 | ||
43 | import javax.annotation.PostConstruct; | 45 | import javax.annotation.PostConstruct; |
44 | import javax.annotation.PreDestroy; | 46 | import javax.annotation.PreDestroy; |
@@ -77,7 +79,8 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | @@ -77,7 +79,8 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | ||
77 | 79 | ||
78 | private volatile boolean stopped = true; | 80 | private volatile boolean stopped = true; |
79 | 81 | ||
80 | - public ZkDiscoveryService(TbServiceInfoProvider serviceInfoProvider, PartitionService partitionService) { | 82 | + public ZkDiscoveryService(TbServiceInfoProvider serviceInfoProvider, |
83 | + PartitionService partitionService) { | ||
81 | this.serviceInfoProvider = serviceInfoProvider; | 84 | this.serviceInfoProvider = serviceInfoProvider; |
82 | this.partitionService = partitionService; | 85 | this.partitionService = partitionService; |
83 | } | 86 | } |
@@ -126,7 +129,8 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | @@ -126,7 +129,8 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | ||
126 | return; | 129 | return; |
127 | } | 130 | } |
128 | publishCurrentServer(); | 131 | publishCurrentServer(); |
129 | - partitionService.recalculatePartitions(serviceInfoProvider.getServiceInfo(), getOtherServers()); | 132 | + TransportProtos.ServiceInfo currentService = serviceInfoProvider.getServiceInfo(); |
133 | + partitionService.recalculatePartitions(currentService, getOtherServers()); | ||
130 | } | 134 | } |
131 | 135 | ||
132 | public synchronized void publishCurrentServer() { | 136 | public synchronized void publishCurrentServer() { |
@@ -281,11 +285,11 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | @@ -281,11 +285,11 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi | ||
281 | case CHILD_ADDED: | 285 | case CHILD_ADDED: |
282 | case CHILD_UPDATED: | 286 | case CHILD_UPDATED: |
283 | case CHILD_REMOVED: | 287 | case CHILD_REMOVED: |
284 | - partitionService.recalculatePartitions(serviceInfoProvider.getServiceInfo(), getOtherServers()); | 288 | + TransportProtos.ServiceInfo currentService = serviceInfoProvider.getServiceInfo(); |
289 | + partitionService.recalculatePartitions(currentService, getOtherServers()); | ||
285 | break; | 290 | break; |
286 | default: | 291 | default: |
287 | break; | 292 | break; |
288 | } | 293 | } |
289 | } | 294 | } |
290 | - | ||
291 | } | 295 | } |
common/queue/src/main/java/org/thingsboard/server/queue/discovery/event/ClusterTopologyChangeEvent.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/discovery/ClusterTopologyChangeEvent.java
@@ -13,10 +13,9 @@ | @@ -13,10 +13,9 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.queue.discovery; | 16 | +package org.thingsboard.server.queue.discovery.event; |
17 | 17 | ||
18 | import lombok.Getter; | 18 | import lombok.Getter; |
19 | -import org.springframework.context.ApplicationEvent; | ||
20 | import org.thingsboard.server.common.msg.queue.ServiceQueueKey; | 19 | import org.thingsboard.server.common.msg.queue.ServiceQueueKey; |
21 | 20 | ||
22 | import java.util.Set; | 21 | import java.util.Set; |
common/queue/src/main/java/org/thingsboard/server/queue/discovery/event/PartitionChangeEvent.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/discovery/PartitionChangeEvent.java
@@ -13,10 +13,9 @@ | @@ -13,10 +13,9 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.queue.discovery; | 16 | +package org.thingsboard.server.queue.discovery.event; |
17 | 17 | ||
18 | import lombok.Getter; | 18 | import lombok.Getter; |
19 | -import org.springframework.context.ApplicationEvent; | ||
20 | import org.thingsboard.server.common.msg.queue.ServiceQueueKey; | 19 | import org.thingsboard.server.common.msg.queue.ServiceQueueKey; |
21 | import org.thingsboard.server.common.msg.queue.ServiceType; | 20 | import org.thingsboard.server.common.msg.queue.ServiceType; |
22 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 21 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
common/queue/src/main/java/org/thingsboard/server/queue/discovery/event/ServiceListChangedEvent.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2021 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.discovery.event; | ||
17 | + | ||
18 | +import lombok.Getter; | ||
19 | +import lombok.ToString; | ||
20 | +import org.thingsboard.server.gen.transport.TransportProtos.ServiceInfo; | ||
21 | + | ||
22 | +import java.util.List; | ||
23 | + | ||
24 | +@Getter | ||
25 | +@ToString | ||
26 | +public class ServiceListChangedEvent extends TbApplicationEvent { | ||
27 | + private final List<ServiceInfo> otherServices; | ||
28 | + private final ServiceInfo currentService; | ||
29 | + | ||
30 | + public ServiceListChangedEvent(List<ServiceInfo> otherServices, ServiceInfo currentService) { | ||
31 | + super(otherServices); | ||
32 | + this.otherServices = otherServices; | ||
33 | + this.currentService = currentService; | ||
34 | + } | ||
35 | +} |
common/queue/src/main/java/org/thingsboard/server/queue/discovery/event/TbApplicationEvent.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/discovery/TbApplicationEvent.java
@@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.queue.discovery; | 16 | +package org.thingsboard.server.queue.discovery.event; |
17 | 17 | ||
18 | import lombok.Getter; | 18 | import lombok.Getter; |
19 | import org.springframework.context.ApplicationEvent; | 19 | import org.springframework.context.ApplicationEvent; |
common/queue/src/main/java/org/thingsboard/server/queue/util/TbSnmpTransportComponent.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2021 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.util; | ||
17 | + | ||
18 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
19 | + | ||
20 | +import java.lang.annotation.ElementType; | ||
21 | +import java.lang.annotation.Retention; | ||
22 | +import java.lang.annotation.RetentionPolicy; | ||
23 | +import java.lang.annotation.Target; | ||
24 | + | ||
25 | +@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.snmp.enabled}'=='true')") | ||
26 | +@Retention(RetentionPolicy.RUNTIME) | ||
27 | +@Target({ElementType.TYPE, ElementType.METHOD}) | ||
28 | +public @interface TbSnmpTransportComponent { | ||
29 | +} |
@@ -34,6 +34,7 @@ message ServiceInfo { | @@ -34,6 +34,7 @@ message ServiceInfo { | ||
34 | int64 tenantIdMSB = 3; | 34 | int64 tenantIdMSB = 3; |
35 | int64 tenantIdLSB = 4; | 35 | int64 tenantIdLSB = 4; |
36 | repeated QueueInfo ruleEngineQueues = 5; | 36 | repeated QueueInfo ruleEngineQueues = 5; |
37 | + repeated string transports = 6; | ||
37 | } | 38 | } |
38 | 39 | ||
39 | /** | 40 | /** |
@@ -250,6 +251,34 @@ message GetEntityProfileResponseMsg { | @@ -250,6 +251,34 @@ message GetEntityProfileResponseMsg { | ||
250 | bytes apiState = 3; | 251 | bytes apiState = 3; |
251 | } | 252 | } |
252 | 253 | ||
254 | +message GetDeviceRequestMsg { | ||
255 | + int64 deviceIdMSB = 1; | ||
256 | + int64 deviceIdLSB = 2; | ||
257 | +} | ||
258 | + | ||
259 | +message GetDeviceResponseMsg { | ||
260 | + int64 deviceProfileIdMSB = 1; | ||
261 | + int64 deviceProfileIdLSB = 2; | ||
262 | + bytes deviceTransportConfiguration = 3; | ||
263 | +} | ||
264 | + | ||
265 | +message GetDeviceCredentialsRequestMsg { | ||
266 | + int64 deviceIdMSB = 1; | ||
267 | + int64 deviceIdLSB = 2; | ||
268 | +} | ||
269 | + | ||
270 | +message GetDeviceCredentialsResponseMsg { | ||
271 | + bytes deviceCredentialsData = 1; | ||
272 | +} | ||
273 | + | ||
274 | +message GetSnmpDevicesRequestMsg { | ||
275 | + | ||
276 | +} | ||
277 | + | ||
278 | +message GetSnmpDevicesResponseMsg { | ||
279 | + repeated string ids = 1; | ||
280 | +} | ||
281 | + | ||
253 | message EntityUpdateMsg { | 282 | message EntityUpdateMsg { |
254 | string entityType = 1; | 283 | string entityType = 1; |
255 | bytes data = 2; | 284 | bytes data = 2; |
@@ -559,6 +588,9 @@ message TransportApiRequestMsg { | @@ -559,6 +588,9 @@ message TransportApiRequestMsg { | ||
559 | ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7; | 588 | ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7; |
560 | ValidateDeviceLwM2MCredentialsRequestMsg validateDeviceLwM2MCredentialsRequestMsg = 8; | 589 | ValidateDeviceLwM2MCredentialsRequestMsg validateDeviceLwM2MCredentialsRequestMsg = 8; |
561 | GetResourcesRequestMsg resourcesRequestMsg = 9; | 590 | GetResourcesRequestMsg resourcesRequestMsg = 9; |
591 | + GetSnmpDevicesRequestMsg snmpDevicesRequestMsg = 10; | ||
592 | + GetDeviceRequestMsg deviceRequestMsg = 11; | ||
593 | + GetDeviceCredentialsRequestMsg deviceCredentialsRequestMsg = 12; | ||
562 | } | 594 | } |
563 | 595 | ||
564 | /* Response from ThingsBoard Core Service to Transport Service */ | 596 | /* Response from ThingsBoard Core Service to Transport Service */ |
@@ -567,8 +599,11 @@ message TransportApiResponseMsg { | @@ -567,8 +599,11 @@ message TransportApiResponseMsg { | ||
567 | GetOrCreateDeviceFromGatewayResponseMsg getOrCreateDeviceResponseMsg = 2; | 599 | GetOrCreateDeviceFromGatewayResponseMsg getOrCreateDeviceResponseMsg = 2; |
568 | GetEntityProfileResponseMsg entityProfileResponseMsg = 3; | 600 | GetEntityProfileResponseMsg entityProfileResponseMsg = 3; |
569 | ProvisionDeviceResponseMsg provisionDeviceResponseMsg = 4; | 601 | ProvisionDeviceResponseMsg provisionDeviceResponseMsg = 4; |
602 | + GetSnmpDevicesResponseMsg snmpDevicesResponseMsg = 5; | ||
570 | LwM2MResponseMsg lwM2MResponseMsg = 6; | 603 | LwM2MResponseMsg lwM2MResponseMsg = 6; |
571 | GetResourcesResponseMsg resourcesResponseMsg = 7; | 604 | GetResourcesResponseMsg resourcesResponseMsg = 7; |
605 | + GetDeviceResponseMsg deviceResponseMsg = 8; | ||
606 | + GetDeviceCredentialsResponseMsg deviceCredentialsResponseMsg = 9; | ||
572 | } | 607 | } |
573 | 608 | ||
574 | /* Messages that are handled by ThingsBoard Core Service */ | 609 | /* Messages that are handled by ThingsBoard Core Service */ |
@@ -18,12 +18,12 @@ package org.thingsboard.server.transport.coap; | @@ -18,12 +18,12 @@ package org.thingsboard.server.transport.coap; | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | import org.eclipse.californium.core.CoapResource; | 19 | import org.eclipse.californium.core.CoapResource; |
20 | import org.eclipse.californium.core.CoapServer; | 20 | import org.eclipse.californium.core.CoapServer; |
21 | - | ||
22 | import org.eclipse.californium.core.network.CoapEndpoint; | 21 | import org.eclipse.californium.core.network.CoapEndpoint; |
23 | import org.eclipse.californium.core.network.CoapEndpoint.Builder; | 22 | import org.eclipse.californium.core.network.CoapEndpoint.Builder; |
24 | import org.springframework.beans.factory.annotation.Autowired; | 23 | import org.springframework.beans.factory.annotation.Autowired; |
25 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | 24 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
26 | import org.springframework.stereotype.Service; | 25 | import org.springframework.stereotype.Service; |
26 | +import org.thingsboard.server.common.data.TbTransportService; | ||
27 | 27 | ||
28 | import javax.annotation.PostConstruct; | 28 | import javax.annotation.PostConstruct; |
29 | import javax.annotation.PreDestroy; | 29 | import javax.annotation.PreDestroy; |
@@ -34,7 +34,7 @@ import java.net.UnknownHostException; | @@ -34,7 +34,7 @@ import java.net.UnknownHostException; | ||
34 | @Service("CoapTransportService") | 34 | @Service("CoapTransportService") |
35 | @ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.coap.enabled}'=='true')") | 35 | @ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.coap.enabled}'=='true')") |
36 | @Slf4j | 36 | @Slf4j |
37 | -public class CoapTransportService { | 37 | +public class CoapTransportService implements TbTransportService { |
38 | 38 | ||
39 | private static final String V1 = "v1"; | 39 | private static final String V1 = "v1"; |
40 | private static final String API = "api"; | 40 | private static final String API = "api"; |
@@ -73,4 +73,9 @@ public class CoapTransportService { | @@ -73,4 +73,9 @@ public class CoapTransportService { | ||
73 | this.server.destroy(); | 73 | this.server.destroy(); |
74 | log.info("CoAP transport stopped!"); | 74 | log.info("CoAP transport stopped!"); |
75 | } | 75 | } |
76 | + | ||
77 | + @Override | ||
78 | + public String getName() { | ||
79 | + return "COAP"; | ||
80 | + } | ||
76 | } | 81 | } |
@@ -31,6 +31,7 @@ import org.springframework.web.bind.annotation.RequestParam; | @@ -31,6 +31,7 @@ import org.springframework.web.bind.annotation.RequestParam; | ||
31 | import org.springframework.web.bind.annotation.RestController; | 31 | import org.springframework.web.bind.annotation.RestController; |
32 | import org.springframework.web.context.request.async.DeferredResult; | 32 | import org.springframework.web.context.request.async.DeferredResult; |
33 | import org.thingsboard.server.common.data.DeviceTransportType; | 33 | import org.thingsboard.server.common.data.DeviceTransportType; |
34 | +import org.thingsboard.server.common.data.TbTransportService; | ||
34 | import org.thingsboard.server.common.data.id.DeviceId; | 35 | import org.thingsboard.server.common.data.id.DeviceId; |
35 | import org.thingsboard.server.common.transport.SessionMsgListener; | 36 | import org.thingsboard.server.common.transport.SessionMsgListener; |
36 | import org.thingsboard.server.common.transport.TransportContext; | 37 | import org.thingsboard.server.common.transport.TransportContext; |
@@ -41,7 +42,6 @@ import org.thingsboard.server.common.transport.auth.SessionInfoCreator; | @@ -41,7 +42,6 @@ import org.thingsboard.server.common.transport.auth.SessionInfoCreator; | ||
41 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | 42 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
42 | import org.thingsboard.server.gen.transport.TransportProtos; | 43 | import org.thingsboard.server.gen.transport.TransportProtos; |
43 | import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; | 44 | import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; |
44 | -import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; | ||
45 | import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg; | 45 | import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg; |
46 | import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponseMsg; | 46 | import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponseMsg; |
47 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; | 47 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; |
@@ -53,7 +53,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMs | @@ -53,7 +53,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMs | ||
53 | import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseMsg; | 53 | import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseMsg; |
54 | import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcRequestMsg; | 54 | import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcRequestMsg; |
55 | import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg; | 55 | import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg; |
56 | -import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; | ||
57 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; | 56 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; |
58 | 57 | ||
59 | import javax.servlet.http.HttpServletRequest; | 58 | import javax.servlet.http.HttpServletRequest; |
@@ -69,7 +68,7 @@ import java.util.function.Consumer; | @@ -69,7 +68,7 @@ import java.util.function.Consumer; | ||
69 | @ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.http.enabled}'=='true')") | 68 | @ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.http.enabled}'=='true')") |
70 | @RequestMapping("/api/v1") | 69 | @RequestMapping("/api/v1") |
71 | @Slf4j | 70 | @Slf4j |
72 | -public class DeviceApiController { | 71 | +public class DeviceApiController implements TbTransportService { |
73 | 72 | ||
74 | @Autowired | 73 | @Autowired |
75 | private HttpTransportContext transportContext; | 74 | private HttpTransportContext transportContext; |
@@ -338,4 +337,9 @@ public class DeviceApiController { | @@ -338,4 +337,9 @@ public class DeviceApiController { | ||
338 | .build(), TransportServiceCallback.EMPTY); | 337 | .build(), TransportServiceCallback.EMPTY); |
339 | } | 338 | } |
340 | 339 | ||
340 | + @Override | ||
341 | + public String getName() { | ||
342 | + return "HTTP"; | ||
343 | + } | ||
344 | + | ||
341 | } | 345 | } |
@@ -20,12 +20,13 @@ import org.eclipse.leshan.core.response.ReadResponse; | @@ -20,12 +20,13 @@ import org.eclipse.leshan.core.response.ReadResponse; | ||
20 | import org.eclipse.leshan.server.registration.Registration; | 20 | import org.eclipse.leshan.server.registration.Registration; |
21 | import org.thingsboard.server.common.data.Device; | 21 | import org.thingsboard.server.common.data.Device; |
22 | import org.thingsboard.server.common.data.DeviceProfile; | 22 | import org.thingsboard.server.common.data.DeviceProfile; |
23 | +import org.thingsboard.server.common.data.TbTransportService; | ||
23 | import org.thingsboard.server.gen.transport.TransportProtos; | 24 | import org.thingsboard.server.gen.transport.TransportProtos; |
24 | 25 | ||
25 | import java.util.Collection; | 26 | import java.util.Collection; |
26 | import java.util.Optional; | 27 | import java.util.Optional; |
27 | 28 | ||
28 | -public interface LwM2mTransportService { | 29 | +public interface LwM2mTransportService extends TbTransportService { |
29 | 30 | ||
30 | void onRegistered(Registration registration, Collection<Observation> previousObsersations); | 31 | void onRegistered(Registration registration, Collection<Observation> previousObsersations); |
31 | 32 |
@@ -40,6 +40,7 @@ import org.springframework.stereotype.Service; | @@ -40,6 +40,7 @@ import org.springframework.stereotype.Service; | ||
40 | import org.thingsboard.common.util.JacksonUtil; | 40 | import org.thingsboard.common.util.JacksonUtil; |
41 | import org.thingsboard.server.common.data.Device; | 41 | import org.thingsboard.server.common.data.Device; |
42 | import org.thingsboard.server.common.data.DeviceProfile; | 42 | import org.thingsboard.server.common.data.DeviceProfile; |
43 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
43 | import org.thingsboard.server.common.transport.TransportService; | 44 | import org.thingsboard.server.common.transport.TransportService; |
44 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; | 45 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; |
45 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; | 46 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; |
@@ -1118,4 +1119,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1118,4 +1119,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1118 | namesIsWritable.addAll(new HashSet<>(keyNamesIsWritable.values())); | 1119 | namesIsWritable.addAll(new HashSet<>(keyNamesIsWritable.values())); |
1119 | return new ArrayList<>(namesIsWritable); | 1120 | return new ArrayList<>(namesIsWritable); |
1120 | } | 1121 | } |
1122 | + | ||
1123 | + @Override | ||
1124 | + public String getName() { | ||
1125 | + return "LWM2M"; | ||
1126 | + } | ||
1121 | } | 1127 | } |
@@ -28,6 +28,7 @@ import org.springframework.beans.factory.annotation.Value; | @@ -28,6 +28,7 @@ import org.springframework.beans.factory.annotation.Value; | ||
28 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | 28 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
29 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | 29 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
30 | import org.springframework.stereotype.Service; | 30 | import org.springframework.stereotype.Service; |
31 | +import org.thingsboard.server.common.data.TbTransportService; | ||
31 | 32 | ||
32 | import javax.annotation.PostConstruct; | 33 | import javax.annotation.PostConstruct; |
33 | import javax.annotation.PreDestroy; | 34 | import javax.annotation.PreDestroy; |
@@ -38,7 +39,7 @@ import javax.annotation.PreDestroy; | @@ -38,7 +39,7 @@ import javax.annotation.PreDestroy; | ||
38 | @Service("MqttTransportService") | 39 | @Service("MqttTransportService") |
39 | @ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.mqtt.enabled}'=='true')") | 40 | @ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.mqtt.enabled}'=='true')") |
40 | @Slf4j | 41 | @Slf4j |
41 | -public class MqttTransportService { | 42 | +public class MqttTransportService implements TbTransportService { |
42 | 43 | ||
43 | @Value("${transport.mqtt.bind_address}") | 44 | @Value("${transport.mqtt.bind_address}") |
44 | private String host; | 45 | private String host; |
@@ -90,4 +91,9 @@ public class MqttTransportService { | @@ -90,4 +91,9 @@ public class MqttTransportService { | ||
90 | } | 91 | } |
91 | log.info("MQTT transport stopped!"); | 92 | log.info("MQTT transport stopped!"); |
92 | } | 93 | } |
94 | + | ||
95 | + @Override | ||
96 | + public String getName() { | ||
97 | + return "MQTT"; | ||
98 | + } | ||
93 | } | 99 | } |
@@ -58,9 +58,5 @@ | @@ -58,9 +58,5 @@ | ||
58 | <groupId>org.snmp4j</groupId> | 58 | <groupId>org.snmp4j</groupId> |
59 | <artifactId>snmp4j</artifactId> | 59 | <artifactId>snmp4j</artifactId> |
60 | </dependency> | 60 | </dependency> |
61 | - <dependency> | ||
62 | - <groupId>org.thingsboard.common</groupId> | ||
63 | - <artifactId>dao-api</artifactId> | ||
64 | - </dependency> | ||
65 | </dependencies> | 61 | </dependencies> |
66 | </project> | 62 | </project> |
common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/SnmpDeviceSimulator.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2021 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.transport.snmp; | ||
17 | + | ||
18 | +import org.snmp4j.CommunityTarget; | ||
19 | +import org.snmp4j.PDU; | ||
20 | +import org.snmp4j.Snmp; | ||
21 | +import org.snmp4j.Target; | ||
22 | +import org.snmp4j.event.ResponseEvent; | ||
23 | +import org.snmp4j.mp.SnmpConstants; | ||
24 | +import org.snmp4j.smi.GenericAddress; | ||
25 | +import org.snmp4j.smi.OID; | ||
26 | +import org.snmp4j.smi.OctetString; | ||
27 | +import org.snmp4j.smi.VariableBinding; | ||
28 | +import org.snmp4j.transport.DefaultUdpTransportMapping; | ||
29 | +import org.snmp4j.transport.UdpTransportMapping; | ||
30 | + | ||
31 | +import java.io.IOException; | ||
32 | + | ||
33 | +/** | ||
34 | + * For testing purposes. Will be removed when the time comes | ||
35 | + */ | ||
36 | +public class SnmpDeviceSimulator { | ||
37 | + private final Target target; | ||
38 | + private final OID oid = new OID(".1.3.6.1.2.1.1.1.0"); | ||
39 | + private Snmp snmp; | ||
40 | + | ||
41 | + public SnmpDeviceSimulator(int port) { | ||
42 | + String address = "udp:127.0.0.1/" + port; | ||
43 | + | ||
44 | + CommunityTarget target = new CommunityTarget(); | ||
45 | + target.setCommunity(new OctetString("public")); | ||
46 | + target.setAddress(GenericAddress.parse(address)); | ||
47 | + target.setRetries(2); | ||
48 | + target.setTimeout(1500); | ||
49 | + target.setVersion(SnmpConstants.version2c); | ||
50 | + | ||
51 | + this.target = target; | ||
52 | + } | ||
53 | + | ||
54 | + public static void main(String[] args) throws IOException { | ||
55 | + SnmpDeviceSimulator deviceSimulator = new SnmpDeviceSimulator(161); | ||
56 | + | ||
57 | + deviceSimulator.start(); | ||
58 | + String response = deviceSimulator.sendRequest(PDU.GET); | ||
59 | + | ||
60 | + System.out.println(response); | ||
61 | + } | ||
62 | + | ||
63 | + public void start() throws IOException { | ||
64 | + UdpTransportMapping transport = new DefaultUdpTransportMapping(); | ||
65 | + transport.addTransportListener((sourceTransport, incomingAddress, wholeMessage, tmStateReference) -> { | ||
66 | + System.out.println(); | ||
67 | + }); | ||
68 | + snmp = new Snmp(transport); | ||
69 | + | ||
70 | + transport.listen(); | ||
71 | + } | ||
72 | + | ||
73 | + public String sendRequest(int pduType) throws IOException { | ||
74 | + PDU pdu = new PDU(); | ||
75 | + pdu.add(new VariableBinding(oid)); | ||
76 | + pdu.setType(pduType); | ||
77 | + | ||
78 | + ResponseEvent responseEvent = snmp.send(pdu, target); | ||
79 | + return responseEvent.getResponse().get(0).getVariable().toString(); | ||
80 | + } | ||
81 | +} |
@@ -15,17 +15,19 @@ | @@ -15,17 +15,19 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.transport.snmp; | 16 | package org.thingsboard.server.transport.snmp; |
17 | 17 | ||
18 | -import lombok.Getter; | 18 | +import lombok.RequiredArgsConstructor; |
19 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
20 | import org.snmp4j.PDU; | 20 | import org.snmp4j.PDU; |
21 | -import org.snmp4j.Snmp; | ||
22 | import org.snmp4j.smi.OID; | 21 | import org.snmp4j.smi.OID; |
23 | import org.snmp4j.smi.VariableBinding; | 22 | import org.snmp4j.smi.VariableBinding; |
24 | -import org.springframework.beans.factory.annotation.Autowired; | ||
25 | -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
26 | -import org.springframework.stereotype.Service; | 23 | +import org.springframework.boot.context.event.ApplicationReadyEvent; |
24 | +import org.springframework.context.event.EventListener; | ||
25 | +import org.springframework.core.annotation.Order; | ||
26 | +import org.springframework.stereotype.Component; | ||
27 | import org.thingsboard.server.common.data.Device; | 27 | import org.thingsboard.server.common.data.Device; |
28 | import org.thingsboard.server.common.data.DeviceProfile; | 28 | import org.thingsboard.server.common.data.DeviceProfile; |
29 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
30 | +import org.thingsboard.server.common.data.device.data.DeviceTransportConfiguration; | ||
29 | import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration; | 31 | import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration; |
30 | import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileKvMapping; | 32 | import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileKvMapping; |
31 | import org.thingsboard.server.common.data.device.profile.SnmpProfileTransportConfiguration; | 33 | import org.thingsboard.server.common.data.device.profile.SnmpProfileTransportConfiguration; |
@@ -33,84 +35,180 @@ import org.thingsboard.server.common.data.id.DeviceId; | @@ -33,84 +35,180 @@ import org.thingsboard.server.common.data.id.DeviceId; | ||
33 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 35 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
34 | import org.thingsboard.server.common.data.security.DeviceCredentials; | 36 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
35 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; | 37 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; |
38 | +import org.thingsboard.server.common.transport.DeviceUpdatedEvent; | ||
36 | import org.thingsboard.server.common.transport.TransportContext; | 39 | import org.thingsboard.server.common.transport.TransportContext; |
37 | -import org.thingsboard.server.dao.device.DeviceCredentialsService; | ||
38 | -import org.thingsboard.server.transport.snmp.session.DeviceSessionCtx; | 40 | +import org.thingsboard.server.common.transport.TransportDeviceProfileCache; |
41 | +import org.thingsboard.server.common.transport.TransportService; | ||
42 | +import org.thingsboard.server.common.transport.TransportServiceCallback; | ||
43 | +import org.thingsboard.server.common.transport.auth.SessionInfoCreator; | ||
44 | +import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | ||
45 | +import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; | ||
46 | +import org.thingsboard.server.gen.transport.TransportProtos; | ||
47 | +import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; | ||
48 | +import org.thingsboard.server.queue.util.TbSnmpTransportComponent; | ||
49 | +import org.thingsboard.server.transport.snmp.service.ProtoTransportEntityService; | ||
50 | +import org.thingsboard.server.transport.snmp.service.SnmpTransportBalancingService; | ||
51 | +import org.thingsboard.server.transport.snmp.service.SnmpTransportService; | ||
52 | +import org.thingsboard.server.transport.snmp.session.DeviceSessionContext; | ||
39 | 53 | ||
40 | import java.util.ArrayList; | 54 | import java.util.ArrayList; |
55 | +import java.util.Collection; | ||
41 | import java.util.HashMap; | 56 | import java.util.HashMap; |
57 | +import java.util.LinkedList; | ||
42 | import java.util.List; | 58 | import java.util.List; |
43 | import java.util.Map; | 59 | import java.util.Map; |
44 | import java.util.Optional; | 60 | import java.util.Optional; |
61 | +import java.util.UUID; | ||
45 | import java.util.concurrent.ConcurrentHashMap; | 62 | import java.util.concurrent.ConcurrentHashMap; |
63 | +import java.util.concurrent.ConcurrentLinkedDeque; | ||
46 | import java.util.concurrent.ExecutorService; | 64 | import java.util.concurrent.ExecutorService; |
47 | import java.util.stream.Collectors; | 65 | import java.util.stream.Collectors; |
48 | 66 | ||
49 | -@Service("SnmpTransportContext") | ||
50 | -@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.snmp.enabled}'=='true')") | 67 | +@TbSnmpTransportComponent |
68 | +@Component | ||
51 | @Slf4j | 69 | @Slf4j |
70 | +@RequiredArgsConstructor | ||
52 | public class SnmpTransportContext extends TransportContext { | 71 | public class SnmpTransportContext extends TransportContext { |
53 | - @Autowired | ||
54 | - DeviceCredentialsService deviceCredentialsService; | ||
55 | - | ||
56 | - @Autowired | ||
57 | - SnmpTransportService snmpTransportService; | ||
58 | - | ||
59 | - @Getter | ||
60 | - private final Map<DeviceProfileId, SnmpProfileTransportConfiguration> profileTransportConfig = new ConcurrentHashMap<>(); | ||
61 | - @Getter | ||
62 | - private final Map<DeviceProfileId, List<PDU>> pdusPerProfile = new ConcurrentHashMap<>(); | ||
63 | - @Getter | ||
64 | - private final Map<DeviceId, DeviceSessionCtx> deviceSessions = new ConcurrentHashMap<>(); | ||
65 | - | ||
66 | - public Optional<SnmpDeviceProfileKvMapping> findAttributesMapping(DeviceProfileId deviceProfileId, OID responseOid) { | ||
67 | - if (profileTransportConfig.containsKey(deviceProfileId)) { | ||
68 | - return findMapping(responseOid, profileTransportConfig.get(deviceProfileId).getAttributes()); | ||
69 | - } | ||
70 | - return Optional.empty(); | 72 | + private final SnmpTransportService snmpTransportService; |
73 | + private final TransportDeviceProfileCache deviceProfileCache; | ||
74 | + private final TransportService transportService; | ||
75 | + private final ProtoTransportEntityService protoEntityService; | ||
76 | + private final SnmpTransportBalancingService balancingService; | ||
77 | + | ||
78 | + private final Map<DeviceId, DeviceSessionContext> sessions = new ConcurrentHashMap<>(); | ||
79 | + private final Map<DeviceProfileId, SnmpProfileTransportConfiguration> profilesTransportConfigs = new ConcurrentHashMap<>(); | ||
80 | + private final Map<DeviceProfileId, List<PDU>> profilesPdus = new ConcurrentHashMap<>(); | ||
81 | + private Collection<DeviceId> allSnmpDevicesIds = new ConcurrentLinkedDeque<>(); | ||
82 | + | ||
83 | + @EventListener(ApplicationReadyEvent.class) | ||
84 | + @Order(2) | ||
85 | + public void initDevicesSessions() { | ||
86 | + log.info("Initializing SNMP devices sessions"); | ||
87 | + allSnmpDevicesIds = protoEntityService.getAllSnmpDevicesIds().stream() | ||
88 | + .map(DeviceId::new) | ||
89 | + .collect(Collectors.toList()); | ||
90 | + log.trace("Found all SNMP devices ids: {}", allSnmpDevicesIds); | ||
91 | + | ||
92 | + List<DeviceId> managedDevicesIds = allSnmpDevicesIds.stream() | ||
93 | + .filter(deviceId -> balancingService.isManagedByCurrentTransport(deviceId.getId())) | ||
94 | + .collect(Collectors.toList()); | ||
95 | + log.info("SNMP devices managed by current SNMP transport: {}", managedDevicesIds); | ||
96 | + | ||
97 | + managedDevicesIds.stream() | ||
98 | + .map(protoEntityService::getDeviceById) | ||
99 | + .collect(Collectors.toList()) | ||
100 | + .forEach(this::establishDeviceSession); | ||
71 | } | 101 | } |
72 | 102 | ||
73 | - public Optional<SnmpDeviceProfileKvMapping> findTelemetryMapping(DeviceProfileId deviceProfileId, OID responseOid) { | ||
74 | - if (profileTransportConfig.containsKey(deviceProfileId)) { | ||
75 | - return findMapping(responseOid, profileTransportConfig.get(deviceProfileId).getTelemetry()); | 103 | + private void establishDeviceSession(Device device) { |
104 | + if (device == null) return; | ||
105 | + log.info("Establishing SNMP device session for device {}", device.getId()); | ||
106 | + | ||
107 | + DeviceProfileId deviceProfileId = device.getDeviceProfileId(); | ||
108 | + DeviceProfile deviceProfile = deviceProfileCache.get(deviceProfileId); | ||
109 | + | ||
110 | + DeviceCredentials credentials = protoEntityService.getDeviceCredentialsByDeviceId(device.getId()); | ||
111 | + if (credentials.getCredentialsType() != DeviceCredentialsType.ACCESS_TOKEN) { | ||
112 | + log.warn("[{}] Expected credentials type is {} but found {}", device.getId(), DeviceCredentialsType.ACCESS_TOKEN, credentials.getCredentialsType()); | ||
113 | + return; | ||
76 | } | 114 | } |
77 | - return Optional.empty(); | ||
78 | - } | ||
79 | 115 | ||
80 | - private Optional<SnmpDeviceProfileKvMapping> findMapping(OID responseOid, List<SnmpDeviceProfileKvMapping> mappings) { | ||
81 | - return mappings.stream() | ||
82 | - .filter(kvMapping -> new OID(kvMapping.getOid()).equals(responseOid)) | ||
83 | - //TODO: OID shouldn't be duplicated in the config, add backend and UI verification | ||
84 | - .findFirst(); | ||
85 | - } | 116 | + SnmpDeviceTransportConfiguration deviceTransportConfiguration = (SnmpDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration(); |
117 | + if (!deviceTransportConfiguration.isValid()) { | ||
118 | + log.warn("SNMP device transport configuration is not valid"); | ||
119 | + return; | ||
120 | + } | ||
86 | 121 | ||
87 | - public void initPduListPerProfile() { | ||
88 | - profileTransportConfig.forEach(this::updatePduListPerProfile); | ||
89 | - } | 122 | + SnmpProfileTransportConfiguration profileTransportConfiguration = (SnmpProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration(); |
123 | + profilesPdus.computeIfAbsent(deviceProfileId, id -> createPdus(profileTransportConfiguration)); | ||
90 | 124 | ||
91 | - public void updatePduListPerProfile(DeviceProfileId id, SnmpProfileTransportConfiguration config) { | ||
92 | - pdusPerProfile.put(id, createPduList(config)); | 125 | + DeviceSessionContext deviceSessionContext = new DeviceSessionContext( |
126 | + device, deviceProfile, | ||
127 | + credentials.getCredentialsId(), deviceTransportConfiguration, | ||
128 | + this, snmpTransportService | ||
129 | + ); | ||
130 | + registerSessionMsgListener(deviceSessionContext); | ||
131 | + sessions.put(device.getId(), deviceSessionContext); | ||
132 | + log.info("Established SNMP device session for device {}", device.getId()); | ||
93 | } | 133 | } |
94 | 134 | ||
95 | - public void updateDeviceSessionCtx(Device device, DeviceProfile deviceProfile, Snmp snmp) { | ||
96 | - DeviceCredentials credentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(device.getTenantId(), device.getId()); | ||
97 | - if (DeviceCredentialsType.ACCESS_TOKEN.equals(credentials.getCredentialsType())) { | ||
98 | - SnmpDeviceTransportConfiguration snmpDeviceTransportConfiguration = (SnmpDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration(); | ||
99 | - if (snmpDeviceTransportConfiguration.isValid()) { | ||
100 | - DeviceSessionCtx deviceSessionCtx = new DeviceSessionCtx(this, credentials.getCredentialsId(), snmpDeviceTransportConfiguration, snmp, device.getId(), deviceProfile); | ||
101 | - deviceSessionCtx.createSessionInfo(ctx -> getTransportService().registerAsyncSession(deviceSessionCtx.getSessionInfo(), deviceSessionCtx)); | ||
102 | - this.deviceSessions.put(device.getId(), deviceSessionCtx); | ||
103 | - } | ||
104 | - } else { | 135 | + private void updateDeviceSession(DeviceSessionContext sessionContext, Device device, DeviceProfile deviceProfile) { |
136 | + log.info("Updating SNMP device session for device {}", device.getId()); | ||
137 | + DeviceProfileId deviceProfileId = deviceProfile.getId(); | ||
138 | + | ||
139 | + DeviceCredentials credentials = protoEntityService.getDeviceCredentialsByDeviceId(device.getId()); | ||
140 | + if (credentials.getCredentialsType() != DeviceCredentialsType.ACCESS_TOKEN) { | ||
105 | log.warn("[{}] Expected credentials type is {} but found {}", device.getId(), DeviceCredentialsType.ACCESS_TOKEN, credentials.getCredentialsType()); | 141 | log.warn("[{}] Expected credentials type is {} but found {}", device.getId(), DeviceCredentialsType.ACCESS_TOKEN, credentials.getCredentialsType()); |
142 | + destroyDeviceSession(sessionContext); | ||
143 | + return; | ||
144 | + } | ||
145 | + | ||
146 | + SnmpProfileTransportConfiguration profileTransportConfiguration = (SnmpProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration(); | ||
147 | + SnmpDeviceTransportConfiguration deviceTransportConfiguration = (SnmpDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration(); | ||
148 | + sessionContext.setProfileTransportConfiguration(profileTransportConfiguration); | ||
149 | + sessionContext.setDeviceTransportConfiguration(deviceTransportConfiguration); | ||
150 | + if (!deviceTransportConfiguration.isValid()) { | ||
151 | + log.warn("SNMP device transport configuration is not valid"); | ||
152 | + destroyDeviceSession(sessionContext); | ||
153 | + return; | ||
154 | + } | ||
155 | + | ||
156 | + if (!profileTransportConfiguration.equals(profilesTransportConfigs.get(deviceProfileId))) { | ||
157 | + profilesPdus.put(deviceProfileId, createPdus(profileTransportConfiguration)); | ||
158 | + profilesTransportConfigs.put(deviceProfileId, profileTransportConfiguration); | ||
159 | + sessionContext.initTarget(profileTransportConfiguration, deviceTransportConfiguration); | ||
160 | + } else if (!deviceTransportConfiguration.equals(sessionContext.getDeviceTransportConfiguration())) { | ||
161 | + sessionContext.initTarget(profileTransportConfiguration, deviceTransportConfiguration); | ||
162 | + } else { | ||
163 | + log.trace("Configuration of the device {} was not updated", device); | ||
106 | } | 164 | } |
107 | } | 165 | } |
108 | 166 | ||
109 | - public ExecutorService getSnmpCallbackExecutor() { | ||
110 | - return snmpTransportService.getSnmpCallbackExecutor(); | 167 | + private void destroyDeviceSession(DeviceSessionContext sessionContext) { |
168 | + if (sessionContext == null) return; | ||
169 | + log.info("Destroying SNMP device session for device {}", sessionContext.getDevice().getId()); | ||
170 | + sessionContext.close(); | ||
171 | + transportService.deregisterSession(sessionContext.getSessionInfo()); | ||
172 | + sessions.remove(sessionContext.getDeviceId()); | ||
173 | + log.trace("Deregistered and removed session"); | ||
174 | + | ||
175 | + DeviceProfileId deviceProfileId = sessionContext.getDeviceProfile().getId(); | ||
176 | + if (sessions.values().stream() | ||
177 | + .map(DeviceAwareSessionContext::getDeviceProfile) | ||
178 | + .noneMatch(deviceProfile -> deviceProfile.getId().equals(deviceProfileId))) { | ||
179 | + log.trace("Removed values for device profile {} from configs and pdus caches", deviceProfileId); | ||
180 | + profilesTransportConfigs.remove(deviceProfileId); | ||
181 | + profilesPdus.remove(deviceProfileId); | ||
182 | + } | ||
111 | } | 183 | } |
112 | 184 | ||
113 | - private List<PDU> createPduList(SnmpProfileTransportConfiguration deviceProfileConfig) { | 185 | + private void registerSessionMsgListener(DeviceSessionContext deviceSessionContext) { |
186 | + transportService.process(DeviceTransportType.SNMP, | ||
187 | + TransportProtos.ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceSessionContext.getToken()).build(), | ||
188 | + new TransportServiceCallback<ValidateDeviceCredentialsResponse>() { | ||
189 | + @Override | ||
190 | + public void onSuccess(ValidateDeviceCredentialsResponse msg) { | ||
191 | + if (msg.hasDeviceInfo()) { | ||
192 | + SessionInfoProto sessionInfo = SessionInfoCreator.create( | ||
193 | + msg, SnmpTransportContext.this, UUID.randomUUID() | ||
194 | + ); | ||
195 | + | ||
196 | + transportService.registerAsyncSession(sessionInfo, deviceSessionContext); | ||
197 | + deviceSessionContext.setSessionInfo(sessionInfo); | ||
198 | + deviceSessionContext.setDeviceInfo(msg.getDeviceInfo()); | ||
199 | + } else { | ||
200 | + log.warn("[{}] Failed to process device auth", deviceSessionContext.getDeviceId()); | ||
201 | + } | ||
202 | + } | ||
203 | + | ||
204 | + @Override | ||
205 | + public void onError(Throwable e) { | ||
206 | + log.warn("[{}] Failed to process device auth: {}", deviceSessionContext.getDeviceId(), e); | ||
207 | + } | ||
208 | + }); | ||
209 | + } | ||
210 | + | ||
211 | + private List<PDU> createPdus(SnmpProfileTransportConfiguration deviceProfileConfig) { | ||
114 | Map<String, List<VariableBinding>> varBindingPerMethod = new HashMap<>(); | 212 | Map<String, List<VariableBinding>> varBindingPerMethod = new HashMap<>(); |
115 | 213 | ||
116 | deviceProfileConfig.getKvMappings().forEach(mapping -> varBindingPerMethod | 214 | deviceProfileConfig.getKvMappings().forEach(mapping -> varBindingPerMethod |
@@ -127,7 +225,106 @@ public class SnmpTransportContext extends TransportContext { | @@ -127,7 +225,106 @@ public class SnmpTransportContext extends TransportContext { | ||
127 | .collect(Collectors.toList()); | 225 | .collect(Collectors.toList()); |
128 | } | 226 | } |
129 | 227 | ||
130 | - //TODO: Extract SNMP methods to enum | 228 | + @EventListener(DeviceUpdatedEvent.class) |
229 | + public void onDeviceUpdatedOrCreated(DeviceUpdatedEvent deviceUpdatedEvent) { | ||
230 | + Device device = deviceUpdatedEvent.getDevice(); | ||
231 | + log.trace("Got creating or updating device event for device {}", device); | ||
232 | + DeviceTransportType transportType = Optional.ofNullable(device.getDeviceData().getTransportConfiguration()) | ||
233 | + .map(DeviceTransportConfiguration::getType) | ||
234 | + .orElse(null); | ||
235 | + if (!allSnmpDevicesIds.contains(device.getId())) { | ||
236 | + if (transportType != DeviceTransportType.SNMP) { | ||
237 | + return; | ||
238 | + } | ||
239 | + allSnmpDevicesIds.add(device.getId()); | ||
240 | + if (balancingService.isManagedByCurrentTransport(device.getId().getId())) { | ||
241 | + establishDeviceSession(device); | ||
242 | + } | ||
243 | + } else { | ||
244 | + if (balancingService.isManagedByCurrentTransport(device.getId().getId())) { | ||
245 | + DeviceSessionContext sessionContext = sessions.get(device.getId()); | ||
246 | + if (transportType == DeviceTransportType.SNMP) { | ||
247 | + if (sessionContext != null) { | ||
248 | + updateDeviceSession(sessionContext, device, deviceProfileCache.get(device.getDeviceProfileId())); | ||
249 | + } else { | ||
250 | + establishDeviceSession(device); | ||
251 | + } | ||
252 | + } else { | ||
253 | + log.trace("Transport type was changed to {}", transportType); | ||
254 | + destroyDeviceSession(sessionContext); | ||
255 | + } | ||
256 | + } | ||
257 | + } | ||
258 | + } | ||
259 | + | ||
260 | + public void onDeviceDeleted(DeviceSessionContext sessionContext) { | ||
261 | + destroyDeviceSession(sessionContext); | ||
262 | + } | ||
263 | + | ||
264 | + public void onDeviceProfileUpdated(DeviceProfile deviceProfile, DeviceSessionContext sessionContext) { | ||
265 | + updateDeviceSession(sessionContext, sessionContext.getDevice(), deviceProfile); | ||
266 | + } | ||
267 | + | ||
268 | + public void onSnmpTransportListChanged() { | ||
269 | + log.trace("SNMP transport list changed. Updating sessions"); | ||
270 | + List<DeviceId> deleted = new LinkedList<>(); | ||
271 | + for (DeviceId deviceId : allSnmpDevicesIds) { | ||
272 | + if (balancingService.isManagedByCurrentTransport(deviceId.getId())) { | ||
273 | + if (!sessions.containsKey(deviceId)) { | ||
274 | + Device device = protoEntityService.getDeviceById(deviceId); | ||
275 | + if (device != null) { | ||
276 | + log.info("SNMP device {} is now managed by current transport node", deviceId); | ||
277 | + establishDeviceSession(device); | ||
278 | + } else { | ||
279 | + deleted.add(deviceId); | ||
280 | + } | ||
281 | + } | ||
282 | + } else { | ||
283 | + Optional.ofNullable(sessions.get(deviceId)) | ||
284 | + .ifPresent(sessionContext -> { | ||
285 | + log.info("SNMP session for device {} is not managed by current transport node anymore", deviceId); | ||
286 | + destroyDeviceSession(sessionContext); | ||
287 | + }); | ||
288 | + } | ||
289 | + } | ||
290 | + log.trace("Removing deleted SNMP devices: {}", deleted); | ||
291 | + allSnmpDevicesIds.removeAll(deleted); | ||
292 | + } | ||
293 | + | ||
294 | + | ||
295 | + public Collection<DeviceSessionContext> getSessions() { | ||
296 | + return sessions.values(); | ||
297 | + } | ||
298 | + | ||
299 | + public Map<DeviceProfileId, List<PDU>> getProfilesPdus() { | ||
300 | + return profilesPdus; | ||
301 | + } | ||
302 | + | ||
303 | + public Optional<SnmpDeviceProfileKvMapping> getAttributesMapping(DeviceProfileId deviceProfileId, OID responseOid) { | ||
304 | + if (profilesTransportConfigs.containsKey(deviceProfileId)) { | ||
305 | + return getMapping(responseOid, profilesTransportConfigs.get(deviceProfileId).getAttributes()); | ||
306 | + } | ||
307 | + return Optional.empty(); | ||
308 | + } | ||
309 | + | ||
310 | + public Optional<SnmpDeviceProfileKvMapping> getTelemetryMapping(DeviceProfileId deviceProfileId, OID responseOid) { | ||
311 | + if (profilesTransportConfigs.containsKey(deviceProfileId)) { | ||
312 | + return getMapping(responseOid, profilesTransportConfigs.get(deviceProfileId).getTelemetry()); | ||
313 | + } | ||
314 | + return Optional.empty(); | ||
315 | + } | ||
316 | + | ||
317 | + private Optional<SnmpDeviceProfileKvMapping> getMapping(OID responseOid, List<SnmpDeviceProfileKvMapping> mappings) { | ||
318 | + return mappings.stream() | ||
319 | + .filter(kvMapping -> new OID(kvMapping.getOid()).equals(responseOid)) | ||
320 | + //TODO: OID shouldn't be duplicated in the config, add backend and UI verification | ||
321 | + .findFirst(); | ||
322 | + } | ||
323 | + | ||
324 | + public ExecutorService getSnmpCallbackExecutor() { | ||
325 | + return snmpTransportService.getSnmpCallbackExecutor(); | ||
326 | + } | ||
327 | + | ||
131 | private int getSnmpMethod(String configMethod) { | 328 | private int getSnmpMethod(String configMethod) { |
132 | switch (configMethod) { | 329 | switch (configMethod) { |
133 | case "get": | 330 | case "get": |
common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/SnmpTransportService.java
deleted
100644 → 0
1 | -/** | ||
2 | - * Copyright © 2016-2021 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.transport.snmp; | ||
17 | - | ||
18 | -import lombok.Getter; | ||
19 | -import lombok.extern.slf4j.Slf4j; | ||
20 | -import org.snmp4j.Snmp; | ||
21 | -import org.snmp4j.transport.DefaultUdpTransportMapping; | ||
22 | -import org.springframework.beans.factory.annotation.Autowired; | ||
23 | -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
24 | -import org.springframework.boot.context.event.ApplicationReadyEvent; | ||
25 | -import org.springframework.context.event.EventListener; | ||
26 | -import org.springframework.core.annotation.Order; | ||
27 | -import org.springframework.stereotype.Service; | ||
28 | -import org.thingsboard.common.util.ThingsBoardThreadFactory; | ||
29 | -import org.thingsboard.server.common.data.DeviceInfo; | ||
30 | -import org.thingsboard.server.common.data.DeviceProfile; | ||
31 | -import org.thingsboard.server.common.data.DeviceTransportType; | ||
32 | -import org.thingsboard.server.common.data.Tenant; | ||
33 | -import org.thingsboard.server.common.data.device.profile.SnmpProfileTransportConfiguration; | ||
34 | -import org.thingsboard.server.common.data.id.TenantId; | ||
35 | -import org.thingsboard.server.common.data.page.PageDataIterable; | ||
36 | -import org.thingsboard.server.dao.device.DeviceProfileService; | ||
37 | -import org.thingsboard.server.dao.device.DeviceService; | ||
38 | -import org.thingsboard.server.dao.tenant.TenantService; | ||
39 | -import org.thingsboard.server.transport.snmp.session.DeviceSessionCtx; | ||
40 | - | ||
41 | -import javax.annotation.PostConstruct; | ||
42 | -import javax.annotation.PreDestroy; | ||
43 | -import java.io.IOException; | ||
44 | -import java.util.concurrent.ExecutorService; | ||
45 | -import java.util.concurrent.Executors; | ||
46 | -import java.util.concurrent.ScheduledExecutorService; | ||
47 | -import java.util.concurrent.TimeUnit; | ||
48 | - | ||
49 | -@Service("SnmpTransportService") | ||
50 | -@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.snmp.enabled}'=='true')") | ||
51 | -@Slf4j | ||
52 | -public class SnmpTransportService { | ||
53 | - | ||
54 | - private static final int ENTITY_PACK_LIMIT = 1024; | ||
55 | - | ||
56 | - @Autowired | ||
57 | - private SnmpTransportContext snmpTransportContext; | ||
58 | - | ||
59 | - @Autowired | ||
60 | - DeviceProfileService deviceProfileService; | ||
61 | - | ||
62 | - @Autowired | ||
63 | - TenantService tenantService; | ||
64 | - | ||
65 | - @Autowired | ||
66 | - DeviceService deviceService; | ||
67 | - | ||
68 | - @Getter | ||
69 | - private ExecutorService snmpCallbackExecutor; | ||
70 | - private Snmp snmp; | ||
71 | - private ScheduledExecutorService pollingExecutor; | ||
72 | - | ||
73 | - @PostConstruct | ||
74 | - public void init() { | ||
75 | - log.info("Starting SNMP transport..."); | ||
76 | - pollingExecutor = Executors.newScheduledThreadPool(1, ThingsBoardThreadFactory.forName("snmp-polling")); | ||
77 | - //TODO: Set parallelism value in the config | ||
78 | - snmpCallbackExecutor = Executors.newWorkStealingPool(20); | ||
79 | - initializeSnmp(); | ||
80 | - log.info("SNMP transport started!"); | ||
81 | - } | ||
82 | - | ||
83 | - @PreDestroy | ||
84 | - public void shutdown() { | ||
85 | - log.info("Stopping SNMP transport!"); | ||
86 | - if (pollingExecutor != null) { | ||
87 | - pollingExecutor.shutdownNow(); | ||
88 | - } | ||
89 | - if (snmpCallbackExecutor != null) { | ||
90 | - snmpCallbackExecutor.shutdownNow(); | ||
91 | - } | ||
92 | - if (snmp != null) { | ||
93 | - try { | ||
94 | - snmp.close(); | ||
95 | - } catch (IOException e) { | ||
96 | - log.error(e.getMessage(), e); | ||
97 | - } | ||
98 | - } | ||
99 | - log.info("SNMP transport stopped!"); | ||
100 | - } | ||
101 | - | ||
102 | - @EventListener(ApplicationReadyEvent.class) | ||
103 | - @Order(value = 2) | ||
104 | - public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { | ||
105 | - log.info("Received application ready event. Starting SNMP polling."); | ||
106 | - initSessionCtxList(); | ||
107 | - startPolling(); | ||
108 | - } | ||
109 | - | ||
110 | - private void initializeSnmp() { | ||
111 | - try { | ||
112 | - this.snmp = new Snmp(new DefaultUdpTransportMapping()); | ||
113 | - this.snmp.listen(); | ||
114 | - } catch (IOException e) { | ||
115 | - //TODO: what should be done if transport wasn't initialized? | ||
116 | - log.error(e.getMessage(), e); | ||
117 | - } | ||
118 | - } | ||
119 | - | ||
120 | - private void initSessionCtxList() { | ||
121 | - //TODO: This approach works for monolith, in cluster the same data will be fetched by each node. | ||
122 | - for (Tenant tenant : new PageDataIterable<>(tenantService::findTenants, ENTITY_PACK_LIMIT)) { | ||
123 | - TenantId tenantId = tenant.getTenantId(); | ||
124 | - for (DeviceProfile deviceProfile : new PageDataIterable<>(pageLink -> deviceProfileService.findDeviceProfiles(tenantId, pageLink), ENTITY_PACK_LIMIT)) { | ||
125 | - if (DeviceTransportType.SNMP.equals(deviceProfile.getTransportType())) { | ||
126 | - snmpTransportContext.getProfileTransportConfig().put(deviceProfile.getId(), | ||
127 | - (SnmpProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()); | ||
128 | - initDeviceSessions(deviceProfile); | ||
129 | - } | ||
130 | - } | ||
131 | - } | ||
132 | - snmpTransportContext.initPduListPerProfile(); | ||
133 | - } | ||
134 | - | ||
135 | - private void initDeviceSessions(DeviceProfile deviceProfile) { | ||
136 | - for (DeviceInfo deviceInfo : new PageDataIterable<>(pageLink -> deviceService.findDeviceInfosByTenantIdAndDeviceProfileId(deviceProfile.getTenantId(), deviceProfile.getId(), pageLink), ENTITY_PACK_LIMIT)) { | ||
137 | - snmpTransportContext.updateDeviceSessionCtx(deviceInfo, deviceProfile, snmp); | ||
138 | - } | ||
139 | - } | ||
140 | - | ||
141 | - private void startPolling() { | ||
142 | - //TODO: Get poll period from configuration; | ||
143 | - int poolPeriodSeconds = 1; | ||
144 | - pollingExecutor.scheduleAtFixedRate(() -> snmpTransportContext.getDeviceSessions().values().forEach(DeviceSessionCtx::executeSnmpRequest), | ||
145 | - 0, poolPeriodSeconds, TimeUnit.SECONDS); | ||
146 | - } | ||
147 | -} |
1 | +/** | ||
2 | + * Copyright © 2016-2021 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.transport.snmp.event; | ||
17 | + | ||
18 | +import lombok.RequiredArgsConstructor; | ||
19 | +import org.springframework.stereotype.Component; | ||
20 | +import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | ||
21 | +import org.thingsboard.server.queue.discovery.event.ServiceListChangedEvent; | ||
22 | +import org.thingsboard.server.queue.util.TbSnmpTransportComponent; | ||
23 | +import org.thingsboard.server.transport.snmp.service.SnmpTransportBalancingService; | ||
24 | + | ||
25 | +@TbSnmpTransportComponent | ||
26 | +@Component | ||
27 | +@RequiredArgsConstructor | ||
28 | +public class ServiceListChangedEventListener extends TbApplicationEventListener<ServiceListChangedEvent> { | ||
29 | + private final SnmpTransportBalancingService snmpTransportBalancingService; | ||
30 | + | ||
31 | + @Override | ||
32 | + protected void onTbApplicationEvent(ServiceListChangedEvent event) { | ||
33 | + snmpTransportBalancingService.onServiceListChanged(event); | ||
34 | + } | ||
35 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2021 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.transport.snmp.event; | ||
17 | + | ||
18 | +import org.thingsboard.server.queue.discovery.event.TbApplicationEvent; | ||
19 | + | ||
20 | +public class SnmpTransportListChangedEvent extends TbApplicationEvent { | ||
21 | + public SnmpTransportListChangedEvent() { | ||
22 | + super(new Object()); | ||
23 | + } | ||
24 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2021 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.transport.snmp.event; | ||
17 | + | ||
18 | +import lombok.RequiredArgsConstructor; | ||
19 | +import org.springframework.stereotype.Component; | ||
20 | +import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | ||
21 | +import org.thingsboard.server.queue.util.TbSnmpTransportComponent; | ||
22 | +import org.thingsboard.server.transport.snmp.SnmpTransportContext; | ||
23 | + | ||
24 | +@TbSnmpTransportComponent | ||
25 | +@Component | ||
26 | +@RequiredArgsConstructor | ||
27 | +public class SnmpTransportListChangedEventListener extends TbApplicationEventListener<SnmpTransportListChangedEvent> { | ||
28 | + private final SnmpTransportContext snmpTransportContext; | ||
29 | + | ||
30 | + @Override | ||
31 | + protected void onTbApplicationEvent(SnmpTransportListChangedEvent event) { | ||
32 | + snmpTransportContext.onSnmpTransportListChanged(); | ||
33 | + } | ||
34 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2021 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.transport.snmp.service; | ||
17 | + | ||
18 | +import lombok.RequiredArgsConstructor; | ||
19 | +import org.springframework.stereotype.Service; | ||
20 | +import org.thingsboard.server.common.data.Device; | ||
21 | +import org.thingsboard.server.common.data.device.data.DeviceData; | ||
22 | +import org.thingsboard.server.common.data.device.data.DeviceTransportConfiguration; | ||
23 | +import org.thingsboard.server.common.data.id.DeviceId; | ||
24 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
25 | +import org.thingsboard.server.common.data.security.DeviceCredentials; | ||
26 | +import org.thingsboard.server.common.transport.TransportService; | ||
27 | +import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; | ||
28 | +import org.thingsboard.server.gen.transport.TransportProtos; | ||
29 | +import org.thingsboard.server.queue.util.TbSnmpTransportComponent; | ||
30 | + | ||
31 | +import java.util.List; | ||
32 | +import java.util.UUID; | ||
33 | +import java.util.stream.Collectors; | ||
34 | + | ||
35 | +@TbSnmpTransportComponent | ||
36 | +@Service | ||
37 | +@RequiredArgsConstructor | ||
38 | +public class ProtoTransportEntityService { | ||
39 | + private final TransportService transportService; | ||
40 | + private final DataDecodingEncodingService dataDecodingEncodingService; | ||
41 | + | ||
42 | + public Device getDeviceById(DeviceId id) { | ||
43 | + TransportProtos.GetDeviceResponseMsg deviceProto = transportService.getDevice(TransportProtos.GetDeviceRequestMsg.newBuilder() | ||
44 | + .setDeviceIdMSB(id.getId().getMostSignificantBits()) | ||
45 | + .setDeviceIdLSB(id.getId().getLeastSignificantBits()) | ||
46 | + .build()); | ||
47 | + | ||
48 | + if (deviceProto == null) { | ||
49 | + return null; | ||
50 | + } | ||
51 | + | ||
52 | + DeviceProfileId deviceProfileId = new DeviceProfileId(new UUID( | ||
53 | + deviceProto.getDeviceProfileIdMSB(), deviceProto.getDeviceProfileIdLSB()) | ||
54 | + ); | ||
55 | + | ||
56 | + Device device = new Device(); | ||
57 | + device.setId(id); | ||
58 | + device.setDeviceProfileId(deviceProfileId); | ||
59 | + | ||
60 | + DeviceTransportConfiguration deviceTransportConfiguration = (DeviceTransportConfiguration) dataDecodingEncodingService.decode( | ||
61 | + deviceProto.getDeviceTransportConfiguration().toByteArray() | ||
62 | + ).orElseThrow(() -> new IllegalStateException("Can't find device transport configuration")); | ||
63 | + | ||
64 | + DeviceData deviceData = new DeviceData(); | ||
65 | + deviceData.setTransportConfiguration(deviceTransportConfiguration); | ||
66 | + device.setDeviceData(deviceData); | ||
67 | + | ||
68 | + return device; | ||
69 | + } | ||
70 | + | ||
71 | + public DeviceCredentials getDeviceCredentialsByDeviceId(DeviceId deviceId) { | ||
72 | + TransportProtos.GetDeviceCredentialsResponseMsg deviceCredentialsResponse = transportService.getDeviceCredentials( | ||
73 | + TransportProtos.GetDeviceCredentialsRequestMsg.newBuilder() | ||
74 | + .setDeviceIdMSB(deviceId.getId().getMostSignificantBits()) | ||
75 | + .setDeviceIdLSB(deviceId.getId().getLeastSignificantBits()) | ||
76 | + .build() | ||
77 | + ); | ||
78 | + | ||
79 | + return (DeviceCredentials) dataDecodingEncodingService.decode(deviceCredentialsResponse.getDeviceCredentialsData().toByteArray()) | ||
80 | + .orElseThrow(() -> new IllegalArgumentException("Device credentials not found")); | ||
81 | + } | ||
82 | + | ||
83 | + public List<UUID> getAllSnmpDevicesIds() { | ||
84 | + TransportProtos.GetSnmpDevicesResponseMsg devicesIdsResponse = transportService.getSnmpDevicesIds( | ||
85 | + TransportProtos.GetSnmpDevicesRequestMsg.getDefaultInstance() | ||
86 | + ); | ||
87 | + | ||
88 | + return devicesIdsResponse.getIdsList().stream() | ||
89 | + .map(UUID::fromString) | ||
90 | + .collect(Collectors.toList()); | ||
91 | + } | ||
92 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2021 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.transport.snmp.service; | ||
17 | + | ||
18 | +import lombok.RequiredArgsConstructor; | ||
19 | +import lombok.extern.slf4j.Slf4j; | ||
20 | +import org.springframework.context.ApplicationEventPublisher; | ||
21 | +import org.springframework.stereotype.Service; | ||
22 | +import org.thingsboard.server.gen.transport.TransportProtos.ServiceInfo; | ||
23 | +import org.thingsboard.server.queue.discovery.PartitionService; | ||
24 | +import org.thingsboard.server.queue.discovery.event.ServiceListChangedEvent; | ||
25 | +import org.thingsboard.server.queue.util.TbSnmpTransportComponent; | ||
26 | +import org.thingsboard.server.transport.snmp.event.SnmpTransportListChangedEvent; | ||
27 | + | ||
28 | +import java.util.Comparator; | ||
29 | +import java.util.List; | ||
30 | +import java.util.UUID; | ||
31 | +import java.util.stream.Collectors; | ||
32 | +import java.util.stream.Stream; | ||
33 | + | ||
34 | +@TbSnmpTransportComponent | ||
35 | +@Service | ||
36 | +@RequiredArgsConstructor | ||
37 | +@Slf4j | ||
38 | +public class SnmpTransportBalancingService { | ||
39 | + private final PartitionService partitionService; | ||
40 | + private final ApplicationEventPublisher eventPublisher; | ||
41 | + private final SnmpTransportService snmpTransportService; | ||
42 | + | ||
43 | + private int snmpTransportsCount = 1; | ||
44 | + private Integer currentTransportPartitionIndex = 0; | ||
45 | + | ||
46 | + public void onServiceListChanged(ServiceListChangedEvent event) { | ||
47 | + log.trace("Got service list changed event: {}", event); | ||
48 | + recalculatePartitions(event.getOtherServices(), event.getCurrentService()); | ||
49 | + } | ||
50 | + | ||
51 | + public boolean isManagedByCurrentTransport(UUID entityId) { | ||
52 | + boolean isManaged = resolvePartitionIndexForEntity(entityId) == currentTransportPartitionIndex; | ||
53 | + if (!isManaged) { | ||
54 | + log.trace("Entity {} is not managed by current SNMP transport node", entityId); | ||
55 | + } | ||
56 | + return isManaged; | ||
57 | + } | ||
58 | + | ||
59 | + private int resolvePartitionIndexForEntity(UUID entityId) { | ||
60 | + return partitionService.resolvePartitionIndex(entityId, snmpTransportsCount); | ||
61 | + } | ||
62 | + | ||
63 | + private void recalculatePartitions(List<ServiceInfo> otherServices, ServiceInfo currentService) { | ||
64 | + log.info("Recalculating partitions for SNMP transports"); | ||
65 | + List<ServiceInfo> snmpTransports = Stream.concat(otherServices.stream(), Stream.of(currentService)) | ||
66 | + .filter(service -> service.getTransportsList().contains(snmpTransportService.getName())) | ||
67 | + .sorted(Comparator.comparing(ServiceInfo::getServiceId)) | ||
68 | + .collect(Collectors.toList()); | ||
69 | + log.trace("Found SNMP transports: {}", snmpTransports); | ||
70 | + | ||
71 | + int previousCurrentTransportPartitionIndex = currentTransportPartitionIndex; | ||
72 | + int previousSnmpTransportsCount = snmpTransportsCount; | ||
73 | + | ||
74 | + if (!snmpTransports.isEmpty()) { | ||
75 | + for (int i = 0; i < snmpTransports.size(); i++) { | ||
76 | + if (snmpTransports.get(i).equals(currentService)) { | ||
77 | + currentTransportPartitionIndex = i; | ||
78 | + break; | ||
79 | + } | ||
80 | + } | ||
81 | + snmpTransportsCount = snmpTransports.size(); | ||
82 | + } | ||
83 | + | ||
84 | + if (snmpTransportsCount != previousSnmpTransportsCount || currentTransportPartitionIndex != previousCurrentTransportPartitionIndex) { | ||
85 | + log.info("SNMP transports partitions have changed: transports count = {}, current transport partition index = {}", snmpTransportsCount, currentTransportPartitionIndex); | ||
86 | + eventPublisher.publishEvent(new SnmpTransportListChangedEvent()); | ||
87 | + } else { | ||
88 | + log.info("SNMP transports partitions have not changed"); | ||
89 | + } | ||
90 | + } | ||
91 | + | ||
92 | +} |
common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java
renamed from
common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/SnmpSessionListener.java
@@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.transport.snmp.session; | 16 | +package org.thingsboard.server.transport.snmp.service; |
17 | 17 | ||
18 | import com.google.gson.JsonElement; | 18 | import com.google.gson.JsonElement; |
19 | import com.google.gson.JsonObject; | 19 | import com.google.gson.JsonObject; |
@@ -25,9 +25,16 @@ import lombok.extern.slf4j.Slf4j; | @@ -25,9 +25,16 @@ import lombok.extern.slf4j.Slf4j; | ||
25 | import org.snmp4j.PDU; | 25 | import org.snmp4j.PDU; |
26 | import org.snmp4j.Snmp; | 26 | import org.snmp4j.Snmp; |
27 | import org.snmp4j.event.ResponseEvent; | 27 | import org.snmp4j.event.ResponseEvent; |
28 | -import org.snmp4j.event.ResponseListener; | ||
29 | import org.snmp4j.smi.VariableBinding; | 28 | import org.snmp4j.smi.VariableBinding; |
29 | +import org.snmp4j.transport.DefaultUdpTransportMapping; | ||
30 | +import org.springframework.boot.context.event.ApplicationReadyEvent; | ||
31 | +import org.springframework.context.annotation.Lazy; | ||
32 | +import org.springframework.context.event.EventListener; | ||
33 | +import org.springframework.core.annotation.Order; | ||
34 | +import org.springframework.stereotype.Service; | ||
35 | +import org.thingsboard.common.util.ThingsBoardThreadFactory; | ||
30 | import org.thingsboard.server.common.data.DeviceTransportType; | 36 | import org.thingsboard.server.common.data.DeviceTransportType; |
37 | +import org.thingsboard.server.common.data.TbTransportService; | ||
31 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 38 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
32 | import org.thingsboard.server.common.data.kv.DataType; | 39 | import org.thingsboard.server.common.data.kv.DataType; |
33 | import org.thingsboard.server.common.transport.TransportContext; | 40 | import org.thingsboard.server.common.transport.TransportContext; |
@@ -39,27 +46,116 @@ import org.thingsboard.server.common.transport.auth.SessionInfoCreator; | @@ -39,27 +46,116 @@ import org.thingsboard.server.common.transport.auth.SessionInfoCreator; | ||
39 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | 46 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
40 | import org.thingsboard.server.gen.transport.TransportProtos; | 47 | import org.thingsboard.server.gen.transport.TransportProtos; |
41 | import org.thingsboard.server.transport.snmp.SnmpTransportContext; | 48 | import org.thingsboard.server.transport.snmp.SnmpTransportContext; |
49 | +import org.thingsboard.server.queue.util.TbSnmpTransportComponent; | ||
50 | +import org.thingsboard.server.transport.snmp.session.DeviceSessionContext; | ||
42 | 51 | ||
52 | +import javax.annotation.PreDestroy; | ||
53 | +import java.io.IOException; | ||
43 | import java.util.UUID; | 54 | import java.util.UUID; |
55 | +import java.util.concurrent.ExecutorService; | ||
56 | +import java.util.concurrent.Executors; | ||
57 | +import java.util.concurrent.ScheduledExecutorService; | ||
58 | +import java.util.concurrent.TimeUnit; | ||
44 | import java.util.function.Consumer; | 59 | import java.util.function.Consumer; |
45 | 60 | ||
61 | +@TbSnmpTransportComponent | ||
62 | +@Service | ||
46 | @Slf4j | 63 | @Slf4j |
47 | -@AllArgsConstructor | ||
48 | -public class SnmpSessionListener implements ResponseListener { | ||
49 | - | ||
50 | - @Getter | 64 | +public class SnmpTransportService implements TbTransportService { |
51 | private final SnmpTransportContext snmpTransportContext; | 65 | private final SnmpTransportContext snmpTransportContext; |
52 | 66 | ||
53 | @Getter | 67 | @Getter |
54 | - private final String token; | 68 | + private ExecutorService snmpCallbackExecutor; |
69 | + @Getter | ||
70 | + private Snmp snmp; | ||
71 | + private ScheduledExecutorService pollingExecutor; | ||
55 | 72 | ||
56 | - @Override | ||
57 | - public void onResponse(ResponseEvent event) { | ||
58 | - ((Snmp) event.getSource()).cancel(event.getRequest(), this); | ||
59 | - snmpTransportContext.getSnmpCallbackExecutor().submit(() -> processSnmpResponse(event)); | 73 | + public SnmpTransportService(@Lazy SnmpTransportContext snmpTransportContext) { |
74 | + this.snmpTransportContext = snmpTransportContext; | ||
60 | } | 75 | } |
61 | 76 | ||
62 | - private void processSnmpResponse(ResponseEvent event) { | 77 | + // @PostConstruct |
78 | + private void init() { | ||
79 | + log.info("Starting SNMP transport..."); | ||
80 | + pollingExecutor = Executors.newScheduledThreadPool(1, ThingsBoardThreadFactory.forName("snmp-polling")); | ||
81 | + //TODO: Set parallelism value in the config | ||
82 | + snmpCallbackExecutor = Executors.newWorkStealingPool(20); | ||
83 | + | ||
84 | + initializeSnmp(); | ||
85 | + | ||
86 | + log.info("SNMP transport started!"); | ||
87 | + } | ||
88 | + | ||
89 | + @PreDestroy | ||
90 | + public void shutdown() { | ||
91 | + log.info("Stopping SNMP transport!"); | ||
92 | + if (pollingExecutor != null) { | ||
93 | + pollingExecutor.shutdownNow(); | ||
94 | + } | ||
95 | + if (snmpCallbackExecutor != null) { | ||
96 | + snmpCallbackExecutor.shutdownNow(); | ||
97 | + } | ||
98 | + if (snmp != null) { | ||
99 | + try { | ||
100 | + snmp.close(); | ||
101 | + } catch (IOException e) { | ||
102 | + log.error(e.getMessage(), e); | ||
103 | + } | ||
104 | + } | ||
105 | + log.info("SNMP transport stopped!"); | ||
106 | + } | ||
107 | + | ||
108 | + @EventListener(ApplicationReadyEvent.class) | ||
109 | + @Order(value = 10) | ||
110 | + public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { | ||
111 | + log.info("Received application ready event. Starting SNMP polling."); | ||
112 | +// startPolling(); | ||
113 | + } | ||
114 | + | ||
115 | + private void initializeSnmp() { | ||
116 | + try { | ||
117 | + this.snmp = new Snmp(new DefaultUdpTransportMapping()); | ||
118 | + this.snmp.listen(); | ||
119 | + } catch (IOException e) { | ||
120 | + //TODO: what should be done if transport wasn't initialized? | ||
121 | + log.error(e.getMessage(), e); | ||
122 | + } | ||
123 | + } | ||
124 | + | ||
125 | + private void startPolling() { | ||
126 | + //TODO: Get poll period from configuration; | ||
127 | + int pollPeriodSeconds = 1; | ||
128 | + | ||
129 | + pollingExecutor.scheduleWithFixedDelay(() -> { | ||
130 | + snmpTransportContext.getSessions().forEach(this::executeSnmpRequest); | ||
131 | + }, 0, pollPeriodSeconds, TimeUnit.SECONDS); | ||
132 | + } | ||
133 | + | ||
134 | + private void executeSnmpRequest(DeviceSessionContext sessionContext) { | ||
135 | + long timeNow = System.currentTimeMillis(); | ||
136 | + long nextRequestExecutionTime = sessionContext.getPreviousRequestExecutedAt() + sessionContext.getProfileTransportConfiguration().getPollPeriodMs(); | ||
137 | + | ||
138 | + if (nextRequestExecutionTime < timeNow) { | ||
139 | + sessionContext.setPreviousRequestExecutedAt(timeNow); | ||
140 | + | ||
141 | + DeviceProfileId deviceProfileId = sessionContext.getDeviceProfile().getId(); | ||
142 | + snmpTransportContext.getProfilesPdus().get(deviceProfileId).forEach(pdu -> { | ||
143 | + try { | ||
144 | + log.debug("[{}] Sending SNMP message...", pdu.getRequestID()); | ||
145 | + snmp.send(pdu, sessionContext.getTarget(), deviceProfileId, sessionContext); | ||
146 | + } catch (IOException e) { | ||
147 | + log.error(e.getMessage(), e); | ||
148 | + } | ||
149 | + }); | ||
150 | + } | ||
151 | + } | ||
152 | + | ||
153 | + public void onNewDeviceResponse(ResponseEvent responseEvent, DeviceSessionContext sessionContext) { | ||
154 | + ((Snmp) responseEvent.getSource()).cancel(responseEvent.getRequest(), sessionContext); | ||
155 | + snmpTransportContext.getSnmpCallbackExecutor().submit(() -> processSnmpResponse(responseEvent, sessionContext)); | ||
156 | + } | ||
157 | + | ||
158 | + private void processSnmpResponse(ResponseEvent event, DeviceSessionContext sessionContext) { | ||
63 | PDU response = event.getResponse(); | 159 | PDU response = event.getResponse(); |
64 | if (event.getError() != null) { | 160 | if (event.getError() != null) { |
65 | log.warn("Response error: {}", event.getError().getMessage(), event.getError()); | 161 | log.warn("Response error: {}", event.getError().getMessage(), event.getError()); |
@@ -72,8 +168,8 @@ public class SnmpSessionListener implements ResponseListener { | @@ -72,8 +168,8 @@ public class SnmpSessionListener implements ResponseListener { | ||
72 | TransportService transportService = snmpTransportContext.getTransportService(); | 168 | TransportService transportService = snmpTransportContext.getTransportService(); |
73 | for (int i = 0; i < response.size(); i++) { | 169 | for (int i = 0; i < response.size(); i++) { |
74 | VariableBinding vb = response.get(i); | 170 | VariableBinding vb = response.get(i); |
75 | - snmpTransportContext.findAttributesMapping(deviceProfileId, vb.getOid()).ifPresent(kvMapping -> transportService.process(DeviceTransportType.DEFAULT, | ||
76 | - TransportProtos.ValidateDeviceTokenRequestMsg.newBuilder().setToken(token).build(), | 171 | + snmpTransportContext.getAttributesMapping(deviceProfileId, vb.getOid()).ifPresent(kvMapping -> transportService.process(DeviceTransportType.DEFAULT, |
172 | + TransportProtos.ValidateDeviceTokenRequestMsg.newBuilder().setToken(sessionContext.getToken()).build(), | ||
77 | new DeviceAuthCallback(snmpTransportContext, sessionInfo -> { | 173 | new DeviceAuthCallback(snmpTransportContext, sessionInfo -> { |
78 | try { | 174 | try { |
79 | transportService.process(sessionInfo, | 175 | transportService.process(sessionInfo, |
@@ -84,8 +180,8 @@ public class SnmpSessionListener implements ResponseListener { | @@ -84,8 +180,8 @@ public class SnmpSessionListener implements ResponseListener { | ||
84 | log.warn("Failed to process SNMP response: {}", e.getMessage(), e); | 180 | log.warn("Failed to process SNMP response: {}", e.getMessage(), e); |
85 | } | 181 | } |
86 | }))); | 182 | }))); |
87 | - snmpTransportContext.findTelemetryMapping(deviceProfileId, vb.getOid()).ifPresent(kvMapping -> transportService.process(DeviceTransportType.DEFAULT, | ||
88 | - TransportProtos.ValidateDeviceTokenRequestMsg.newBuilder().setToken(token).build(), | 183 | + snmpTransportContext.getTelemetryMapping(deviceProfileId, vb.getOid()).ifPresent(kvMapping -> transportService.process(DeviceTransportType.DEFAULT, |
184 | + TransportProtos.ValidateDeviceTokenRequestMsg.newBuilder().setToken(sessionContext.getToken()).build(), | ||
89 | new DeviceAuthCallback(snmpTransportContext, sessionInfo -> { | 185 | new DeviceAuthCallback(snmpTransportContext, sessionInfo -> { |
90 | try { | 186 | try { |
91 | transportService.process(sessionInfo, | 187 | transportService.process(sessionInfo, |
@@ -103,6 +199,14 @@ public class SnmpSessionListener implements ResponseListener { | @@ -103,6 +199,14 @@ public class SnmpSessionListener implements ResponseListener { | ||
103 | } | 199 | } |
104 | } | 200 | } |
105 | 201 | ||
202 | + private void reportActivity(TransportProtos.SessionInfoProto sessionInfo) { | ||
203 | + snmpTransportContext.getTransportService().process(sessionInfo, TransportProtos.SubscriptionInfoProto.newBuilder() | ||
204 | + .setAttributeSubscription(false) | ||
205 | + .setRpcSubscription(false) | ||
206 | + .setLastActivityTime(System.currentTimeMillis()) | ||
207 | + .build(), TransportServiceCallback.EMPTY); | ||
208 | + } | ||
209 | + | ||
106 | private TransportProtos.PostAttributeMsg convertToPostAttributes(String keyName, DataType dataType, String payload) throws AdaptorException { | 210 | private TransportProtos.PostAttributeMsg convertToPostAttributes(String keyName, DataType dataType, String payload) throws AdaptorException { |
107 | try { | 211 | try { |
108 | return JsonConverter.convertToAttributesProto(getKvJson(keyName, dataType, payload)); | 212 | return JsonConverter.convertToAttributesProto(getKvJson(keyName, dataType, payload)); |
@@ -143,14 +247,6 @@ public class SnmpSessionListener implements ResponseListener { | @@ -143,14 +247,6 @@ public class SnmpSessionListener implements ResponseListener { | ||
143 | return new JsonParser().parse(result.toString()); | 247 | return new JsonParser().parse(result.toString()); |
144 | } | 248 | } |
145 | 249 | ||
146 | - private void reportActivity(TransportProtos.SessionInfoProto sessionInfo) { | ||
147 | - snmpTransportContext.getTransportService().process(sessionInfo, TransportProtos.SubscriptionInfoProto.newBuilder() | ||
148 | - .setAttributeSubscription(false) | ||
149 | - .setRpcSubscription(false) | ||
150 | - .setLastActivityTime(System.currentTimeMillis()) | ||
151 | - .build(), TransportServiceCallback.EMPTY); | ||
152 | - } | ||
153 | - | ||
154 | @AllArgsConstructor | 250 | @AllArgsConstructor |
155 | private static class DeviceAuthCallback implements TransportServiceCallback<ValidateDeviceCredentialsResponse> { | 251 | private static class DeviceAuthCallback implements TransportServiceCallback<ValidateDeviceCredentialsResponse> { |
156 | private final TransportContext transportContext; | 252 | private final TransportContext transportContext; |
@@ -170,4 +266,9 @@ public class SnmpSessionListener implements ResponseListener { | @@ -170,4 +266,9 @@ public class SnmpSessionListener implements ResponseListener { | ||
170 | log.warn("Failed to process device auth", e); | 266 | log.warn("Failed to process device auth", e); |
171 | } | 267 | } |
172 | } | 268 | } |
269 | + | ||
270 | + @Override | ||
271 | + public String getName() { | ||
272 | + return "SNMP"; | ||
273 | + } | ||
173 | } | 274 | } |
common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java
renamed from
common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionCtx.java
@@ -19,21 +19,18 @@ import lombok.Getter; | @@ -19,21 +19,18 @@ import lombok.Getter; | ||
19 | import lombok.Setter; | 19 | import lombok.Setter; |
20 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
21 | import org.snmp4j.CommunityTarget; | 21 | import org.snmp4j.CommunityTarget; |
22 | -import org.snmp4j.Snmp; | ||
23 | import org.snmp4j.Target; | 22 | import org.snmp4j.Target; |
23 | +import org.snmp4j.event.ResponseEvent; | ||
24 | +import org.snmp4j.event.ResponseListener; | ||
24 | import org.snmp4j.mp.SnmpConstants; | 25 | import org.snmp4j.mp.SnmpConstants; |
25 | import org.snmp4j.smi.GenericAddress; | 26 | import org.snmp4j.smi.GenericAddress; |
26 | import org.snmp4j.smi.OctetString; | 27 | import org.snmp4j.smi.OctetString; |
27 | import org.thingsboard.server.common.data.Device; | 28 | import org.thingsboard.server.common.data.Device; |
28 | import org.thingsboard.server.common.data.DeviceProfile; | 29 | import org.thingsboard.server.common.data.DeviceProfile; |
29 | -import org.thingsboard.server.common.data.DeviceTransportType; | ||
30 | import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration; | 30 | import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration; |
31 | import org.thingsboard.server.common.data.device.profile.SnmpProfileTransportConfiguration; | 31 | import org.thingsboard.server.common.data.device.profile.SnmpProfileTransportConfiguration; |
32 | import org.thingsboard.server.common.data.id.DeviceId; | 32 | import org.thingsboard.server.common.data.id.DeviceId; |
33 | import org.thingsboard.server.common.transport.SessionMsgListener; | 33 | import org.thingsboard.server.common.transport.SessionMsgListener; |
34 | -import org.thingsboard.server.common.transport.TransportServiceCallback; | ||
35 | -import org.thingsboard.server.common.transport.auth.SessionInfoCreator; | ||
36 | -import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | ||
37 | import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; | 34 | import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; |
38 | import org.thingsboard.server.gen.transport.TransportProtos; | 35 | import org.thingsboard.server.gen.transport.TransportProtos; |
39 | import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; | 36 | import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; |
@@ -42,154 +39,92 @@ import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotifica | @@ -42,154 +39,92 @@ import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotifica | ||
42 | import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMsg; | 39 | import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMsg; |
43 | import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg; | 40 | import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg; |
44 | import org.thingsboard.server.transport.snmp.SnmpTransportContext; | 41 | import org.thingsboard.server.transport.snmp.SnmpTransportContext; |
42 | +import org.thingsboard.server.transport.snmp.service.SnmpTransportService; | ||
45 | 43 | ||
46 | -import java.io.IOException; | ||
47 | -import java.util.Optional; | ||
48 | import java.util.UUID; | 44 | import java.util.UUID; |
49 | import java.util.concurrent.atomic.AtomicInteger; | 45 | import java.util.concurrent.atomic.AtomicInteger; |
50 | -import java.util.function.Consumer; | ||
51 | 46 | ||
52 | @Slf4j | 47 | @Slf4j |
53 | -public class DeviceSessionCtx extends DeviceAwareSessionContext implements SessionMsgListener { | ||
54 | - private final AtomicInteger msgIdSeq = new AtomicInteger(0); | ||
55 | - | 48 | +public class DeviceSessionContext extends DeviceAwareSessionContext implements SessionMsgListener, ResponseListener { |
56 | @Getter | 49 | @Getter |
57 | - @Setter | ||
58 | - private SnmpDeviceTransportConfiguration deviceTransportConfig; | 50 | + private Target target; |
51 | + private final String token; | ||
59 | @Getter | 52 | @Getter |
60 | @Setter | 53 | @Setter |
61 | - private SnmpSessionListener snmpSessionListener; | 54 | + private SnmpProfileTransportConfiguration profileTransportConfiguration; |
62 | @Getter | 55 | @Getter |
63 | @Setter | 56 | @Setter |
64 | - private Target target; | 57 | + private SnmpDeviceTransportConfiguration deviceTransportConfiguration; |
65 | @Getter | 58 | @Getter |
66 | - @Setter | ||
67 | - private volatile TransportProtos.SessionInfoProto sessionInfo; | 59 | + private final Device device; |
60 | + | ||
61 | + private final SnmpTransportContext snmpTransportContext; | ||
62 | + private final SnmpTransportService snmpTransportService; | ||
68 | 63 | ||
69 | - private Snmp snmp; | ||
70 | - private SnmpProfileTransportConfiguration snmpProfileTransportConfiguration; | 64 | + @Getter |
65 | + @Setter | ||
71 | private long previousRequestExecutedAt = 0; | 66 | private long previousRequestExecutedAt = 0; |
67 | + private final AtomicInteger msgIdSeq = new AtomicInteger(0); | ||
68 | + private boolean isActive = true; | ||
72 | 69 | ||
73 | - public DeviceSessionCtx(SnmpTransportContext transportContext, String token, SnmpDeviceTransportConfiguration deviceTransportConfig, | ||
74 | - Snmp snmp, DeviceId deviceId, DeviceProfile deviceProfile) { | 70 | + public DeviceSessionContext(Device device, DeviceProfile deviceProfile, |
71 | + String token, SnmpDeviceTransportConfiguration deviceTransportConfiguration, | ||
72 | + SnmpTransportContext snmpTransportContext, SnmpTransportService snmpTransportService) { | ||
75 | super(UUID.randomUUID()); | 73 | super(UUID.randomUUID()); |
76 | - this.snmpSessionListener = new SnmpSessionListener(transportContext, token); | ||
77 | - super.setDeviceId(deviceId); | 74 | + super.setDeviceId(device.getId()); |
78 | super.setDeviceProfile(deviceProfile); | 75 | super.setDeviceProfile(deviceProfile); |
79 | - //TODO: What should be done if snmp null? | ||
80 | - if (snmp != null) { | ||
81 | - this.snmp = snmp; | ||
82 | - } | ||
83 | - this.snmpProfileTransportConfiguration = (SnmpProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration(); | ||
84 | - initTarget(this.snmpProfileTransportConfiguration, deviceTransportConfig); | ||
85 | - } | 76 | + this.device = device; |
86 | 77 | ||
87 | - @Override | ||
88 | - public int nextMsgId() { | ||
89 | - return msgIdSeq.incrementAndGet(); | ||
90 | - } | 78 | + this.token = token; |
79 | + this.snmpTransportContext = snmpTransportContext; | ||
80 | + this.snmpTransportService = snmpTransportService; | ||
91 | 81 | ||
92 | - @Override | ||
93 | - public void onGetAttributesResponse(GetAttributeResponseMsg getAttributesResponse) { | ||
94 | - } | ||
95 | - | ||
96 | - @Override | ||
97 | - public void onAttributeUpdate(AttributeUpdateNotificationMsg attributeUpdateNotification) { | ||
98 | - } | ||
99 | - | ||
100 | - @Override | ||
101 | - public void onRemoteSessionCloseCommand(SessionCloseNotificationProto sessionCloseNotification) { | ||
102 | - } | ||
103 | - | ||
104 | - @Override | ||
105 | - public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { | ||
106 | - } | 82 | + this.profileTransportConfiguration = (SnmpProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration(); |
83 | + this.deviceTransportConfiguration = deviceTransportConfiguration; | ||
107 | 84 | ||
108 | - @Override | ||
109 | - public void onToServerRpcResponse(ToServerRpcResponseMsg toServerResponse) { | 85 | + initTarget(this.profileTransportConfiguration, this.deviceTransportConfiguration); |
110 | } | 86 | } |
111 | 87 | ||
112 | @Override | 88 | @Override |
113 | public void onDeviceProfileUpdate(TransportProtos.SessionInfoProto newSessionInfo, DeviceProfile deviceProfile) { | 89 | public void onDeviceProfileUpdate(TransportProtos.SessionInfoProto newSessionInfo, DeviceProfile deviceProfile) { |
114 | - super.onDeviceProfileUpdate(sessionInfo, deviceProfile); | ||
115 | - if (DeviceTransportType.SNMP.equals(deviceProfile.getTransportType())) { | ||
116 | - snmpProfileTransportConfiguration = (SnmpProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration(); | ||
117 | - snmpSessionListener.getSnmpTransportContext().getProfileTransportConfig().put( | ||
118 | - deviceProfile.getId(), | ||
119 | - snmpProfileTransportConfiguration); | ||
120 | - snmpSessionListener.getSnmpTransportContext().updatePduListPerProfile(deviceProfile.getId(), snmpProfileTransportConfiguration); | ||
121 | - } else { | ||
122 | - //TODO: should the context be removed from the map? | 90 | + super.onDeviceProfileUpdate(newSessionInfo, deviceProfile); |
91 | + if (isActive) { | ||
92 | + snmpTransportContext.onDeviceProfileUpdated(deviceProfile, this); | ||
123 | } | 93 | } |
124 | } | 94 | } |
125 | 95 | ||
126 | @Override | 96 | @Override |
127 | - public void onDeviceUpdate(TransportProtos.SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) { | ||
128 | - super.onDeviceUpdate(sessionInfo, device, deviceProfileOpt); | ||
129 | - if (super.getDeviceProfile() != null && DeviceTransportType.SNMP.equals(super.getDeviceProfile().getTransportType())) { | ||
130 | - snmpSessionListener.getSnmpTransportContext().updateDeviceSessionCtx(device, deviceProfile, null); | ||
131 | - SnmpProfileTransportConfiguration profileTransportConfig = (SnmpProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration(); | ||
132 | - SnmpDeviceTransportConfiguration deviceTransportConfig = (SnmpDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration(); | ||
133 | - initTarget(profileTransportConfig, deviceTransportConfig); | ||
134 | - } else { | ||
135 | - //TODO: should the context be removed from the map? | ||
136 | - } | ||
137 | - } | ||
138 | - | ||
139 | - public void createSessionInfo(Consumer<TransportProtos.SessionInfoProto> registerSession) { | ||
140 | - getSnmpSessionListener().getSnmpTransportContext().getTransportService().process(DeviceTransportType.SNMP, | ||
141 | - TransportProtos.ValidateDeviceTokenRequestMsg.newBuilder().setToken(getSnmpSessionListener().getToken()).build(), | ||
142 | - new TransportServiceCallback<ValidateDeviceCredentialsResponse>() { | ||
143 | - @Override | ||
144 | - public void onSuccess(ValidateDeviceCredentialsResponse msg) { | ||
145 | - if (msg.hasDeviceInfo()) { | ||
146 | - sessionInfo = SessionInfoCreator.create(msg, getSnmpSessionListener().getSnmpTransportContext(), UUID.randomUUID()); | ||
147 | - registerSession.accept(sessionInfo); | ||
148 | - setDeviceInfo(msg.getDeviceInfo()); | ||
149 | - } else { | ||
150 | - log.warn("[{}] Failed to process device auth", getDeviceId()); | ||
151 | - } | ||
152 | - } | ||
153 | - | ||
154 | - @Override | ||
155 | - public void onError(Throwable e) { | ||
156 | - log.warn("[{}] Failed to process device auth", getDeviceId(), e); | ||
157 | - } | ||
158 | - }); | 97 | + public void onDeviceDeleted(DeviceId deviceId) { |
98 | + snmpTransportContext.onDeviceDeleted(this); | ||
159 | } | 99 | } |
160 | 100 | ||
161 | - public void executeSnmpRequest() { | ||
162 | - long timeNow = System.currentTimeMillis(); | ||
163 | - long nextRequestExecutionTime = previousRequestExecutedAt + snmpProfileTransportConfiguration.getPoolPeriodMs(); | ||
164 | - if (nextRequestExecutionTime < timeNow) { | ||
165 | - previousRequestExecutedAt = timeNow; | ||
166 | - | ||
167 | - snmpSessionListener.getSnmpTransportContext().getPdusPerProfile().get(deviceProfile.getId()).forEach(pdu -> { | ||
168 | - try { | ||
169 | - log.debug("[{}] Sending SNMP message...", pdu.getRequestID()); | ||
170 | - snmp.send(pdu, | ||
171 | - target, | ||
172 | - deviceProfile.getId(), | ||
173 | - snmpSessionListener); | ||
174 | - } catch (IOException e) { | ||
175 | - log.error(e.getMessage(), e); | ||
176 | - } | ||
177 | - }); | 101 | + @Override |
102 | + public void onResponse(ResponseEvent event) { | ||
103 | + if (isActive) { | ||
104 | + snmpTransportService.onNewDeviceResponse(event, this); | ||
178 | } | 105 | } |
179 | } | 106 | } |
180 | 107 | ||
181 | - private void initTarget(SnmpProfileTransportConfiguration profileTransportConfig, SnmpDeviceTransportConfiguration deviceTransportConfig) { | ||
182 | - this.deviceTransportConfig = deviceTransportConfig; | 108 | + public void initTarget(SnmpProfileTransportConfiguration profileTransportConfig, SnmpDeviceTransportConfiguration deviceTransportConfig) { |
109 | + log.trace("Initializing target for SNMP session of device {}", device); | ||
183 | CommunityTarget communityTarget = new CommunityTarget(); | 110 | CommunityTarget communityTarget = new CommunityTarget(); |
184 | - communityTarget.setAddress(GenericAddress.parse(GenericAddress.TYPE_UDP + ":" + this.deviceTransportConfig.getAddress() + "/" + this.deviceTransportConfig.getPort())); | ||
185 | - communityTarget.setVersion(getSnmpVersion(this.deviceTransportConfig.getProtocolVersion())); | ||
186 | - communityTarget.setCommunity(new OctetString(this.deviceTransportConfig.getCommunity())); | 111 | + communityTarget.setAddress(GenericAddress.parse(GenericAddress.TYPE_UDP + ":" + deviceTransportConfig.getAddress() + "/" + deviceTransportConfig.getPort())); |
112 | + communityTarget.setVersion(getSnmpVersion(deviceTransportConfig.getProtocolVersion())); | ||
113 | + communityTarget.setCommunity(new OctetString(deviceTransportConfig.getCommunity())); | ||
187 | communityTarget.setTimeout(profileTransportConfig.getTimeoutMs()); | 114 | communityTarget.setTimeout(profileTransportConfig.getTimeoutMs()); |
188 | communityTarget.setRetries(profileTransportConfig.getRetries()); | 115 | communityTarget.setRetries(profileTransportConfig.getRetries()); |
189 | this.target = communityTarget; | 116 | this.target = communityTarget; |
190 | log.info("SNMP target initialized: {}", this.target); | 117 | log.info("SNMP target initialized: {}", this.target); |
191 | } | 118 | } |
192 | 119 | ||
120 | + public void close() { | ||
121 | + isActive = false; | ||
122 | + } | ||
123 | + | ||
124 | + public String getToken() { | ||
125 | + return token; | ||
126 | + } | ||
127 | + | ||
193 | //TODO: replace with enum, wtih preliminary discussion of type version in config (string or integer) | 128 | //TODO: replace with enum, wtih preliminary discussion of type version in config (string or integer) |
194 | private int getSnmpVersion(String configSnmpVersion) { | 129 | private int getSnmpVersion(String configSnmpVersion) { |
195 | switch (configSnmpVersion) { | 130 | switch (configSnmpVersion) { |
@@ -203,4 +138,29 @@ public class DeviceSessionCtx extends DeviceAwareSessionContext implements Sessi | @@ -203,4 +138,29 @@ public class DeviceSessionCtx extends DeviceAwareSessionContext implements Sessi | ||
203 | return -1; | 138 | return -1; |
204 | } | 139 | } |
205 | } | 140 | } |
141 | + | ||
142 | + @Override | ||
143 | + public int nextMsgId() { | ||
144 | + return msgIdSeq.incrementAndGet(); | ||
145 | + } | ||
146 | + | ||
147 | + @Override | ||
148 | + public void onGetAttributesResponse(GetAttributeResponseMsg getAttributesResponse) { | ||
149 | + } | ||
150 | + | ||
151 | + @Override | ||
152 | + public void onAttributeUpdate(AttributeUpdateNotificationMsg attributeUpdateNotification) { | ||
153 | + } | ||
154 | + | ||
155 | + @Override | ||
156 | + public void onRemoteSessionCloseCommand(SessionCloseNotificationProto sessionCloseNotification) { | ||
157 | + } | ||
158 | + | ||
159 | + @Override | ||
160 | + public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { | ||
161 | + } | ||
162 | + | ||
163 | + @Override | ||
164 | + public void onToServerRpcResponse(ToServerRpcResponseMsg toServerResponse) { | ||
165 | + } | ||
206 | } | 166 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2021 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.common.transport; | ||
17 | + | ||
18 | +import lombok.Getter; | ||
19 | +import org.thingsboard.server.common.data.Device; | ||
20 | + | ||
21 | +@Getter | ||
22 | +public class DeviceUpdatedEvent { | ||
23 | + private final Device device; | ||
24 | + | ||
25 | + public DeviceUpdatedEvent(Device device) { | ||
26 | + this.device = device; | ||
27 | + } | ||
28 | +} |
@@ -17,6 +17,7 @@ package org.thingsboard.server.common.transport; | @@ -17,6 +17,7 @@ package org.thingsboard.server.common.transport; | ||
17 | 17 | ||
18 | import org.thingsboard.server.common.data.Device; | 18 | import org.thingsboard.server.common.data.Device; |
19 | import org.thingsboard.server.common.data.DeviceProfile; | 19 | import org.thingsboard.server.common.data.DeviceProfile; |
20 | +import org.thingsboard.server.common.data.id.DeviceId; | ||
20 | import org.thingsboard.server.gen.transport.TransportProtos; | 21 | import org.thingsboard.server.gen.transport.TransportProtos; |
21 | import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg; | 22 | import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg; |
22 | import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; | 23 | import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; |
@@ -49,4 +50,7 @@ public interface SessionMsgListener { | @@ -49,4 +50,7 @@ public interface SessionMsgListener { | ||
49 | 50 | ||
50 | default void onDeviceUpdate(TransportProtos.SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) { | 51 | default void onDeviceUpdate(TransportProtos.SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) { |
51 | } | 52 | } |
53 | + | ||
54 | + default void onDeviceDeleted(DeviceId deviceId) { | ||
55 | + } | ||
52 | } | 56 | } |
@@ -21,6 +21,7 @@ import lombok.Getter; | @@ -21,6 +21,7 @@ import lombok.Getter; | ||
21 | import lombok.extern.slf4j.Slf4j; | 21 | import lombok.extern.slf4j.Slf4j; |
22 | import org.springframework.beans.factory.annotation.Autowired; | 22 | import org.springframework.beans.factory.annotation.Autowired; |
23 | import org.springframework.stereotype.Service; | 23 | import org.springframework.stereotype.Service; |
24 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
24 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; | 25 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; |
25 | import org.thingsboard.server.queue.scheduler.SchedulerComponent; | 26 | import org.thingsboard.server.queue.scheduler.SchedulerComponent; |
26 | import org.thingsboard.server.queue.util.TbTransportComponent; | 27 | import org.thingsboard.server.queue.util.TbTransportComponent; |
@@ -22,11 +22,17 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes | @@ -22,11 +22,17 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes | ||
22 | import org.thingsboard.server.common.transport.service.SessionMetaData; | 22 | import org.thingsboard.server.common.transport.service.SessionMetaData; |
23 | import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; | 23 | import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; |
24 | import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg; | 24 | import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg; |
25 | +import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceCredentialsRequestMsg; | ||
26 | +import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceCredentialsResponseMsg; | ||
27 | +import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceRequestMsg; | ||
28 | +import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceResponseMsg; | ||
25 | import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg; | 29 | import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg; |
26 | import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg; | 30 | import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg; |
27 | import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; | 31 | import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; |
28 | import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesRequestMsg; | 32 | import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesRequestMsg; |
29 | import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesResponseMsg; | 33 | import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesResponseMsg; |
34 | +import org.thingsboard.server.gen.transport.TransportProtos.GetSnmpDevicesRequestMsg; | ||
35 | +import org.thingsboard.server.gen.transport.TransportProtos.GetSnmpDevicesResponseMsg; | ||
30 | import org.thingsboard.server.gen.transport.TransportProtos.LwM2MRequestMsg; | 36 | import org.thingsboard.server.gen.transport.TransportProtos.LwM2MRequestMsg; |
31 | import org.thingsboard.server.gen.transport.TransportProtos.LwM2MResponseMsg; | 37 | import org.thingsboard.server.gen.transport.TransportProtos.LwM2MResponseMsg; |
32 | import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; | 38 | import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; |
@@ -55,6 +61,12 @@ public interface TransportService { | @@ -55,6 +61,12 @@ public interface TransportService { | ||
55 | 61 | ||
56 | GetResourcesResponseMsg getResources(GetResourcesRequestMsg msg); | 62 | GetResourcesResponseMsg getResources(GetResourcesRequestMsg msg); |
57 | 63 | ||
64 | + GetSnmpDevicesResponseMsg getSnmpDevicesIds(GetSnmpDevicesRequestMsg requestMsg); | ||
65 | + | ||
66 | + GetDeviceResponseMsg getDevice(GetDeviceRequestMsg requestMsg); | ||
67 | + | ||
68 | + GetDeviceCredentialsResponseMsg getDeviceCredentials(GetDeviceCredentialsRequestMsg requestMsg); | ||
69 | + | ||
58 | void process(DeviceTransportType transportType, ValidateDeviceTokenRequestMsg msg, | 70 | void process(DeviceTransportType transportType, ValidateDeviceTokenRequestMsg msg, |
59 | TransportServiceCallback<ValidateDeviceCredentialsResponse> callback); | 71 | TransportServiceCallback<ValidateDeviceCredentialsResponse> callback); |
60 | 72 |
@@ -112,8 +112,8 @@ public class DefaultTransportDeviceProfileCache implements TransportDeviceProfil | @@ -112,8 +112,8 @@ public class DefaultTransportDeviceProfileCache implements TransportDeviceProfil | ||
112 | profile = profileOpt.get(); | 112 | profile = profileOpt.get(); |
113 | this.put(profile); | 113 | this.put(profile); |
114 | } else { | 114 | } else { |
115 | - log.warn("[{}] Can't device profile: {}", id, entityProfileMsg.getData()); | ||
116 | - throw new RuntimeException("Can't device profile!"); | 115 | + log.warn("[{}] Can't find device profile: {}", id, entityProfileMsg.getData()); |
116 | + throw new RuntimeException("Can't find device profile!"); | ||
117 | } | 117 | } |
118 | } finally { | 118 | } finally { |
119 | deviceProfileFetchLock.unlock(); | 119 | deviceProfileFetchLock.unlock(); |
@@ -23,6 +23,7 @@ import com.google.gson.JsonObject; | @@ -23,6 +23,7 @@ import com.google.gson.JsonObject; | ||
23 | import com.google.protobuf.ByteString; | 23 | import com.google.protobuf.ByteString; |
24 | import lombok.extern.slf4j.Slf4j; | 24 | import lombok.extern.slf4j.Slf4j; |
25 | import org.springframework.beans.factory.annotation.Value; | 25 | import org.springframework.beans.factory.annotation.Value; |
26 | +import org.springframework.context.ApplicationEventPublisher; | ||
26 | import org.springframework.stereotype.Service; | 27 | import org.springframework.stereotype.Service; |
27 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 28 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
28 | import org.thingsboard.server.common.data.ApiUsageRecordKey; | 29 | import org.thingsboard.server.common.data.ApiUsageRecordKey; |
@@ -47,6 +48,7 @@ import org.thingsboard.server.common.msg.tools.TbRateLimitsException; | @@ -47,6 +48,7 @@ import org.thingsboard.server.common.msg.tools.TbRateLimitsException; | ||
47 | import org.thingsboard.server.common.stats.MessagesStats; | 48 | import org.thingsboard.server.common.stats.MessagesStats; |
48 | import org.thingsboard.server.common.stats.StatsFactory; | 49 | import org.thingsboard.server.common.stats.StatsFactory; |
49 | import org.thingsboard.server.common.stats.StatsType; | 50 | import org.thingsboard.server.common.stats.StatsType; |
51 | +import org.thingsboard.server.common.transport.DeviceUpdatedEvent; | ||
50 | import org.thingsboard.server.common.transport.SessionMsgListener; | 52 | import org.thingsboard.server.common.transport.SessionMsgListener; |
51 | import org.thingsboard.server.common.transport.TransportDeviceProfileCache; | 53 | import org.thingsboard.server.common.transport.TransportDeviceProfileCache; |
52 | import org.thingsboard.server.common.transport.TransportService; | 54 | import org.thingsboard.server.common.transport.TransportService; |
@@ -61,7 +63,6 @@ import org.thingsboard.server.common.transport.util.JsonUtils; | @@ -61,7 +63,6 @@ import org.thingsboard.server.common.transport.util.JsonUtils; | ||
61 | import org.thingsboard.server.gen.transport.TransportProtos; | 63 | import org.thingsboard.server.gen.transport.TransportProtos; |
62 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; | 64 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; |
63 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; | 65 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; |
64 | -import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; | ||
65 | import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; | 66 | import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; |
66 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; | 67 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; |
67 | import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; | 68 | import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; |
@@ -131,6 +132,7 @@ public class DefaultTransportService implements TransportService { | @@ -131,6 +132,7 @@ public class DefaultTransportService implements TransportService { | ||
131 | private final TransportRateLimitService rateLimitService; | 132 | private final TransportRateLimitService rateLimitService; |
132 | private final DataDecodingEncodingService dataDecodingEncodingService; | 133 | private final DataDecodingEncodingService dataDecodingEncodingService; |
133 | private final SchedulerComponent scheduler; | 134 | private final SchedulerComponent scheduler; |
135 | + private final ApplicationEventPublisher eventPublisher; | ||
134 | 136 | ||
135 | protected TbQueueRequestTemplate<TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> transportApiRequestTemplate; | 137 | protected TbQueueRequestTemplate<TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> transportApiRequestTemplate; |
136 | protected TbQueueProducer<TbProtoQueueMsg<ToRuleEngineMsg>> ruleEngineMsgProducer; | 138 | protected TbQueueProducer<TbProtoQueueMsg<ToRuleEngineMsg>> ruleEngineMsgProducer; |
@@ -157,7 +159,8 @@ public class DefaultTransportService implements TransportService { | @@ -157,7 +159,8 @@ public class DefaultTransportService implements TransportService { | ||
157 | TransportDeviceProfileCache deviceProfileCache, | 159 | TransportDeviceProfileCache deviceProfileCache, |
158 | TransportTenantProfileCache tenantProfileCache, | 160 | TransportTenantProfileCache tenantProfileCache, |
159 | TbApiUsageClient apiUsageClient, TransportRateLimitService rateLimitService, | 161 | TbApiUsageClient apiUsageClient, TransportRateLimitService rateLimitService, |
160 | - DataDecodingEncodingService dataDecodingEncodingService, SchedulerComponent scheduler) { | 162 | + DataDecodingEncodingService dataDecodingEncodingService, SchedulerComponent scheduler, |
163 | + ApplicationEventPublisher eventPublisher) { | ||
161 | this.serviceInfoProvider = serviceInfoProvider; | 164 | this.serviceInfoProvider = serviceInfoProvider; |
162 | this.queueProvider = queueProvider; | 165 | this.queueProvider = queueProvider; |
163 | this.producerProvider = producerProvider; | 166 | this.producerProvider = producerProvider; |
@@ -169,6 +172,7 @@ public class DefaultTransportService implements TransportService { | @@ -169,6 +172,7 @@ public class DefaultTransportService implements TransportService { | ||
169 | this.rateLimitService = rateLimitService; | 172 | this.rateLimitService = rateLimitService; |
170 | this.dataDecodingEncodingService = dataDecodingEncodingService; | 173 | this.dataDecodingEncodingService = dataDecodingEncodingService; |
171 | this.scheduler = scheduler; | 174 | this.scheduler = scheduler; |
175 | + this.eventPublisher = eventPublisher; | ||
172 | } | 176 | } |
173 | 177 | ||
174 | @PostConstruct | 178 | @PostConstruct |
@@ -267,6 +271,58 @@ public class DefaultTransportService implements TransportService { | @@ -267,6 +271,58 @@ public class DefaultTransportService implements TransportService { | ||
267 | } | 271 | } |
268 | 272 | ||
269 | @Override | 273 | @Override |
274 | + public TransportProtos.GetSnmpDevicesResponseMsg getSnmpDevicesIds(TransportProtos.GetSnmpDevicesRequestMsg requestMsg) { | ||
275 | + TbProtoQueueMsg<TransportProtos.TransportApiRequestMsg> protoMsg = new TbProtoQueueMsg<>( | ||
276 | + UUID.randomUUID(), TransportProtos.TransportApiRequestMsg.newBuilder() | ||
277 | + .setSnmpDevicesRequestMsg(requestMsg) | ||
278 | + .build() | ||
279 | + ); | ||
280 | + | ||
281 | + try { | ||
282 | + TbProtoQueueMsg<TransportApiResponseMsg> response = transportApiRequestTemplate.send(protoMsg).get(); | ||
283 | + return response.getValue().getSnmpDevicesResponseMsg(); | ||
284 | + } catch (InterruptedException | ExecutionException e) { | ||
285 | + throw new RuntimeException(e); | ||
286 | + } | ||
287 | + } | ||
288 | + | ||
289 | + @Override | ||
290 | + public TransportProtos.GetDeviceResponseMsg getDevice(TransportProtos.GetDeviceRequestMsg requestMsg) { | ||
291 | + TbProtoQueueMsg<TransportApiRequestMsg> protoMsg = new TbProtoQueueMsg<>( | ||
292 | + UUID.randomUUID(), TransportProtos.TransportApiRequestMsg.newBuilder() | ||
293 | + .setDeviceRequestMsg(requestMsg) | ||
294 | + .build() | ||
295 | + ); | ||
296 | + | ||
297 | + try { | ||
298 | + TransportApiResponseMsg response = transportApiRequestTemplate.send(protoMsg).get().getValue(); | ||
299 | + if (response.hasDeviceResponseMsg()) { | ||
300 | + return response.getDeviceResponseMsg(); | ||
301 | + } else { | ||
302 | + return null; | ||
303 | + } | ||
304 | + } catch (InterruptedException | ExecutionException e) { | ||
305 | + throw new RuntimeException(e); | ||
306 | + } | ||
307 | + } | ||
308 | + | ||
309 | + @Override | ||
310 | + public TransportProtos.GetDeviceCredentialsResponseMsg getDeviceCredentials(TransportProtos.GetDeviceCredentialsRequestMsg requestMsg) { | ||
311 | + TbProtoQueueMsg<TransportApiRequestMsg> protoMsg = new TbProtoQueueMsg<>( | ||
312 | + UUID.randomUUID(), TransportProtos.TransportApiRequestMsg.newBuilder() | ||
313 | + .setDeviceCredentialsRequestMsg(requestMsg) | ||
314 | + .build() | ||
315 | + ); | ||
316 | + | ||
317 | + try { | ||
318 | + TbProtoQueueMsg<TransportApiResponseMsg> response = transportApiRequestTemplate.send(protoMsg).get(); | ||
319 | + return response.getValue().getDeviceCredentialsResponseMsg(); | ||
320 | + } catch (InterruptedException | ExecutionException e) { | ||
321 | + throw new RuntimeException(e); | ||
322 | + } | ||
323 | + } | ||
324 | + | ||
325 | + @Override | ||
270 | public void process(DeviceTransportType transportType, TransportProtos.ValidateDeviceTokenRequestMsg msg, | 326 | public void process(DeviceTransportType transportType, TransportProtos.ValidateDeviceTokenRequestMsg msg, |
271 | TransportServiceCallback<ValidateDeviceCredentialsResponse> callback) { | 327 | TransportServiceCallback<ValidateDeviceCredentialsResponse> callback) { |
272 | log.trace("Processing msg: {}", msg); | 328 | log.trace("Processing msg: {}", msg); |
@@ -685,7 +741,10 @@ public class DefaultTransportService implements TransportService { | @@ -685,7 +741,10 @@ public class DefaultTransportService implements TransportService { | ||
685 | } | 741 | } |
686 | } else if (EntityType.DEVICE.equals(entityType)) { | 742 | } else if (EntityType.DEVICE.equals(entityType)) { |
687 | Optional<Device> deviceOpt = dataDecodingEncodingService.decode(msg.getData().toByteArray()); | 743 | Optional<Device> deviceOpt = dataDecodingEncodingService.decode(msg.getData().toByteArray()); |
688 | - deviceOpt.ifPresent(this::onDeviceUpdate); | 744 | + deviceOpt.ifPresent(device -> { |
745 | + onDeviceUpdate(device); | ||
746 | + eventPublisher.publishEvent(new DeviceUpdatedEvent(device)); | ||
747 | + }); | ||
689 | } | 748 | } |
690 | } else if (toSessionMsg.hasEntityDeleteMsg()) { | 749 | } else if (toSessionMsg.hasEntityDeleteMsg()) { |
691 | TransportProtos.EntityDeleteMsg msg = toSessionMsg.getEntityDeleteMsg(); | 750 | TransportProtos.EntityDeleteMsg msg = toSessionMsg.getEntityDeleteMsg(); |
@@ -699,6 +758,7 @@ public class DefaultTransportService implements TransportService { | @@ -699,6 +758,7 @@ public class DefaultTransportService implements TransportService { | ||
699 | rateLimitService.remove(new TenantId(entityUuid)); | 758 | rateLimitService.remove(new TenantId(entityUuid)); |
700 | } else if (EntityType.DEVICE.equals(entityType)) { | 759 | } else if (EntityType.DEVICE.equals(entityType)) { |
701 | rateLimitService.remove(new DeviceId(entityUuid)); | 760 | rateLimitService.remove(new DeviceId(entityUuid)); |
761 | + onDeviceDeleted(new DeviceId(entityUuid)); | ||
702 | } | 762 | } |
703 | } else if (toSessionMsg.hasResourceUpdateMsg()) { | 763 | } else if (toSessionMsg.hasResourceUpdateMsg()) { |
704 | //TODO: update resource cache | 764 | //TODO: update resource cache |
@@ -764,6 +824,17 @@ public class DefaultTransportService implements TransportService { | @@ -764,6 +824,17 @@ public class DefaultTransportService implements TransportService { | ||
764 | }); | 824 | }); |
765 | } | 825 | } |
766 | 826 | ||
827 | + private void onDeviceDeleted(DeviceId deviceId) { | ||
828 | + sessions.forEach((id, md) -> { | ||
829 | + DeviceId sessionDeviceId = new DeviceId(new UUID(md.getSessionInfo().getDeviceIdMSB(), md.getSessionInfo().getDeviceIdLSB())); | ||
830 | + if (sessionDeviceId.equals(deviceId)) { | ||
831 | + transportCallbackExecutor.submit(() -> { | ||
832 | + md.getListener().onDeviceDeleted(deviceId); | ||
833 | + }); | ||
834 | + } | ||
835 | + }); | ||
836 | + } | ||
837 | + | ||
767 | protected UUID toSessionId(TransportProtos.SessionInfoProto sessionInfo) { | 838 | protected UUID toSessionId(TransportProtos.SessionInfoProto sessionInfo) { |
768 | return new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()); | 839 | return new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()); |
769 | } | 840 | } |
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device; | @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device; | ||
18 | import com.google.common.util.concurrent.ListenableFuture; | 18 | import com.google.common.util.concurrent.ListenableFuture; |
19 | import org.thingsboard.server.common.data.Device; | 19 | import org.thingsboard.server.common.data.Device; |
20 | import org.thingsboard.server.common.data.DeviceInfo; | 20 | import org.thingsboard.server.common.data.DeviceInfo; |
21 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
21 | import org.thingsboard.server.common.data.EntitySubtype; | 22 | import org.thingsboard.server.common.data.EntitySubtype; |
22 | import org.thingsboard.server.common.data.id.TenantId; | 23 | import org.thingsboard.server.common.data.id.TenantId; |
23 | import org.thingsboard.server.common.data.page.PageData; | 24 | import org.thingsboard.server.common.data.page.PageData; |
@@ -215,4 +216,7 @@ public interface DeviceDao extends Dao<Device>, TenantEntityDao { | @@ -215,4 +216,7 @@ public interface DeviceDao extends Dao<Device>, TenantEntityDao { | ||
215 | * @return the list of device objects | 216 | * @return the list of device objects |
216 | */ | 217 | */ |
217 | PageData<Device> findDevicesByTenantIdAndProfileId(UUID tenantId, UUID profileId, PageLink pageLink); | 218 | PageData<Device> findDevicesByTenantIdAndProfileId(UUID tenantId, UUID profileId, PageLink pageLink); |
219 | + | ||
220 | + List<UUID> findDevicesIdsByDeviceProfileTransportType(DeviceTransportType transportType); | ||
221 | + | ||
218 | } | 222 | } |
@@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.Customer; | @@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.Customer; | ||
36 | import org.thingsboard.server.common.data.Device; | 36 | import org.thingsboard.server.common.data.Device; |
37 | import org.thingsboard.server.common.data.DeviceInfo; | 37 | import org.thingsboard.server.common.data.DeviceInfo; |
38 | import org.thingsboard.server.common.data.DeviceProfile; | 38 | import org.thingsboard.server.common.data.DeviceProfile; |
39 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
39 | import org.thingsboard.server.common.data.EntitySubtype; | 40 | import org.thingsboard.server.common.data.EntitySubtype; |
40 | import org.thingsboard.server.common.data.EntityType; | 41 | import org.thingsboard.server.common.data.EntityType; |
41 | import org.thingsboard.server.common.data.EntityView; | 42 | import org.thingsboard.server.common.data.EntityView; |
@@ -80,6 +81,7 @@ import java.util.Collections; | @@ -80,6 +81,7 @@ import java.util.Collections; | ||
80 | import java.util.Comparator; | 81 | import java.util.Comparator; |
81 | import java.util.List; | 82 | import java.util.List; |
82 | import java.util.Optional; | 83 | import java.util.Optional; |
84 | +import java.util.UUID; | ||
83 | import java.util.concurrent.ExecutionException; | 85 | import java.util.concurrent.ExecutionException; |
84 | import java.util.stream.Collectors; | 86 | import java.util.stream.Collectors; |
85 | 87 | ||
@@ -554,6 +556,11 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | @@ -554,6 +556,11 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | ||
554 | return savedDevice; | 556 | return savedDevice; |
555 | } | 557 | } |
556 | 558 | ||
559 | + @Override | ||
560 | + public List<UUID> findDevicesIdsByDeviceProfileTransportType(DeviceTransportType transportType) { | ||
561 | + return deviceDao.findDevicesIdsByDeviceProfileTransportType(transportType); | ||
562 | + } | ||
563 | + | ||
557 | private DataValidator<Device> deviceValidator = | 564 | private DataValidator<Device> deviceValidator = |
558 | new DataValidator<Device>() { | 565 | new DataValidator<Device>() { |
559 | 566 |
@@ -20,6 +20,7 @@ import org.springframework.data.domain.Pageable; | @@ -20,6 +20,7 @@ import org.springframework.data.domain.Pageable; | ||
20 | import org.springframework.data.jpa.repository.Query; | 20 | import org.springframework.data.jpa.repository.Query; |
21 | import org.springframework.data.repository.PagingAndSortingRepository; | 21 | import org.springframework.data.repository.PagingAndSortingRepository; |
22 | import org.springframework.data.repository.query.Param; | 22 | import org.springframework.data.repository.query.Param; |
23 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
23 | import org.thingsboard.server.dao.model.sql.DeviceEntity; | 24 | import org.thingsboard.server.dao.model.sql.DeviceEntity; |
24 | import org.thingsboard.server.dao.model.sql.DeviceInfoEntity; | 25 | import org.thingsboard.server.dao.model.sql.DeviceInfoEntity; |
25 | 26 | ||
@@ -170,4 +171,9 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit | @@ -170,4 +171,9 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit | ||
170 | Long countByDeviceProfileId(UUID deviceProfileId); | 171 | Long countByDeviceProfileId(UUID deviceProfileId); |
171 | 172 | ||
172 | Long countByTenantId(UUID tenantId); | 173 | Long countByTenantId(UUID tenantId); |
174 | + | ||
175 | + @Query("SELECT d.id FROM DeviceEntity d " + | ||
176 | + "INNER JOIN DeviceProfileEntity p ON d.deviceProfileId = p.id " + | ||
177 | + "WHERE p.transportType = :transportType") | ||
178 | + List<UUID> findIdsByDeviceProfileTransportType(@Param("transportType") DeviceTransportType transportType); | ||
173 | } | 179 | } |
@@ -22,6 +22,7 @@ import org.springframework.stereotype.Component; | @@ -22,6 +22,7 @@ import org.springframework.stereotype.Component; | ||
22 | import org.springframework.util.StringUtils; | 22 | import org.springframework.util.StringUtils; |
23 | import org.thingsboard.server.common.data.Device; | 23 | import org.thingsboard.server.common.data.Device; |
24 | import org.thingsboard.server.common.data.DeviceInfo; | 24 | import org.thingsboard.server.common.data.DeviceInfo; |
25 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
25 | import org.thingsboard.server.common.data.EntitySubtype; | 26 | import org.thingsboard.server.common.data.EntitySubtype; |
26 | import org.thingsboard.server.common.data.EntityType; | 27 | import org.thingsboard.server.common.data.EntityType; |
27 | import org.thingsboard.server.common.data.id.TenantId; | 28 | import org.thingsboard.server.common.data.id.TenantId; |
@@ -115,6 +116,11 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> | @@ -115,6 +116,11 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> | ||
115 | } | 116 | } |
116 | 117 | ||
117 | @Override | 118 | @Override |
119 | + public List<UUID> findDevicesIdsByDeviceProfileTransportType(DeviceTransportType transportType) { | ||
120 | + return deviceRepository.findIdsByDeviceProfileTransportType(transportType); | ||
121 | + } | ||
122 | + | ||
123 | + @Override | ||
118 | public PageData<DeviceInfo> findDeviceInfosByTenantIdAndCustomerId(UUID tenantId, UUID customerId, PageLink pageLink) { | 124 | public PageData<DeviceInfo> findDeviceInfosByTenantIdAndCustomerId(UUID tenantId, UUID customerId, PageLink pageLink) { |
119 | return DaoUtil.toPageData( | 125 | return DaoUtil.toPageData( |
120 | deviceRepository.findDeviceInfosByTenantIdAndCustomerId( | 126 | deviceRepository.findDeviceInfosByTenantIdAndCustomerId( |
docker/tb-transports/snmp/conf/logback.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8" ?> | ||
2 | +<!-- | ||
3 | + | ||
4 | + Copyright © 2016-2021 The Thingsboard Authors | ||
5 | + | ||
6 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | + you may not use this file except in compliance with the License. | ||
8 | + You may obtain a copy of the License at | ||
9 | + | ||
10 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + | ||
12 | + Unless required by applicable law or agreed to in writing, software | ||
13 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | + See the License for the specific language governing permissions and | ||
16 | + limitations under the License. | ||
17 | + | ||
18 | +--> | ||
19 | +<!DOCTYPE configuration> | ||
20 | +<configuration scan="true" scanPeriod="10 seconds"> | ||
21 | + | ||
22 | + <appender name="fileLogAppender" | ||
23 | + class="ch.qos.logback.core.rolling.RollingFileAppender"> | ||
24 | + <file>/var/log/tb-snmp-transport/${TB_SERVICE_ID}/tb-snmp-transport.log</file> | ||
25 | + <rollingPolicy | ||
26 | + class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> | ||
27 | + <fileNamePattern>/var/log/tb-snmp-transport/${TB_SERVICE_ID}/tb-snmp-transport.%d{yyyy-MM-dd}.%i.log</fileNamePattern> | ||
28 | + <maxFileSize>100MB</maxFileSize> | ||
29 | + <maxHistory>30</maxHistory> | ||
30 | + <totalSizeCap>3GB</totalSizeCap> | ||
31 | + </rollingPolicy> | ||
32 | + <encoder> | ||
33 | + <pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern> | ||
34 | + </encoder> | ||
35 | + </appender> | ||
36 | + | ||
37 | + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||
38 | + <encoder> | ||
39 | + <pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern> | ||
40 | + </encoder> | ||
41 | + </appender> | ||
42 | + | ||
43 | + <logger name="org.thingsboard.server" level="INFO" /> | ||
44 | + | ||
45 | + <root level="INFO"> | ||
46 | + <appender-ref ref="fileLogAppender"/> | ||
47 | + <appender-ref ref="STDOUT"/> | ||
48 | + </root> | ||
49 | + | ||
50 | +</configuration> |
1 | +# | ||
2 | +# Copyright © 2016-2021 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 | + | ||
17 | +export JAVA_OPTS="$JAVA_OPTS -Xlog:gc*,heap*,age*,safepoint=debug:file=/var/log/tb-snmp-transport/${TB_SERVICE_ID}-gc.log:time,uptime,level,tags:filecount=10,filesize=10M" | ||
18 | +export JAVA_OPTS="$JAVA_OPTS -XX:+IgnoreUnrecognizedVMOptions -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/tb-snmp-transport/${TB_SERVICE_ID}-heapdump.bin" | ||
19 | +export JAVA_OPTS="$JAVA_OPTS -XX:-UseBiasedLocking -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark" | ||
20 | +export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=500 -XX:+UseStringDeduplication -XX:+ParallelRefProcEnabled -XX:MaxTenuringThreshold=10" | ||
21 | +export JAVA_OPTS="$JAVA_OPTS -XX:+ExitOnOutOfMemoryError" | ||
22 | +export LOG_FILENAME=tb-snmp-transport.out | ||
23 | +export LOADER_PATH=/usr/share/tb-snmp-transport/conf |
@@ -14,7 +14,7 @@ | @@ -14,7 +14,7 @@ | ||
14 | # limitations under the License. | 14 | # limitations under the License. |
15 | # | 15 | # |
16 | 16 | ||
17 | -FROM thingsboard/openjdk8 | 17 | +FROM thingsboard/openjdk11 |
18 | 18 | ||
19 | COPY start-tb-snmp-transport.sh ${pkg.name}.deb /tmp/ | 19 | COPY start-tb-snmp-transport.sh ${pkg.name}.deb /tmp/ |
20 | 20 |
transport/snmp/src/main/conf/logback.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8" ?> | ||
2 | +<!-- | ||
3 | + | ||
4 | + Copyright © 2016-2021 The Thingsboard Authors | ||
5 | + | ||
6 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | + you may not use this file except in compliance with the License. | ||
8 | + You may obtain a copy of the License at | ||
9 | + | ||
10 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + | ||
12 | + Unless required by applicable law or agreed to in writing, software | ||
13 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | + See the License for the specific language governing permissions and | ||
16 | + limitations under the License. | ||
17 | + | ||
18 | +--> | ||
19 | +<!DOCTYPE configuration> | ||
20 | +<configuration> | ||
21 | + | ||
22 | + <appender name="fileLogAppender" | ||
23 | + class="ch.qos.logback.core.rolling.RollingFileAppender"> | ||
24 | + <file>${pkg.logFolder}/${pkg.name}.log</file> | ||
25 | + <rollingPolicy | ||
26 | + class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> | ||
27 | + <fileNamePattern>${pkg.logFolder}/${pkg.name}.%d{yyyy-MM-dd}.%i.log</fileNamePattern> | ||
28 | + <maxFileSize>100MB</maxFileSize> | ||
29 | + <maxHistory>30</maxHistory> | ||
30 | + <totalSizeCap>3GB</totalSizeCap> | ||
31 | + </rollingPolicy> | ||
32 | + <encoder> | ||
33 | + <pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern> | ||
34 | + </encoder> | ||
35 | + </appender> | ||
36 | + | ||
37 | + <logger name="org.thingsboard.server" level="INFO" /> | ||
38 | + | ||
39 | + <logger name="com.microsoft.azure.servicebus.primitives.CoreMessageReceiver" level="OFF" /> | ||
40 | + | ||
41 | + <root level="INFO"> | ||
42 | + <appender-ref ref="fileLogAppender"/> | ||
43 | + </root> | ||
44 | + | ||
45 | +</configuration> |
1 | +# | ||
2 | +# Copyright © 2016-2021 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 | + | ||
17 | +export JAVA_OPTS="$JAVA_OPTS -Xlog:gc*,heap*,age*,safepoint=debug:file=@pkg.logFolder@/gc.log:time,uptime,level,tags:filecount=10,filesize=10M" | ||
18 | +export JAVA_OPTS="$JAVA_OPTS -XX:+IgnoreUnrecognizedVMOptions -XX:+HeapDumpOnOutOfMemoryError" | ||
19 | +export JAVA_OPTS="$JAVA_OPTS -XX:-UseBiasedLocking -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark" | ||
20 | +export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=500 -XX:+UseStringDeduplication -XX:+ParallelRefProcEnabled -XX:MaxTenuringThreshold=10" | ||
21 | +export LOG_FILENAME=${pkg.name}.out | ||
22 | +export LOADER_PATH=${pkg.installFolder}/conf |
1 | +<?xml version="1.0" encoding="UTF-8" ?> | ||
2 | +<!-- | ||
3 | + | ||
4 | + Copyright © 2016-2021 The Thingsboard Authors | ||
5 | + | ||
6 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | + you may not use this file except in compliance with the License. | ||
8 | + You may obtain a copy of the License at | ||
9 | + | ||
10 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + | ||
12 | + Unless required by applicable law or agreed to in writing, software | ||
13 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | + See the License for the specific language governing permissions and | ||
16 | + limitations under the License. | ||
17 | + | ||
18 | +--> | ||
19 | +<!DOCTYPE configuration> | ||
20 | +<configuration scan="true" scanPeriod="10 seconds"> | ||
21 | + | ||
22 | + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||
23 | + <encoder> | ||
24 | + <pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern> | ||
25 | + </encoder> | ||
26 | + </appender> | ||
27 | + | ||
28 | + <logger name="org.thingsboard.server" level="TRACE" /> | ||
29 | + | ||
30 | + <logger name="com.microsoft.azure.servicebus.primitives.CoreMessageReceiver" level="OFF" /> | ||
31 | + | ||
32 | + <root level="INFO"> | ||
33 | + <appender-ref ref="STDOUT"/> | ||
34 | + </root> | ||
35 | + | ||
36 | +</configuration> |
1 | +# | ||
2 | +# Copyright © 2016-2021 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 | + | ||
17 | +server: | ||
18 | + # Server bind address | ||
19 | + address: "${HTTP_BIND_ADDRESS:0.0.0.0}" | ||
20 | + # Server bind port | ||
21 | + port: "${HTTP_BIND_PORT:8085}" | ||
22 | + # Server SSL configuration | ||
23 | + | ||
24 | +# Zookeeper connection parameters. Used for service discovery. | ||
25 | +zk: | ||
26 | + # Enable/disable zookeeper discovery service. | ||
27 | + enabled: "${ZOOKEEPER_ENABLED:false}" | ||
28 | + # Zookeeper connect string | ||
29 | + url: "${ZOOKEEPER_URL:localhost:2181}" | ||
30 | + # Zookeeper retry interval in milliseconds | ||
31 | + retry_interval_ms: "${ZOOKEEPER_RETRY_INTERVAL_MS:3000}" | ||
32 | + # Zookeeper connection timeout in milliseconds | ||
33 | + connection_timeout_ms: "${ZOOKEEPER_CONNECTION_TIMEOUT_MS:3000}" | ||
34 | + # Zookeeper session timeout in milliseconds | ||
35 | + session_timeout_ms: "${ZOOKEEPER_SESSION_TIMEOUT_MS:3000}" | ||
36 | + # Name of the directory in zookeeper 'filesystem' | ||
37 | + zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}" | ||
38 | + | ||
39 | +cluster: | ||
40 | + stats: | ||
41 | + enabled: "${TB_CLUSTER_STATS_ENABLED:false}" | ||
42 | + print_interval_ms: "${TB_CLUSTER_STATS_PRINT_INTERVAL_MS:10000}" | ||
43 | + | ||
44 | +cache: | ||
45 | + # caffeine or redis | ||
46 | + type: "${CACHE_TYPE:caffeine}" | ||
47 | + attributes: | ||
48 | + # make sure that if cache.type is 'redis' and cache.attributes.enabled is 'true' that you change 'maxmemory-policy' Redis config property to 'allkeys-lru', 'allkeys-lfu' or 'allkeys-random' | ||
49 | + enabled: "${CACHE_ATTRIBUTES_ENABLED:true}" | ||
50 | + | ||
51 | +caffeine: | ||
52 | + specs: | ||
53 | + relations: | ||
54 | + timeToLiveInMinutes: 1440 | ||
55 | + maxSize: 0 | ||
56 | + deviceCredentials: | ||
57 | + timeToLiveInMinutes: 1440 | ||
58 | + maxSize: 0 | ||
59 | + devices: | ||
60 | + timeToLiveInMinutes: 1440 | ||
61 | + maxSize: 0 | ||
62 | + sessions: | ||
63 | + timeToLiveInMinutes: 1440 | ||
64 | + maxSize: 0 | ||
65 | + assets: | ||
66 | + timeToLiveInMinutes: 1440 | ||
67 | + maxSize: 0 | ||
68 | + entityViews: | ||
69 | + timeToLiveInMinutes: 1440 | ||
70 | + maxSize: 0 | ||
71 | + claimDevices: | ||
72 | + timeToLiveInMinutes: 1 | ||
73 | + maxSize: 0 | ||
74 | + securitySettings: | ||
75 | + timeToLiveInMinutes: 1440 | ||
76 | + maxSize: 0 | ||
77 | + tenantProfiles: | ||
78 | + timeToLiveInMinutes: 1440 | ||
79 | + maxSize: 0 | ||
80 | + deviceProfiles: | ||
81 | + timeToLiveInMinutes: 1440 | ||
82 | + maxSize: 0 | ||
83 | + attributes: | ||
84 | + timeToLiveInMinutes: 1440 | ||
85 | + maxSize: 100000 | ||
86 | + | ||
87 | +redis: | ||
88 | + # standalone or cluster | ||
89 | + connection: | ||
90 | + type: "${REDIS_CONNECTION_TYPE:standalone}" | ||
91 | + standalone: | ||
92 | + host: "${REDIS_HOST:localhost}" | ||
93 | + port: "${REDIS_PORT:6379}" | ||
94 | + useDefaultClientConfig: "${REDIS_USE_DEFAULT_CLIENT_CONFIG:true}" | ||
95 | + # this value may be used only if you used not default ClientConfig | ||
96 | + clientName: "${REDIS_CLIENT_NAME:standalone}" | ||
97 | + # this value may be used only if you used not default ClientConfig | ||
98 | + connectTimeout: "${REDIS_CLIENT_CONNECT_TIMEOUT:30000}" | ||
99 | + # this value may be used only if you used not default ClientConfig | ||
100 | + readTimeout: "${REDIS_CLIENT_READ_TIMEOUT:60000}" | ||
101 | + # this value may be used only if you used not default ClientConfig | ||
102 | + usePoolConfig: "${REDIS_CLIENT_USE_POOL_CONFIG:false}" | ||
103 | + cluster: | ||
104 | + # Comma-separated list of "host:port" pairs to bootstrap from. | ||
105 | + nodes: "${REDIS_NODES:}" | ||
106 | + # Maximum number of redirects to follow when executing commands across the cluster. | ||
107 | + max-redirects: "${REDIS_MAX_REDIRECTS:12}" | ||
108 | + useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" | ||
109 | + # db index | ||
110 | + db: "${REDIS_DB:0}" | ||
111 | + # db password | ||
112 | + password: "${REDIS_PASSWORD:}" | ||
113 | + # pool config | ||
114 | + pool_config: | ||
115 | + maxTotal: "${REDIS_POOL_CONFIG_MAX_TOTAL:128}" | ||
116 | + maxIdle: "${REDIS_POOL_CONFIG_MAX_IDLE:128}" | ||
117 | + minIdle: "${REDIS_POOL_CONFIG_MIN_IDLE:16}" | ||
118 | + testOnBorrow: "${REDIS_POOL_CONFIG_TEST_ON_BORROW:true}" | ||
119 | + testOnReturn: "${REDIS_POOL_CONFIG_TEST_ON_RETURN:true}" | ||
120 | + testWhileIdle: "${REDIS_POOL_CONFIG_TEST_WHILE_IDLE:true}" | ||
121 | + minEvictableMs: "${REDIS_POOL_CONFIG_MIN_EVICTABLE_MS:60000}" | ||
122 | + evictionRunsMs: "${REDIS_POOL_CONFIG_EVICTION_RUNS_MS:30000}" | ||
123 | + maxWaitMills: "${REDIS_POOL_CONFIG_MAX_WAIT_MS:60000}" | ||
124 | + numberTestsPerEvictionRun: "${REDIS_POOL_CONFIG_NUMBER_TESTS_PER_EVICTION_RUN:3}" | ||
125 | + blockWhenExhausted: "${REDIS_POOL_CONFIG_BLOCK_WHEN_EXHAUSTED:true}" | ||
126 | + | ||
127 | +# Check new version updates parameters | ||
128 | +updates: | ||
129 | + # Enable/disable updates checking. | ||
130 | + enabled: "${UPDATES_ENABLED:true}" | ||
131 | + | ||
132 | +# spring freemarker configuration | ||
133 | +spring.freemarker.checkTemplateLocation: "false" | ||
134 | + | ||
135 | +audit-log: | ||
136 | + # Enable/disable audit log functionality. | ||
137 | + enabled: "${AUDIT_LOG_ENABLED:true}" | ||
138 | + # Specify partitioning size for audit log by tenant id storage. Example MINUTES, HOURS, DAYS, MONTHS | ||
139 | + by_tenant_partitioning: "${AUDIT_LOG_BY_TENANT_PARTITIONING:MONTHS}" | ||
140 | + # Number of days as history period if startTime and endTime are not specified | ||
141 | + default_query_period: "${AUDIT_LOG_DEFAULT_QUERY_PERIOD:30}" | ||
142 | + # Logging levels per each entity type. | ||
143 | + # Allowed values: OFF (disable), W (log write operations), RW (log read and write operations) | ||
144 | + logging-level: | ||
145 | + mask: | ||
146 | + "device": "${AUDIT_LOG_MASK_DEVICE:W}" | ||
147 | + "asset": "${AUDIT_LOG_MASK_ASSET:W}" | ||
148 | + "dashboard": "${AUDIT_LOG_MASK_DASHBOARD:W}" | ||
149 | + "customer": "${AUDIT_LOG_MASK_CUSTOMER:W}" | ||
150 | + "user": "${AUDIT_LOG_MASK_USER:W}" | ||
151 | + "rule_chain": "${AUDIT_LOG_MASK_RULE_CHAIN:W}" | ||
152 | + "alarm": "${AUDIT_LOG_MASK_ALARM:W}" | ||
153 | + "entity_view": "${AUDIT_LOG_MASK_ENTITY_VIEW:W}" | ||
154 | + "device_profile": "${AUDIT_LOG_MASK_DEVICE_PROFILE:W}" | ||
155 | + sink: | ||
156 | + # Type of external sink. possible options: none, elasticsearch | ||
157 | + type: "${AUDIT_LOG_SINK_TYPE:none}" | ||
158 | + # Name of the index where audit logs stored | ||
159 | + # Index name could contain next placeholders (not mandatory): | ||
160 | + # @{TENANT} - substituted by tenant ID | ||
161 | + # @{DATE} - substituted by current date in format provided in audit_log.sink.date_format | ||
162 | + index_pattern: "${AUDIT_LOG_SINK_INDEX_PATTERN:@{TENANT}_AUDIT_LOG_@{DATE}}" | ||
163 | + # Date format. Details of the pattern could be found here: | ||
164 | + # https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html | ||
165 | + date_format: "${AUDIT_LOG_SINK_DATE_FORMAT:YYYY.MM.DD}" | ||
166 | + scheme_name: "${AUDIT_LOG_SINK_SCHEME_NAME:http}" # http or https | ||
167 | + host: "${AUDIT_LOG_SINK_HOST:localhost}" | ||
168 | + port: "${AUDIT_LOG_SINK_PORT:9200}" | ||
169 | + user_name: "${AUDIT_LOG_SINK_USER_NAME:}" | ||
170 | + password: "${AUDIT_LOG_SINK_PASSWORD:}" | ||
171 | + | ||
172 | +state: | ||
173 | + # Should be greater then transport.sessions.report_timeout | ||
174 | + defaultInactivityTimeoutInSec: "${DEFAULT_INACTIVITY_TIMEOUT:600}" | ||
175 | + defaultStateCheckIntervalInSec: "${DEFAULT_STATE_CHECK_INTERVAL:60}" | ||
176 | + persistToTelemetry: "${PERSIST_STATE_TO_TELEMETRY:false}" | ||
177 | + | ||
178 | +transport: | ||
179 | + sessions: | ||
180 | + inactivity_timeout: "${TB_TRANSPORT_SESSIONS_INACTIVITY_TIMEOUT:300000}" | ||
181 | + report_timeout: "${TB_TRANSPORT_SESSIONS_REPORT_TIMEOUT:30000}" | ||
182 | + json: | ||
183 | + # Cast String data types to Numeric if possible when processing Telemetry/Attributes JSON | ||
184 | + type_cast_enabled: "${JSON_TYPE_CAST_ENABLED:true}" | ||
185 | + # Maximum allowed string value length when processing Telemetry/Attributes JSON (0 value disables string value length check) | ||
186 | + max_string_value_length: "${JSON_MAX_STRING_VALUE_LENGTH:0}" | ||
187 | + # Enable/disable http/mqtt/coap transport protocols (has higher priority than certain protocol's 'enabled' property) | ||
188 | + api_enabled: "${TB_TRANSPORT_API_ENABLED:true}" | ||
189 | + # Local LwM2M transport parameters | ||
190 | + snmp: | ||
191 | + enabled: "${SNMP_ENABLED:true}" | ||
192 | + | ||
193 | +queue: | ||
194 | + type: "${TB_QUEUE_TYPE:in-memory}" # in-memory or kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ) | ||
195 | + in_memory: | ||
196 | + stats: | ||
197 | + # For debug lvl | ||
198 | + print-interval-ms: "${TB_QUEUE_IN_MEMORY_STATS_PRINT_INTERVAL_MS:60000}" | ||
199 | + kafka: | ||
200 | + bootstrap.servers: "${TB_KAFKA_SERVERS:localhost:9092}" | ||
201 | + acks: "${TB_KAFKA_ACKS:all}" | ||
202 | + retries: "${TB_KAFKA_RETRIES:1}" | ||
203 | + batch.size: "${TB_KAFKA_BATCH_SIZE:16384}" | ||
204 | + linger.ms: "${TB_KAFKA_LINGER_MS:1}" | ||
205 | + buffer.memory: "${TB_BUFFER_MEMORY:33554432}" | ||
206 | + replication_factor: "${TB_QUEUE_KAFKA_REPLICATION_FACTOR:1}" | ||
207 | + max_poll_interval_ms: "${TB_QUEUE_KAFKA_MAX_POLL_INTERVAL_MS:300000}" | ||
208 | + max_poll_records: "${TB_QUEUE_KAFKA_MAX_POLL_RECORDS:8192}" | ||
209 | + max_partition_fetch_bytes: "${TB_QUEUE_KAFKA_MAX_PARTITION_FETCH_BYTES:16777216}" | ||
210 | + fetch_max_bytes: "${TB_QUEUE_KAFKA_FETCH_MAX_BYTES:134217728}" | ||
211 | + use_confluent_cloud: "${TB_QUEUE_KAFKA_USE_CONFLUENT_CLOUD:false}" | ||
212 | + confluent: | ||
213 | + ssl.algorithm: "${TB_QUEUE_KAFKA_CONFLUENT_SSL_ALGORITHM:https}" | ||
214 | + sasl.mechanism: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_MECHANISM:PLAIN}" | ||
215 | + sasl.config: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_JAAS_CONFIG:org.apache.kafka.common.security.plain.PlainLoginModule required username=\"CLUSTER_API_KEY\" password=\"CLUSTER_API_SECRET\";}" | ||
216 | + security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}" | ||
217 | + other: | ||
218 | + topic-properties: | ||
219 | + rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | ||
220 | + core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | ||
221 | + transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | ||
222 | + notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | ||
223 | + js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100}" | ||
224 | + consumer-stats: | ||
225 | + enabled: "${TB_QUEUE_KAFKA_CONSUMER_STATS_ENABLED:true}" | ||
226 | + print-interval-ms: "${TB_QUEUE_KAFKA_CONSUMER_STATS_MIN_PRINT_INTERVAL_MS:60000}" | ||
227 | + kafka-response-timeout-ms: "${TB_QUEUE_KAFKA_CONSUMER_STATS_RESPONSE_TIMEOUT_MS:1000}" | ||
228 | + aws_sqs: | ||
229 | + use_default_credential_provider_chain: "${TB_QUEUE_AWS_SQS_USE_DEFAULT_CREDENTIAL_PROVIDER_CHAIN:false}" | ||
230 | + access_key_id: "${TB_QUEUE_AWS_SQS_ACCESS_KEY_ID:YOUR_KEY}" | ||
231 | + secret_access_key: "${TB_QUEUE_AWS_SQS_SECRET_ACCESS_KEY:YOUR_SECRET}" | ||
232 | + region: "${TB_QUEUE_AWS_SQS_REGION:YOUR_REGION}" | ||
233 | + threads_per_topic: "${TB_QUEUE_AWS_SQS_THREADS_PER_TOPIC:1}" | ||
234 | + queue-properties: | ||
235 | + rule-engine: "${TB_QUEUE_AWS_SQS_RE_QUEUE_PROPERTIES:VisibilityTimeout:30;MaximumMessageSize:262144;MessageRetentionPeriod:604800}" | ||
236 | + core: "${TB_QUEUE_AWS_SQS_CORE_QUEUE_PROPERTIES:VisibilityTimeout:30;MaximumMessageSize:262144;MessageRetentionPeriod:604800}" | ||
237 | + transport-api: "${TB_QUEUE_AWS_SQS_TA_QUEUE_PROPERTIES:VisibilityTimeout:30;MaximumMessageSize:262144;MessageRetentionPeriod:604800}" | ||
238 | + notifications: "${TB_QUEUE_AWS_SQS_NOTIFICATIONS_QUEUE_PROPERTIES:VisibilityTimeout:30;MaximumMessageSize:262144;MessageRetentionPeriod:604800}" | ||
239 | + js-executor: "${TB_QUEUE_AWS_SQS_JE_QUEUE_PROPERTIES:VisibilityTimeout:30;MaximumMessageSize:262144;MessageRetentionPeriod:604800}" | ||
240 | + # VisibilityTimeout in seconds;MaximumMessageSize in bytes;MessageRetentionPeriod in seconds | ||
241 | + pubsub: | ||
242 | + project_id: "${TB_QUEUE_PUBSUB_PROJECT_ID:YOUR_PROJECT_ID}" | ||
243 | + service_account: "${TB_QUEUE_PUBSUB_SERVICE_ACCOUNT:YOUR_SERVICE_ACCOUNT}" | ||
244 | + max_msg_size: "${TB_QUEUE_PUBSUB_MAX_MSG_SIZE:1048576}" #in bytes | ||
245 | + max_messages: "${TB_QUEUE_PUBSUB_MAX_MESSAGES:1000}" | ||
246 | + queue-properties: | ||
247 | + rule-engine: "${TB_QUEUE_PUBSUB_RE_QUEUE_PROPERTIES:ackDeadlineInSec:30;messageRetentionInSec:604800}" | ||
248 | + core: "${TB_QUEUE_PUBSUB_CORE_QUEUE_PROPERTIES:ackDeadlineInSec:30;messageRetentionInSec:604800}" | ||
249 | + transport-api: "${TB_QUEUE_PUBSUB_TA_QUEUE_PROPERTIES:ackDeadlineInSec:30;messageRetentionInSec:604800}" | ||
250 | + notifications: "${TB_QUEUE_PUBSUB_NOTIFICATIONS_QUEUE_PROPERTIES:ackDeadlineInSec:30;messageRetentionInSec:604800}" | ||
251 | + js-executor: "${TB_QUEUE_PUBSUB_JE_QUEUE_PROPERTIES:ackDeadlineInSec:30;messageRetentionInSec:604800}" | ||
252 | + service_bus: | ||
253 | + namespace_name: "${TB_QUEUE_SERVICE_BUS_NAMESPACE_NAME:YOUR_NAMESPACE_NAME}" | ||
254 | + sas_key_name: "${TB_QUEUE_SERVICE_BUS_SAS_KEY_NAME:YOUR_SAS_KEY_NAME}" | ||
255 | + sas_key: "${TB_QUEUE_SERVICE_BUS_SAS_KEY:YOUR_SAS_KEY}" | ||
256 | + max_messages: "${TB_QUEUE_SERVICE_BUS_MAX_MESSAGES:1000}" | ||
257 | + queue-properties: | ||
258 | + rule-engine: "${TB_QUEUE_SERVICE_BUS_RE_QUEUE_PROPERTIES:lockDurationInSec:30;maxSizeInMb:1024;messageTimeToLiveInSec:604800}" | ||
259 | + core: "${TB_QUEUE_SERVICE_BUS_CORE_QUEUE_PROPERTIES:lockDurationInSec:30;maxSizeInMb:1024;messageTimeToLiveInSec:604800}" | ||
260 | + transport-api: "${TB_QUEUE_SERVICE_BUS_TA_QUEUE_PROPERTIES:lockDurationInSec:30;maxSizeInMb:1024;messageTimeToLiveInSec:604800}" | ||
261 | + notifications: "${TB_QUEUE_SERVICE_BUS_NOTIFICATIONS_QUEUE_PROPERTIES:lockDurationInSec:30;maxSizeInMb:1024;messageTimeToLiveInSec:604800}" | ||
262 | + js-executor: "${TB_QUEUE_SERVICE_BUS_JE_QUEUE_PROPERTIES:lockDurationInSec:30;maxSizeInMb:1024;messageTimeToLiveInSec:604800}" | ||
263 | + rabbitmq: | ||
264 | + exchange_name: "${TB_QUEUE_RABBIT_MQ_EXCHANGE_NAME:}" | ||
265 | + host: "${TB_QUEUE_RABBIT_MQ_HOST:localhost}" | ||
266 | + port: "${TB_QUEUE_RABBIT_MQ_PORT:5672}" | ||
267 | + virtual_host: "${TB_QUEUE_RABBIT_MQ_VIRTUAL_HOST:/}" | ||
268 | + username: "${TB_QUEUE_RABBIT_MQ_USERNAME:YOUR_USERNAME}" | ||
269 | + password: "${TB_QUEUE_RABBIT_MQ_PASSWORD:YOUR_PASSWORD}" | ||
270 | + automatic_recovery_enabled: "${TB_QUEUE_RABBIT_MQ_AUTOMATIC_RECOVERY_ENABLED:false}" | ||
271 | + connection_timeout: "${TB_QUEUE_RABBIT_MQ_CONNECTION_TIMEOUT:60000}" | ||
272 | + handshake_timeout: "${TB_QUEUE_RABBIT_MQ_HANDSHAKE_TIMEOUT:10000}" | ||
273 | + queue-properties: | ||
274 | + rule-engine: "${TB_QUEUE_RABBIT_MQ_RE_QUEUE_PROPERTIES:x-max-length-bytes:1048576000;x-message-ttl:604800000}" | ||
275 | + core: "${TB_QUEUE_RABBIT_MQ_CORE_QUEUE_PROPERTIES:x-max-length-bytes:1048576000;x-message-ttl:604800000}" | ||
276 | + transport-api: "${TB_QUEUE_RABBIT_MQ_TA_QUEUE_PROPERTIES:x-max-length-bytes:1048576000;x-message-ttl:604800000}" | ||
277 | + notifications: "${TB_QUEUE_RABBIT_MQ_NOTIFICATIONS_QUEUE_PROPERTIES:x-max-length-bytes:1048576000;x-message-ttl:604800000}" | ||
278 | + js-executor: "${TB_QUEUE_RABBIT_MQ_JE_QUEUE_PROPERTIES:x-max-length-bytes:1048576000;x-message-ttl:604800000}" | ||
279 | + partitions: | ||
280 | + hash_function_name: "${TB_QUEUE_PARTITIONS_HASH_FUNCTION_NAME:murmur3_128}" # murmur3_32, murmur3_128 or sha256 | ||
281 | + transport_api: | ||
282 | + requests_topic: "${TB_QUEUE_TRANSPORT_API_REQUEST_TOPIC:tb_transport.api.requests}" | ||
283 | + responses_topic: "${TB_QUEUE_TRANSPORT_API_RESPONSE_TOPIC:tb_transport.api.responses}" | ||
284 | + max_pending_requests: "${TB_QUEUE_TRANSPORT_MAX_PENDING_REQUESTS:10000}" | ||
285 | + max_requests_timeout: "${TB_QUEUE_TRANSPORT_MAX_REQUEST_TIMEOUT:10000}" | ||
286 | + max_callback_threads: "${TB_QUEUE_TRANSPORT_MAX_CALLBACK_THREADS:100}" | ||
287 | + request_poll_interval: "${TB_QUEUE_TRANSPORT_REQUEST_POLL_INTERVAL_MS:25}" | ||
288 | + response_poll_interval: "${TB_QUEUE_TRANSPORT_RESPONSE_POLL_INTERVAL_MS:25}" | ||
289 | + core: | ||
290 | + topic: "${TB_QUEUE_CORE_TOPIC:tb_core}" | ||
291 | + poll-interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}" | ||
292 | + partitions: "${TB_QUEUE_CORE_PARTITIONS:10}" | ||
293 | + pack-processing-timeout: "${TB_QUEUE_CORE_PACK_PROCESSING_TIMEOUT_MS:2000}" | ||
294 | + usage-stats-topic: "${TB_QUEUE_US_TOPIC:tb_usage_stats}" | ||
295 | + stats: | ||
296 | + enabled: "${TB_QUEUE_CORE_STATS_ENABLED:true}" | ||
297 | + print-interval-ms: "${TB_QUEUE_CORE_STATS_PRINT_INTERVAL_MS:60000}" | ||
298 | + js: | ||
299 | + # JS Eval request topic | ||
300 | + request_topic: "${REMOTE_JS_EVAL_REQUEST_TOPIC:js_eval.requests}" | ||
301 | + # JS Eval responses topic prefix that is combined with node id | ||
302 | + response_topic_prefix: "${REMOTE_JS_EVAL_RESPONSE_TOPIC:js_eval.responses}" | ||
303 | + # JS Eval max pending requests | ||
304 | + max_pending_requests: "${REMOTE_JS_MAX_PENDING_REQUESTS:10000}" | ||
305 | + # JS Eval max request timeout | ||
306 | + max_eval_requests_timeout: "${REMOTE_JS_MAX_EVAL_REQUEST_TIMEOUT:60000}" | ||
307 | + # JS max request timeout | ||
308 | + max_requests_timeout: "${REMOTE_JS_MAX_REQUEST_TIMEOUT:10000}" | ||
309 | + # JS response poll interval | ||
310 | + response_poll_interval: "${REMOTE_JS_RESPONSE_POLL_INTERVAL_MS:25}" | ||
311 | + rule-engine: | ||
312 | + topic: "${TB_QUEUE_RULE_ENGINE_TOPIC:tb_rule_engine}" | ||
313 | + poll-interval: "${TB_QUEUE_RULE_ENGINE_POLL_INTERVAL_MS:25}" | ||
314 | + pack-processing-timeout: "${TB_QUEUE_RULE_ENGINE_PACK_PROCESSING_TIMEOUT_MS:2000}" | ||
315 | + stats: | ||
316 | + enabled: "${TB_QUEUE_RULE_ENGINE_STATS_ENABLED:true}" | ||
317 | + print-interval-ms: "${TB_QUEUE_RULE_ENGINE_STATS_PRINT_INTERVAL_MS:60000}" | ||
318 | + queues: | ||
319 | + - name: "${TB_QUEUE_RE_MAIN_QUEUE_NAME:Main}" | ||
320 | + topic: "${TB_QUEUE_RE_MAIN_TOPIC:tb_rule_engine.main}" | ||
321 | + poll-interval: "${TB_QUEUE_RE_MAIN_POLL_INTERVAL_MS:25}" | ||
322 | + partitions: "${TB_QUEUE_RE_MAIN_PARTITIONS:10}" | ||
323 | + pack-processing-timeout: "${TB_QUEUE_RE_MAIN_PACK_PROCESSING_TIMEOUT_MS:2000}" | ||
324 | + submit-strategy: | ||
325 | + type: "${TB_QUEUE_RE_MAIN_SUBMIT_STRATEGY_TYPE:BURST}" # BURST, BATCH, SEQUENTIAL_BY_ORIGINATOR, SEQUENTIAL_BY_TENANT, SEQUENTIAL | ||
326 | + # For BATCH only | ||
327 | + batch-size: "${TB_QUEUE_RE_MAIN_SUBMIT_STRATEGY_BATCH_SIZE:1000}" # Maximum number of messages in batch | ||
328 | + processing-strategy: | ||
329 | + type: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_TYPE:SKIP_ALL_FAILURES}" # SKIP_ALL_FAILURES, RETRY_ALL, RETRY_FAILED, RETRY_TIMED_OUT, RETRY_FAILED_AND_TIMED_OUT | ||
330 | + # For RETRY_ALL, RETRY_FAILED, RETRY_TIMED_OUT, RETRY_FAILED_AND_TIMED_OUT | ||
331 | + retries: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_RETRIES:3}" # Number of retries, 0 is unlimited | ||
332 | + failure-percentage: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages; | ||
333 | + pause-between-retries: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_RETRY_PAUSE:3}"# Time in seconds to wait in consumer thread before retries; | ||
334 | + max-pause-between-retries: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_MAX_RETRY_PAUSE:3}"# Max allowed time in seconds for pause between retries. | ||
335 | + - name: "${TB_QUEUE_RE_HP_QUEUE_NAME:HighPriority}" | ||
336 | + topic: "${TB_QUEUE_RE_HP_TOPIC:tb_rule_engine.hp}" | ||
337 | + poll-interval: "${TB_QUEUE_RE_HP_POLL_INTERVAL_MS:25}" | ||
338 | + partitions: "${TB_QUEUE_RE_HP_PARTITIONS:10}" | ||
339 | + pack-processing-timeout: "${TB_QUEUE_RE_HP_PACK_PROCESSING_TIMEOUT_MS:2000}" | ||
340 | + submit-strategy: | ||
341 | + type: "${TB_QUEUE_RE_HP_SUBMIT_STRATEGY_TYPE:BURST}" # BURST, BATCH, SEQUENTIAL_BY_ORIGINATOR, SEQUENTIAL_BY_TENANT, SEQUENTIAL | ||
342 | + # For BATCH only | ||
343 | + batch-size: "${TB_QUEUE_RE_HP_SUBMIT_STRATEGY_BATCH_SIZE:100}" # Maximum number of messages in batch | ||
344 | + processing-strategy: | ||
345 | + type: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_TYPE:RETRY_FAILED_AND_TIMED_OUT}" # SKIP_ALL_FAILURES, RETRY_ALL, RETRY_FAILED, RETRY_TIMED_OUT, RETRY_FAILED_AND_TIMED_OUT | ||
346 | + # For RETRY_ALL, RETRY_FAILED, RETRY_TIMED_OUT, RETRY_FAILED_AND_TIMED_OUT | ||
347 | + retries: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_RETRIES:0}" # Number of retries, 0 is unlimited | ||
348 | + failure-percentage: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages; | ||
349 | + pause-between-retries: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_RETRY_PAUSE:5}"# Time in seconds to wait in consumer thread before retries; | ||
350 | + max-pause-between-retries: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_MAX_RETRY_PAUSE:5}"# Max allowed time in seconds for pause between retries. | ||
351 | + - name: "${TB_QUEUE_RE_SQ_QUEUE_NAME:SequentialByOriginator}" | ||
352 | + topic: "${TB_QUEUE_RE_SQ_TOPIC:tb_rule_engine.sq}" | ||
353 | + poll-interval: "${TB_QUEUE_RE_SQ_POLL_INTERVAL_MS:25}" | ||
354 | + partitions: "${TB_QUEUE_RE_SQ_PARTITIONS:10}" | ||
355 | + pack-processing-timeout: "${TB_QUEUE_RE_SQ_PACK_PROCESSING_TIMEOUT_MS:2000}" | ||
356 | + submit-strategy: | ||
357 | + type: "${TB_QUEUE_RE_SQ_SUBMIT_STRATEGY_TYPE:SEQUENTIAL_BY_ORIGINATOR}" # BURST, BATCH, SEQUENTIAL_BY_ORIGINATOR, SEQUENTIAL_BY_TENANT, SEQUENTIAL | ||
358 | + # For BATCH only | ||
359 | + batch-size: "${TB_QUEUE_RE_SQ_SUBMIT_STRATEGY_BATCH_SIZE:100}" # Maximum number of messages in batch | ||
360 | + processing-strategy: | ||
361 | + type: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_TYPE:RETRY_FAILED_AND_TIMED_OUT}" # SKIP_ALL_FAILURES, RETRY_ALL, RETRY_FAILED, RETRY_TIMED_OUT, RETRY_FAILED_AND_TIMED_OUT | ||
362 | + # For RETRY_ALL, RETRY_FAILED, RETRY_TIMED_OUT, RETRY_FAILED_AND_TIMED_OUT | ||
363 | + retries: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_RETRIES:3}" # Number of retries, 0 is unlimited | ||
364 | + failure-percentage: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages; | ||
365 | + pause-between-retries: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_RETRY_PAUSE:5}"# Time in seconds to wait in consumer thread before retries; | ||
366 | + max-pause-between-retries: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_MAX_RETRY_PAUSE:5}"# Max allowed time in seconds for pause between retries. | ||
367 | + transport: | ||
368 | + # For high priority notifications that require minimum latency and processing time | ||
369 | + notifications_topic: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_TOPIC:tb_transport.notifications}" | ||
370 | + poll_interval: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_POLL_INTERVAL_MS:25}" | ||
371 | + | ||
372 | +event: | ||
373 | + debug: | ||
374 | + max-symbols: "${TB_MAX_DEBUG_EVENT_SYMBOLS:4096}" | ||
375 | + | ||
376 | +service: | ||
377 | + type: "${TB_SERVICE_TYPE:tb-transport}" | ||
378 | + # Unique id for this service (autogenerated if empty) | ||
379 | + id: "${TB_SERVICE_ID:}" | ||
380 | + tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id. | ||
381 | + | ||
382 | +metrics: | ||
383 | + # Enable/disable actuator metrics. | ||
384 | + enabled: "${METRICS_ENABLED:false}" | ||
385 | + timer: | ||
386 | + # Metrics percentiles returned by actuator for timer metrics. List of double values (divided by ,). | ||
387 | + percentiles: "${METRICS_TIMER_PERCENTILES:0.5}" | ||
388 | + | ||
389 | +management: | ||
390 | + endpoints: | ||
391 | + web: | ||
392 | + exposure: | ||
393 | + # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). | ||
394 | + include: '${METRICS_ENDPOINTS_EXPOSE:info}' |