Merge pull request #180 from thingsboard/feature/TB-66
TB-66: Add support of device type mapping in the IoT Gateway
This commit is contained in:
commit
1a6826c07c
@ -37,6 +37,7 @@ import org.thingsboard.server.common.transport.adaptor.AdaptorException;
|
|||||||
import org.thingsboard.server.common.transport.auth.DeviceAuthService;
|
import org.thingsboard.server.common.transport.auth.DeviceAuthService;
|
||||||
import org.thingsboard.server.dao.EncryptionUtil;
|
import org.thingsboard.server.dao.EncryptionUtil;
|
||||||
import org.thingsboard.server.dao.device.DeviceService;
|
import org.thingsboard.server.dao.device.DeviceService;
|
||||||
|
import org.thingsboard.server.dao.relation.RelationService;
|
||||||
import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor;
|
import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor;
|
||||||
import org.thingsboard.server.transport.mqtt.session.GatewaySessionCtx;
|
import org.thingsboard.server.transport.mqtt.session.GatewaySessionCtx;
|
||||||
import org.thingsboard.server.transport.mqtt.session.DeviceSessionCtx;
|
import org.thingsboard.server.transport.mqtt.session.DeviceSessionCtx;
|
||||||
@ -67,14 +68,16 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
|
|||||||
private final SessionMsgProcessor processor;
|
private final SessionMsgProcessor processor;
|
||||||
private final DeviceService deviceService;
|
private final DeviceService deviceService;
|
||||||
private final DeviceAuthService authService;
|
private final DeviceAuthService authService;
|
||||||
|
private final RelationService relationService;
|
||||||
private final SslHandler sslHandler;
|
private final SslHandler sslHandler;
|
||||||
private volatile boolean connected;
|
private volatile boolean connected;
|
||||||
private volatile GatewaySessionCtx gatewaySessionCtx;
|
private volatile GatewaySessionCtx gatewaySessionCtx;
|
||||||
|
|
||||||
public MqttTransportHandler(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService,
|
public MqttTransportHandler(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, RelationService relationService,
|
||||||
MqttTransportAdaptor adaptor, SslHandler sslHandler) {
|
MqttTransportAdaptor adaptor, SslHandler sslHandler) {
|
||||||
this.processor = processor;
|
this.processor = processor;
|
||||||
this.deviceService = deviceService;
|
this.deviceService = deviceService;
|
||||||
|
this.relationService = relationService;
|
||||||
this.authService = authService;
|
this.authService = authService;
|
||||||
this.adaptor = adaptor;
|
this.adaptor = adaptor;
|
||||||
this.deviceSessionCtx = new DeviceSessionCtx(processor, authService, adaptor);
|
this.deviceSessionCtx = new DeviceSessionCtx(processor, authService, adaptor);
|
||||||
@ -371,7 +374,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
|
|||||||
if (infoNode != null) {
|
if (infoNode != null) {
|
||||||
JsonNode gatewayNode = infoNode.get("gateway");
|
JsonNode gatewayNode = infoNode.get("gateway");
|
||||||
if (gatewayNode != null && gatewayNode.asBoolean()) {
|
if (gatewayNode != null && gatewayNode.asBoolean()) {
|
||||||
gatewaySessionCtx = new GatewaySessionCtx(processor, deviceService, authService, deviceSessionCtx);
|
gatewaySessionCtx = new GatewaySessionCtx(processor, deviceService, authService, relationService, deviceSessionCtx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Value;
|
|||||||
import org.thingsboard.server.common.transport.SessionMsgProcessor;
|
import org.thingsboard.server.common.transport.SessionMsgProcessor;
|
||||||
import org.thingsboard.server.common.transport.auth.DeviceAuthService;
|
import org.thingsboard.server.common.transport.auth.DeviceAuthService;
|
||||||
import org.thingsboard.server.dao.device.DeviceService;
|
import org.thingsboard.server.dao.device.DeviceService;
|
||||||
|
import org.thingsboard.server.dao.relation.RelationService;
|
||||||
import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor;
|
import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor;
|
||||||
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
@ -45,14 +46,17 @@ public class MqttTransportServerInitializer extends ChannelInitializer<SocketCha
|
|||||||
private final SessionMsgProcessor processor;
|
private final SessionMsgProcessor processor;
|
||||||
private final DeviceService deviceService;
|
private final DeviceService deviceService;
|
||||||
private final DeviceAuthService authService;
|
private final DeviceAuthService authService;
|
||||||
|
private final RelationService relationService;
|
||||||
private final MqttTransportAdaptor adaptor;
|
private final MqttTransportAdaptor adaptor;
|
||||||
private final MqttSslHandlerProvider sslHandlerProvider;
|
private final MqttSslHandlerProvider sslHandlerProvider;
|
||||||
|
|
||||||
public MqttTransportServerInitializer(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, MqttTransportAdaptor adaptor,
|
public MqttTransportServerInitializer(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, RelationService relationService,
|
||||||
|
MqttTransportAdaptor adaptor,
|
||||||
MqttSslHandlerProvider sslHandlerProvider) {
|
MqttSslHandlerProvider sslHandlerProvider) {
|
||||||
this.processor = processor;
|
this.processor = processor;
|
||||||
this.deviceService = deviceService;
|
this.deviceService = deviceService;
|
||||||
this.authService = authService;
|
this.authService = authService;
|
||||||
|
this.relationService = relationService;
|
||||||
this.adaptor = adaptor;
|
this.adaptor = adaptor;
|
||||||
this.sslHandlerProvider = sslHandlerProvider;
|
this.sslHandlerProvider = sslHandlerProvider;
|
||||||
}
|
}
|
||||||
@ -68,7 +72,7 @@ public class MqttTransportServerInitializer extends ChannelInitializer<SocketCha
|
|||||||
pipeline.addLast("decoder", new MqttDecoder(MAX_PAYLOAD_SIZE));
|
pipeline.addLast("decoder", new MqttDecoder(MAX_PAYLOAD_SIZE));
|
||||||
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
|
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
|
||||||
|
|
||||||
MqttTransportHandler handler = new MqttTransportHandler(processor, deviceService, authService, adaptor, sslHandler);
|
MqttTransportHandler handler = new MqttTransportHandler(processor, deviceService, authService, relationService, adaptor, sslHandler);
|
||||||
pipeline.addLast(handler);
|
pipeline.addLast(handler);
|
||||||
ch.closeFuture().addListener(handler);
|
ch.closeFuture().addListener(handler);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.thingsboard.server.common.transport.SessionMsgProcessor;
|
import org.thingsboard.server.common.transport.SessionMsgProcessor;
|
||||||
import org.thingsboard.server.common.transport.auth.DeviceAuthService;
|
import org.thingsboard.server.common.transport.auth.DeviceAuthService;
|
||||||
import org.thingsboard.server.dao.device.DeviceService;
|
import org.thingsboard.server.dao.device.DeviceService;
|
||||||
|
import org.thingsboard.server.dao.relation.RelationService;
|
||||||
import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor;
|
import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
@ -56,6 +57,9 @@ public class MqttTransportService {
|
|||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private DeviceAuthService authService;
|
private DeviceAuthService authService;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private RelationService relationService;
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private MqttSslHandlerProvider sslHandlerProvider;
|
private MqttSslHandlerProvider sslHandlerProvider;
|
||||||
|
|
||||||
@ -95,7 +99,7 @@ public class MqttTransportService {
|
|||||||
ServerBootstrap b = new ServerBootstrap();
|
ServerBootstrap b = new ServerBootstrap();
|
||||||
b.group(bossGroup, workerGroup)
|
b.group(bossGroup, workerGroup)
|
||||||
.channel(NioServerSocketChannel.class)
|
.channel(NioServerSocketChannel.class)
|
||||||
.childHandler(new MqttTransportServerInitializer(processor, deviceService, authService, adaptor, sslHandlerProvider));
|
.childHandler(new MqttTransportServerInitializer(processor, deviceService, authService, relationService, adaptor, sslHandlerProvider));
|
||||||
|
|
||||||
serverChannel = b.bind(host, port).sync().channel();
|
serverChannel = b.bind(host, port).sync().channel();
|
||||||
log.info("Mqtt transport started!");
|
log.info("Mqtt transport started!");
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import org.springframework.util.StringUtils;
|
|||||||
import org.thingsboard.server.common.data.Device;
|
import org.thingsboard.server.common.data.Device;
|
||||||
import org.thingsboard.server.common.data.id.SessionId;
|
import org.thingsboard.server.common.data.id.SessionId;
|
||||||
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
|
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
|
||||||
|
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||||
import org.thingsboard.server.common.msg.core.*;
|
import org.thingsboard.server.common.msg.core.*;
|
||||||
import org.thingsboard.server.common.msg.session.BasicAdaptorToSessionActorMsg;
|
import org.thingsboard.server.common.msg.session.BasicAdaptorToSessionActorMsg;
|
||||||
import org.thingsboard.server.common.msg.session.BasicToDeviceActorSessionMsg;
|
import org.thingsboard.server.common.msg.session.BasicToDeviceActorSessionMsg;
|
||||||
@ -36,6 +37,7 @@ import org.thingsboard.server.common.transport.adaptor.AdaptorException;
|
|||||||
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
|
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
|
||||||
import org.thingsboard.server.common.transport.auth.DeviceAuthService;
|
import org.thingsboard.server.common.transport.auth.DeviceAuthService;
|
||||||
import org.thingsboard.server.dao.device.DeviceService;
|
import org.thingsboard.server.dao.device.DeviceService;
|
||||||
|
import org.thingsboard.server.dao.relation.RelationService;
|
||||||
import org.thingsboard.server.transport.mqtt.MqttTransportHandler;
|
import org.thingsboard.server.transport.mqtt.MqttTransportHandler;
|
||||||
import org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor;
|
import org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor;
|
||||||
|
|
||||||
@ -58,28 +60,34 @@ public class GatewaySessionCtx {
|
|||||||
private final SessionMsgProcessor processor;
|
private final SessionMsgProcessor processor;
|
||||||
private final DeviceService deviceService;
|
private final DeviceService deviceService;
|
||||||
private final DeviceAuthService authService;
|
private final DeviceAuthService authService;
|
||||||
|
private final RelationService relationService;
|
||||||
private final Map<String, GatewayDeviceSessionCtx> devices;
|
private final Map<String, GatewayDeviceSessionCtx> devices;
|
||||||
private ChannelHandlerContext channel;
|
private ChannelHandlerContext channel;
|
||||||
|
|
||||||
public GatewaySessionCtx(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, DeviceSessionCtx gatewaySessionCtx) {
|
public GatewaySessionCtx(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, RelationService relationService, DeviceSessionCtx gatewaySessionCtx) {
|
||||||
this.processor = processor;
|
this.processor = processor;
|
||||||
this.deviceService = deviceService;
|
this.deviceService = deviceService;
|
||||||
this.authService = authService;
|
this.authService = authService;
|
||||||
|
this.relationService = relationService;
|
||||||
this.gateway = gatewaySessionCtx.getDevice();
|
this.gateway = gatewaySessionCtx.getDevice();
|
||||||
this.gatewaySessionId = gatewaySessionCtx.getSessionId();
|
this.gatewaySessionId = gatewaySessionCtx.getSessionId();
|
||||||
this.devices = new HashMap<>();
|
this.devices = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDeviceConnect(MqttPublishMessage msg) throws AdaptorException {
|
public void onDeviceConnect(MqttPublishMessage msg) throws AdaptorException {
|
||||||
String deviceName = checkDeviceName(getDeviceName(msg));
|
JsonElement json = getJson(msg);
|
||||||
|
String deviceName = checkDeviceName(getDeviceName(json));
|
||||||
|
String deviceType = getDeviceType(json);
|
||||||
if (!devices.containsKey(deviceName)) {
|
if (!devices.containsKey(deviceName)) {
|
||||||
Optional<Device> deviceOpt = deviceService.findDeviceByTenantIdAndName(gateway.getTenantId(), deviceName);
|
Optional<Device> deviceOpt = deviceService.findDeviceByTenantIdAndName(gateway.getTenantId(), deviceName);
|
||||||
Device device = deviceOpt.orElseGet(() -> {
|
Device device = deviceOpt.orElseGet(() -> {
|
||||||
Device newDevice = new Device();
|
Device newDevice = new Device();
|
||||||
newDevice.setTenantId(gateway.getTenantId());
|
newDevice.setTenantId(gateway.getTenantId());
|
||||||
newDevice.setName(deviceName);
|
newDevice.setName(deviceName);
|
||||||
newDevice.setType("default");
|
newDevice.setType(deviceType);
|
||||||
return deviceService.saveDevice(newDevice);
|
newDevice = deviceService.saveDevice(newDevice);
|
||||||
|
relationService.saveRelation(new EntityRelation(gateway.getId(), newDevice.getId(), "Created"));
|
||||||
|
return newDevice;
|
||||||
});
|
});
|
||||||
GatewayDeviceSessionCtx ctx = new GatewayDeviceSessionCtx(this, device);
|
GatewayDeviceSessionCtx ctx = new GatewayDeviceSessionCtx(this, device);
|
||||||
devices.put(deviceName, ctx);
|
devices.put(deviceName, ctx);
|
||||||
@ -91,7 +99,7 @@ public class GatewaySessionCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onDeviceDisconnect(MqttPublishMessage msg) throws AdaptorException {
|
public void onDeviceDisconnect(MqttPublishMessage msg) throws AdaptorException {
|
||||||
String deviceName = checkDeviceName(getDeviceName(msg));
|
String deviceName = checkDeviceName(getDeviceName(getJson(msg)));
|
||||||
GatewayDeviceSessionCtx deviceSessionCtx = devices.remove(deviceName);
|
GatewayDeviceSessionCtx deviceSessionCtx = devices.remove(deviceName);
|
||||||
if (deviceSessionCtx != null) {
|
if (deviceSessionCtx != null) {
|
||||||
processor.process(SessionCloseMsg.onDisconnect(deviceSessionCtx.getSessionId()));
|
processor.process(SessionCloseMsg.onDisconnect(deviceSessionCtx.getSessionId()));
|
||||||
@ -211,11 +219,19 @@ public class GatewaySessionCtx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDeviceName(MqttPublishMessage mqttMsg) throws AdaptorException {
|
private String getDeviceName(JsonElement json) throws AdaptorException {
|
||||||
JsonElement json = JsonMqttAdaptor.validateJsonPayload(gatewaySessionId, mqttMsg.payload());
|
|
||||||
return json.getAsJsonObject().get("device").getAsString();
|
return json.getAsJsonObject().get("device").getAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getDeviceType(JsonElement json) throws AdaptorException {
|
||||||
|
JsonElement type = json.getAsJsonObject().get("type");
|
||||||
|
return type == null ? "default" : type.getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonElement getJson(MqttPublishMessage mqttMsg) throws AdaptorException {
|
||||||
|
return JsonMqttAdaptor.validateJsonPayload(gatewaySessionId, mqttMsg.payload());
|
||||||
|
}
|
||||||
|
|
||||||
protected SessionMsgProcessor getProcessor() {
|
protected SessionMsgProcessor getProcessor() {
|
||||||
return processor;
|
return processor;
|
||||||
}
|
}
|
||||||
@ -229,7 +245,9 @@ public class GatewaySessionCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void ack(MqttPublishMessage msg) {
|
private void ack(MqttPublishMessage msg) {
|
||||||
writeAndFlush(MqttTransportHandler.createMqttPubAckMsg(msg.variableHeader().messageId()));
|
if(msg.variableHeader().messageId() > 0) {
|
||||||
|
writeAndFlush(MqttTransportHandler.createMqttPubAckMsg(msg.variableHeader().messageId()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeAndFlush(MqttMessage mqttMessage) {
|
protected void writeAndFlush(MqttMessage mqttMessage) {
|
||||||
|
|||||||
@ -18,9 +18,7 @@ package org.thingsboard.server.transport.mqtt.util;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.util.Base64Utils;
|
import org.springframework.util.Base64Utils;
|
||||||
import org.thingsboard.server.dao.EncryptionUtil;
|
import org.thingsboard.server.dao.EncryptionUtil;
|
||||||
import sun.misc.BASE64Encoder;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.cert.CertificateEncodingException;
|
import java.security.cert.CertificateEncodingException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user