Commit 1a6826c07c278e895696c059ac08f8b00859f77c
Committed by
GitHub
Merge pull request #180 from thingsboard/feature/TB-66
TB-66: Add support of device type mapping in the IoT Gateway
Showing
5 changed files
with
42 additions
and
15 deletions
@@ -37,6 +37,7 @@ import org.thingsboard.server.common.transport.adaptor.AdaptorException; | @@ -37,6 +37,7 @@ import org.thingsboard.server.common.transport.adaptor.AdaptorException; | ||
37 | import org.thingsboard.server.common.transport.auth.DeviceAuthService; | 37 | import org.thingsboard.server.common.transport.auth.DeviceAuthService; |
38 | import org.thingsboard.server.dao.EncryptionUtil; | 38 | import org.thingsboard.server.dao.EncryptionUtil; |
39 | import org.thingsboard.server.dao.device.DeviceService; | 39 | import org.thingsboard.server.dao.device.DeviceService; |
40 | +import org.thingsboard.server.dao.relation.RelationService; | ||
40 | import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; | 41 | import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; |
41 | import org.thingsboard.server.transport.mqtt.session.GatewaySessionCtx; | 42 | import org.thingsboard.server.transport.mqtt.session.GatewaySessionCtx; |
42 | import org.thingsboard.server.transport.mqtt.session.DeviceSessionCtx; | 43 | import org.thingsboard.server.transport.mqtt.session.DeviceSessionCtx; |
@@ -67,14 +68,16 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | @@ -67,14 +68,16 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | ||
67 | private final SessionMsgProcessor processor; | 68 | private final SessionMsgProcessor processor; |
68 | private final DeviceService deviceService; | 69 | private final DeviceService deviceService; |
69 | private final DeviceAuthService authService; | 70 | private final DeviceAuthService authService; |
71 | + private final RelationService relationService; | ||
70 | private final SslHandler sslHandler; | 72 | private final SslHandler sslHandler; |
71 | private volatile boolean connected; | 73 | private volatile boolean connected; |
72 | private volatile GatewaySessionCtx gatewaySessionCtx; | 74 | private volatile GatewaySessionCtx gatewaySessionCtx; |
73 | 75 | ||
74 | - public MqttTransportHandler(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, | 76 | + public MqttTransportHandler(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, RelationService relationService, |
75 | MqttTransportAdaptor adaptor, SslHandler sslHandler) { | 77 | MqttTransportAdaptor adaptor, SslHandler sslHandler) { |
76 | this.processor = processor; | 78 | this.processor = processor; |
77 | this.deviceService = deviceService; | 79 | this.deviceService = deviceService; |
80 | + this.relationService = relationService; | ||
78 | this.authService = authService; | 81 | this.authService = authService; |
79 | this.adaptor = adaptor; | 82 | this.adaptor = adaptor; |
80 | this.deviceSessionCtx = new DeviceSessionCtx(processor, authService, adaptor); | 83 | this.deviceSessionCtx = new DeviceSessionCtx(processor, authService, adaptor); |
@@ -371,7 +374,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | @@ -371,7 +374,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | ||
371 | if (infoNode != null) { | 374 | if (infoNode != null) { |
372 | JsonNode gatewayNode = infoNode.get("gateway"); | 375 | JsonNode gatewayNode = infoNode.get("gateway"); |
373 | if (gatewayNode != null && gatewayNode.asBoolean()) { | 376 | if (gatewayNode != null && gatewayNode.asBoolean()) { |
374 | - gatewaySessionCtx = new GatewaySessionCtx(processor, deviceService, authService, deviceSessionCtx); | 377 | + gatewaySessionCtx = new GatewaySessionCtx(processor, deviceService, authService, relationService, deviceSessionCtx); |
375 | } | 378 | } |
376 | } | 379 | } |
377 | } | 380 | } |
@@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Value; | @@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Value; | ||
30 | import org.thingsboard.server.common.transport.SessionMsgProcessor; | 30 | import org.thingsboard.server.common.transport.SessionMsgProcessor; |
31 | import org.thingsboard.server.common.transport.auth.DeviceAuthService; | 31 | import org.thingsboard.server.common.transport.auth.DeviceAuthService; |
32 | import org.thingsboard.server.dao.device.DeviceService; | 32 | import org.thingsboard.server.dao.device.DeviceService; |
33 | +import org.thingsboard.server.dao.relation.RelationService; | ||
33 | import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; | 34 | import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; |
34 | 35 | ||
35 | import javax.net.ssl.SSLException; | 36 | import javax.net.ssl.SSLException; |
@@ -45,14 +46,17 @@ public class MqttTransportServerInitializer extends ChannelInitializer<SocketCha | @@ -45,14 +46,17 @@ public class MqttTransportServerInitializer extends ChannelInitializer<SocketCha | ||
45 | private final SessionMsgProcessor processor; | 46 | private final SessionMsgProcessor processor; |
46 | private final DeviceService deviceService; | 47 | private final DeviceService deviceService; |
47 | private final DeviceAuthService authService; | 48 | private final DeviceAuthService authService; |
49 | + private final RelationService relationService; | ||
48 | private final MqttTransportAdaptor adaptor; | 50 | private final MqttTransportAdaptor adaptor; |
49 | private final MqttSslHandlerProvider sslHandlerProvider; | 51 | private final MqttSslHandlerProvider sslHandlerProvider; |
50 | 52 | ||
51 | - public MqttTransportServerInitializer(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, MqttTransportAdaptor adaptor, | 53 | + public MqttTransportServerInitializer(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, RelationService relationService, |
54 | + MqttTransportAdaptor adaptor, | ||
52 | MqttSslHandlerProvider sslHandlerProvider) { | 55 | MqttSslHandlerProvider sslHandlerProvider) { |
53 | this.processor = processor; | 56 | this.processor = processor; |
54 | this.deviceService = deviceService; | 57 | this.deviceService = deviceService; |
55 | this.authService = authService; | 58 | this.authService = authService; |
59 | + this.relationService = relationService; | ||
56 | this.adaptor = adaptor; | 60 | this.adaptor = adaptor; |
57 | this.sslHandlerProvider = sslHandlerProvider; | 61 | this.sslHandlerProvider = sslHandlerProvider; |
58 | } | 62 | } |
@@ -68,7 +72,7 @@ public class MqttTransportServerInitializer extends ChannelInitializer<SocketCha | @@ -68,7 +72,7 @@ public class MqttTransportServerInitializer extends ChannelInitializer<SocketCha | ||
68 | pipeline.addLast("decoder", new MqttDecoder(MAX_PAYLOAD_SIZE)); | 72 | pipeline.addLast("decoder", new MqttDecoder(MAX_PAYLOAD_SIZE)); |
69 | pipeline.addLast("encoder", MqttEncoder.INSTANCE); | 73 | pipeline.addLast("encoder", MqttEncoder.INSTANCE); |
70 | 74 | ||
71 | - MqttTransportHandler handler = new MqttTransportHandler(processor, deviceService, authService, adaptor, sslHandler); | 75 | + MqttTransportHandler handler = new MqttTransportHandler(processor, deviceService, authService, relationService, adaptor, sslHandler); |
72 | pipeline.addLast(handler); | 76 | pipeline.addLast(handler); |
73 | ch.closeFuture().addListener(handler); | 77 | ch.closeFuture().addListener(handler); |
74 | } | 78 | } |
@@ -29,6 +29,7 @@ import org.springframework.stereotype.Service; | @@ -29,6 +29,7 @@ import org.springframework.stereotype.Service; | ||
29 | import org.thingsboard.server.common.transport.SessionMsgProcessor; | 29 | import org.thingsboard.server.common.transport.SessionMsgProcessor; |
30 | import org.thingsboard.server.common.transport.auth.DeviceAuthService; | 30 | import org.thingsboard.server.common.transport.auth.DeviceAuthService; |
31 | import org.thingsboard.server.dao.device.DeviceService; | 31 | import org.thingsboard.server.dao.device.DeviceService; |
32 | +import org.thingsboard.server.dao.relation.RelationService; | ||
32 | import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; | 33 | import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; |
33 | 34 | ||
34 | import javax.annotation.PostConstruct; | 35 | import javax.annotation.PostConstruct; |
@@ -57,6 +58,9 @@ public class MqttTransportService { | @@ -57,6 +58,9 @@ public class MqttTransportService { | ||
57 | private DeviceAuthService authService; | 58 | private DeviceAuthService authService; |
58 | 59 | ||
59 | @Autowired(required = false) | 60 | @Autowired(required = false) |
61 | + private RelationService relationService; | ||
62 | + | ||
63 | + @Autowired(required = false) | ||
60 | private MqttSslHandlerProvider sslHandlerProvider; | 64 | private MqttSslHandlerProvider sslHandlerProvider; |
61 | 65 | ||
62 | @Value("${mqtt.bind_address}") | 66 | @Value("${mqtt.bind_address}") |
@@ -95,7 +99,7 @@ public class MqttTransportService { | @@ -95,7 +99,7 @@ public class MqttTransportService { | ||
95 | ServerBootstrap b = new ServerBootstrap(); | 99 | ServerBootstrap b = new ServerBootstrap(); |
96 | b.group(bossGroup, workerGroup) | 100 | b.group(bossGroup, workerGroup) |
97 | .channel(NioServerSocketChannel.class) | 101 | .channel(NioServerSocketChannel.class) |
98 | - .childHandler(new MqttTransportServerInitializer(processor, deviceService, authService, adaptor, sslHandlerProvider)); | 102 | + .childHandler(new MqttTransportServerInitializer(processor, deviceService, authService, relationService, adaptor, sslHandlerProvider)); |
99 | 103 | ||
100 | serverChannel = b.bind(host, port).sync().channel(); | 104 | serverChannel = b.bind(host, port).sync().channel(); |
101 | log.info("Mqtt transport started!"); | 105 | log.info("Mqtt transport started!"); |
@@ -27,6 +27,7 @@ import org.springframework.util.StringUtils; | @@ -27,6 +27,7 @@ import org.springframework.util.StringUtils; | ||
27 | import org.thingsboard.server.common.data.Device; | 27 | import org.thingsboard.server.common.data.Device; |
28 | import org.thingsboard.server.common.data.id.SessionId; | 28 | import org.thingsboard.server.common.data.id.SessionId; |
29 | import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; | 29 | import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
30 | +import org.thingsboard.server.common.data.relation.EntityRelation; | ||
30 | import org.thingsboard.server.common.msg.core.*; | 31 | import org.thingsboard.server.common.msg.core.*; |
31 | import org.thingsboard.server.common.msg.session.BasicAdaptorToSessionActorMsg; | 32 | import org.thingsboard.server.common.msg.session.BasicAdaptorToSessionActorMsg; |
32 | import org.thingsboard.server.common.msg.session.BasicToDeviceActorSessionMsg; | 33 | import org.thingsboard.server.common.msg.session.BasicToDeviceActorSessionMsg; |
@@ -36,6 +37,7 @@ import org.thingsboard.server.common.transport.adaptor.AdaptorException; | @@ -36,6 +37,7 @@ import org.thingsboard.server.common.transport.adaptor.AdaptorException; | ||
36 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; | 37 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; |
37 | import org.thingsboard.server.common.transport.auth.DeviceAuthService; | 38 | import org.thingsboard.server.common.transport.auth.DeviceAuthService; |
38 | import org.thingsboard.server.dao.device.DeviceService; | 39 | import org.thingsboard.server.dao.device.DeviceService; |
40 | +import org.thingsboard.server.dao.relation.RelationService; | ||
39 | import org.thingsboard.server.transport.mqtt.MqttTransportHandler; | 41 | import org.thingsboard.server.transport.mqtt.MqttTransportHandler; |
40 | import org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor; | 42 | import org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor; |
41 | 43 | ||
@@ -58,28 +60,34 @@ public class GatewaySessionCtx { | @@ -58,28 +60,34 @@ public class GatewaySessionCtx { | ||
58 | private final SessionMsgProcessor processor; | 60 | private final SessionMsgProcessor processor; |
59 | private final DeviceService deviceService; | 61 | private final DeviceService deviceService; |
60 | private final DeviceAuthService authService; | 62 | private final DeviceAuthService authService; |
63 | + private final RelationService relationService; | ||
61 | private final Map<String, GatewayDeviceSessionCtx> devices; | 64 | private final Map<String, GatewayDeviceSessionCtx> devices; |
62 | private ChannelHandlerContext channel; | 65 | private ChannelHandlerContext channel; |
63 | 66 | ||
64 | - public GatewaySessionCtx(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, DeviceSessionCtx gatewaySessionCtx) { | 67 | + public GatewaySessionCtx(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, RelationService relationService, DeviceSessionCtx gatewaySessionCtx) { |
65 | this.processor = processor; | 68 | this.processor = processor; |
66 | this.deviceService = deviceService; | 69 | this.deviceService = deviceService; |
67 | this.authService = authService; | 70 | this.authService = authService; |
71 | + this.relationService = relationService; | ||
68 | this.gateway = gatewaySessionCtx.getDevice(); | 72 | this.gateway = gatewaySessionCtx.getDevice(); |
69 | this.gatewaySessionId = gatewaySessionCtx.getSessionId(); | 73 | this.gatewaySessionId = gatewaySessionCtx.getSessionId(); |
70 | this.devices = new HashMap<>(); | 74 | this.devices = new HashMap<>(); |
71 | } | 75 | } |
72 | 76 | ||
73 | public void onDeviceConnect(MqttPublishMessage msg) throws AdaptorException { | 77 | public void onDeviceConnect(MqttPublishMessage msg) throws AdaptorException { |
74 | - String deviceName = checkDeviceName(getDeviceName(msg)); | 78 | + JsonElement json = getJson(msg); |
79 | + String deviceName = checkDeviceName(getDeviceName(json)); | ||
80 | + String deviceType = getDeviceType(json); | ||
75 | if (!devices.containsKey(deviceName)) { | 81 | if (!devices.containsKey(deviceName)) { |
76 | Optional<Device> deviceOpt = deviceService.findDeviceByTenantIdAndName(gateway.getTenantId(), deviceName); | 82 | Optional<Device> deviceOpt = deviceService.findDeviceByTenantIdAndName(gateway.getTenantId(), deviceName); |
77 | Device device = deviceOpt.orElseGet(() -> { | 83 | Device device = deviceOpt.orElseGet(() -> { |
78 | Device newDevice = new Device(); | 84 | Device newDevice = new Device(); |
79 | newDevice.setTenantId(gateway.getTenantId()); | 85 | newDevice.setTenantId(gateway.getTenantId()); |
80 | newDevice.setName(deviceName); | 86 | newDevice.setName(deviceName); |
81 | - newDevice.setType("default"); | ||
82 | - return deviceService.saveDevice(newDevice); | 87 | + newDevice.setType(deviceType); |
88 | + newDevice = deviceService.saveDevice(newDevice); | ||
89 | + relationService.saveRelation(new EntityRelation(gateway.getId(), newDevice.getId(), "Created")); | ||
90 | + return newDevice; | ||
83 | }); | 91 | }); |
84 | GatewayDeviceSessionCtx ctx = new GatewayDeviceSessionCtx(this, device); | 92 | GatewayDeviceSessionCtx ctx = new GatewayDeviceSessionCtx(this, device); |
85 | devices.put(deviceName, ctx); | 93 | devices.put(deviceName, ctx); |
@@ -91,7 +99,7 @@ public class GatewaySessionCtx { | @@ -91,7 +99,7 @@ public class GatewaySessionCtx { | ||
91 | } | 99 | } |
92 | 100 | ||
93 | public void onDeviceDisconnect(MqttPublishMessage msg) throws AdaptorException { | 101 | public void onDeviceDisconnect(MqttPublishMessage msg) throws AdaptorException { |
94 | - String deviceName = checkDeviceName(getDeviceName(msg)); | 102 | + String deviceName = checkDeviceName(getDeviceName(getJson(msg))); |
95 | GatewayDeviceSessionCtx deviceSessionCtx = devices.remove(deviceName); | 103 | GatewayDeviceSessionCtx deviceSessionCtx = devices.remove(deviceName); |
96 | if (deviceSessionCtx != null) { | 104 | if (deviceSessionCtx != null) { |
97 | processor.process(SessionCloseMsg.onDisconnect(deviceSessionCtx.getSessionId())); | 105 | processor.process(SessionCloseMsg.onDisconnect(deviceSessionCtx.getSessionId())); |
@@ -211,11 +219,19 @@ public class GatewaySessionCtx { | @@ -211,11 +219,19 @@ public class GatewaySessionCtx { | ||
211 | } | 219 | } |
212 | } | 220 | } |
213 | 221 | ||
214 | - private String getDeviceName(MqttPublishMessage mqttMsg) throws AdaptorException { | ||
215 | - JsonElement json = JsonMqttAdaptor.validateJsonPayload(gatewaySessionId, mqttMsg.payload()); | 222 | + private String getDeviceName(JsonElement json) throws AdaptorException { |
216 | return json.getAsJsonObject().get("device").getAsString(); | 223 | return json.getAsJsonObject().get("device").getAsString(); |
217 | } | 224 | } |
218 | 225 | ||
226 | + private String getDeviceType(JsonElement json) throws AdaptorException { | ||
227 | + JsonElement type = json.getAsJsonObject().get("type"); | ||
228 | + return type == null ? "default" : type.getAsString(); | ||
229 | + } | ||
230 | + | ||
231 | + private JsonElement getJson(MqttPublishMessage mqttMsg) throws AdaptorException { | ||
232 | + return JsonMqttAdaptor.validateJsonPayload(gatewaySessionId, mqttMsg.payload()); | ||
233 | + } | ||
234 | + | ||
219 | protected SessionMsgProcessor getProcessor() { | 235 | protected SessionMsgProcessor getProcessor() { |
220 | return processor; | 236 | return processor; |
221 | } | 237 | } |
@@ -229,7 +245,9 @@ public class GatewaySessionCtx { | @@ -229,7 +245,9 @@ public class GatewaySessionCtx { | ||
229 | } | 245 | } |
230 | 246 | ||
231 | private void ack(MqttPublishMessage msg) { | 247 | private void ack(MqttPublishMessage msg) { |
232 | - writeAndFlush(MqttTransportHandler.createMqttPubAckMsg(msg.variableHeader().messageId())); | 248 | + if(msg.variableHeader().messageId() > 0) { |
249 | + writeAndFlush(MqttTransportHandler.createMqttPubAckMsg(msg.variableHeader().messageId())); | ||
250 | + } | ||
233 | } | 251 | } |
234 | 252 | ||
235 | protected void writeAndFlush(MqttMessage mqttMessage) { | 253 | protected void writeAndFlush(MqttMessage mqttMessage) { |
@@ -18,9 +18,7 @@ package org.thingsboard.server.transport.mqtt.util; | @@ -18,9 +18,7 @@ package org.thingsboard.server.transport.mqtt.util; | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | import org.springframework.util.Base64Utils; | 19 | import org.springframework.util.Base64Utils; |
20 | import org.thingsboard.server.dao.EncryptionUtil; | 20 | import org.thingsboard.server.dao.EncryptionUtil; |
21 | -import sun.misc.BASE64Encoder; | ||
22 | 21 | ||
23 | -import java.io.ByteArrayOutputStream; | ||
24 | import java.io.IOException; | 22 | import java.io.IOException; |
25 | import java.security.cert.CertificateEncodingException; | 23 | import java.security.cert.CertificateEncodingException; |
26 | import java.security.cert.X509Certificate; | 24 | import java.security.cert.X509Certificate; |