Commit 1a6826c07c278e895696c059ac08f8b00859f77c

Authored by Andrew Shvayka
Committed by GitHub
2 parents f93dc905 859c1f8e

Merge pull request #180 from thingsboard/feature/TB-66

TB-66: Add support of device type mapping in the IoT Gateway
@@ -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;