diff --git a/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java b/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java index 2e2f1cbb80..6f88cec33b 100644 --- a/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java +++ b/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java @@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; import org.thingsboard.server.common.data.device.profile.AllowCreateNewDevicesDeviceProfileProvisionConfiguration; import org.thingsboard.server.common.data.device.profile.CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration; import org.thingsboard.server.common.data.id.CustomerId; @@ -118,6 +119,13 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND)); } + if (provisionRequest.getCredentialsType() != null) { + ListenableFuture error = validateCredentials(provisionRequest); + if (error != null) { + return error; + } + } + DeviceProfile targetProfile = deviceProfileDao.findByProvisionDeviceKey(provisionRequestKey); if (targetProfile == null) { @@ -152,6 +160,32 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND)); } + private ListenableFuture validateCredentials(ProvisionRequest provisionRequest) { + switch (provisionRequest.getCredentialsType()) { + case ACCESS_TOKEN: + if (StringUtils.isEmpty(provisionRequest.getCredentialsData().getToken())) { + log.error("Failed to get token from credentials data!"); + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE)); + } + break; + case MQTT_BASIC: + if (StringUtils.isEmpty(provisionRequest.getCredentialsData().getClientId()) || + StringUtils.isEmpty(provisionRequest.getCredentialsData().getUsername()) || + StringUtils.isEmpty(provisionRequest.getCredentialsData().getPassword())) { + log.error("Failed to get basic mqtt credentials from credentials data!"); + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE)); + } + break; + case X509_CERTIFICATE: + if (StringUtils.isEmpty(provisionRequest.getCredentialsData().getHash())) { + log.error("Failed to get hash from credentials data!"); + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE)); + } + break; + } + return null; + } + private ListenableFuture processProvision(Device device, ProvisionRequest provisionRequest) { ListenableFuture> provisionStateFuture = attributesService.find(device.getTenantId(), device.getId(), DataConstants.SERVER_SCOPE, DEVICE_PROVISION_STATE); @@ -205,7 +239,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { return Futures.transform(saveProvisionStateAttribute(savedDevice), input -> new ProvisionResponse( - getDeviceCredentials(savedDevice, provisionRequest.getX509CertPubKey()), + getDeviceCredentials(savedDevice), ProvisionResponseStatus.SUCCESS), MoreExecutors.directExecutor()); } log.warn("[{}] The device is already provisioned!", device.getName()); @@ -224,17 +258,33 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { device.setName(provisionRequest.getDeviceName()); device.setType(profile.getName()); device.setTenantId(profile.getTenantId()); - return deviceService.saveDevice(device); + Device savedDevice = deviceService.saveDevice(device); + if (provisionRequest.getCredentialsType() != null) { + DeviceCredentials deviceCredentials = new DeviceCredentials(); + deviceCredentials.setCredentialsType(provisionRequest.getCredentialsType()); + switch (provisionRequest.getCredentialsType()) { + case ACCESS_TOKEN: + deviceCredentials.setDeviceId(savedDevice.getId()); + deviceCredentials.setCredentialsId(provisionRequest.getCredentialsData().getToken()); + break; + case MQTT_BASIC: + BasicMqttCredentials mqttCredentials = new BasicMqttCredentials(); + mqttCredentials.setClientId(provisionRequest.getCredentialsData().getClientId()); + mqttCredentials.setUserName(provisionRequest.getCredentialsData().getUsername()); + mqttCredentials.setPassword(provisionRequest.getCredentialsData().getPassword()); + deviceCredentials.setCredentialsValue(JacksonUtil.toString(mqttCredentials)); + break; + case X509_CERTIFICATE: + deviceCredentials.setCredentialsValue(provisionRequest.getCredentialsData().getHash()); + break; + } + deviceCredentialsService.updateDeviceCredentials(savedDevice.getTenantId(), deviceCredentials); + } + return savedDevice; } - private DeviceCredentials getDeviceCredentials(Device device, String x509CertPubKey) { - DeviceCredentials credentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(device.getTenantId(), device.getId()); - if (!StringUtils.isEmpty(x509CertPubKey)) { - credentials.setCredentialsType(DeviceCredentialsType.X509_CERTIFICATE); - credentials.setCredentialsValue(x509CertPubKey); - return deviceCredentialsService.updateDeviceCredentials(device.getTenantId(), credentials); - } - return credentials; + private DeviceCredentials getDeviceCredentials(Device device) { + return deviceCredentialsService.findDeviceCredentialsByDeviceId(device.getTenantId(), device.getId()); } private void pushProvisionEventToRuleEngine(ProvisionRequest request, Device device, String type) { diff --git a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java index 7b4701754b..b2c93a0ecb 100644 --- a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java +++ b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java @@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; +import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData; import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; @@ -281,7 +282,12 @@ public class DefaultTransportApiService implements TransportApiService { provisionResponseFuture = deviceProvisionService.provisionDevice( new ProvisionRequest( requestMsg.getDeviceName(), - requestMsg.getX509CertPubKey(), + requestMsg.getCredentialsType() != null ? DeviceCredentialsType.valueOf(requestMsg.getCredentialsType().name()) : null, + new ProvisionDeviceCredentialsData(requestMsg.getCredentialsDataProto().getValidateDeviceTokenRequestMsg().getToken(), + requestMsg.getCredentialsDataProto().getValidateBasicMqttCredRequestMsg().getClientId(), + requestMsg.getCredentialsDataProto().getValidateBasicMqttCredRequestMsg().getUserName(), + requestMsg.getCredentialsDataProto().getValidateBasicMqttCredRequestMsg().getPassword(), + requestMsg.getCredentialsDataProto().getValidateDeviceX509CertRequestMsg().getHash()), new ProvisionDeviceProfileCredentials( requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceKey(), requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceSecret()))); diff --git a/application/src/test/java/org/thingsboard/server/mqtt/provision/AbstractMqttProvisionProtoDeviceTest.java b/application/src/test/java/org/thingsboard/server/mqtt/provision/AbstractMqttProvisionProtoDeviceTest.java index 7720ddad4a..54e99077ea 100644 --- a/application/src/test/java/org/thingsboard/server/mqtt/provision/AbstractMqttProvisionProtoDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/mqtt/provision/AbstractMqttProvisionProtoDeviceTest.java @@ -183,7 +183,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI protected byte[] createTestProvisionMessage() { - return ProvisionDeviceRequestMsg.newBuilder().setX509CertPubKey("").setDeviceName("Test Provision device").setProvisionDeviceCredentialsMsg(ProvisionDeviceCredentialsMsg.newBuilder().setProvisionDeviceKey("testProvisionKey").setProvisionDeviceSecret("testProvisionSecret")).build().toByteArray(); + return ProvisionDeviceRequestMsg.newBuilder().setDeviceName("Test Provision device").setProvisionDeviceCredentialsMsg(ProvisionDeviceCredentialsMsg.newBuilder().setProvisionDeviceKey("testProvisionKey").setProvisionDeviceSecret("testProvisionSecret")).build().toByteArray(); } } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/provision/ProvisionRequest.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/provision/ProvisionRequest.java index 1c743fd855..f45b541074 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/provision/ProvisionRequest.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/provision/ProvisionRequest.java @@ -17,12 +17,15 @@ package org.thingsboard.server.dao.device.provision; import lombok.AllArgsConstructor; import lombok.Data; +import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData; import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; +import org.thingsboard.server.common.data.security.DeviceCredentialsType; @Data @AllArgsConstructor public class ProvisionRequest { private String deviceName; - private String x509CertPubKey; + private DeviceCredentialsType credentialsType; + private ProvisionDeviceCredentialsData credentialsData; private ProvisionDeviceProfileCredentials credentials; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java index d2c4aaf60b..5aadca44ec 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java @@ -79,5 +79,11 @@ public class DataConstants { public static final String DEVICE_NAME = "deviceName"; public static final String DEVICE_TYPE = "deviceType"; public static final String CERT_PUB_KEY = "x509CertPubKey"; + public static final String CREDENTIALS_TYPE = "credentialsType"; + public static final String TOKEN = "token"; + public static final String HASH = "hash"; + public static final String CLIENT_ID = "clientId"; + public static final String USERNAME = "username"; + public static final String PASSWORD = "password"; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/credentials/ProvisionDeviceCredentialsData.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/credentials/ProvisionDeviceCredentialsData.java new file mode 100644 index 0000000000..a3e70afd83 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/credentials/ProvisionDeviceCredentialsData.java @@ -0,0 +1,27 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.device.credentials; + +import lombok.Data; + +@Data +public class ProvisionDeviceCredentialsData { + private final String token; + private final String clientId; + private final String username; + private final String password; + private final String hash; +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/MqttTopics.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/MqttTopics.java index 24086e4194..b226b87999 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/MqttTopics.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/MqttTopics.java @@ -68,8 +68,6 @@ public class MqttTopics { public static final String GATEWAY_RPC_TOPIC = BASE_GATEWAY_API_TOPIC + RPC; public static final String GATEWAY_ATTRIBUTES_REQUEST_TOPIC = BASE_GATEWAY_API_TOPIC + ATTRIBUTES_REQUEST; public static final String GATEWAY_ATTRIBUTES_RESPONSE_TOPIC = BASE_GATEWAY_API_TOPIC + ATTRIBUTES_RESPONSE; - public static final String GATEWAY_PROVISION_REQUEST_TOPIC = BASE_GATEWAY_API_TOPIC + PROVISION + REQUEST; - public static final String GATEWAY_PROVISION_RESPONSE_TOPIC = BASE_GATEWAY_API_TOPIC + PROVISION + RESPONSE; private MqttTopics() { } diff --git a/common/queue/src/main/proto/queue.proto b/common/queue/src/main/proto/queue.proto index 6a96f8a6d6..e6dc171550 100644 --- a/common/queue/src/main/proto/queue.proto +++ b/common/queue/src/main/proto/queue.proto @@ -76,6 +76,7 @@ enum KeyValueType { enum CredentialsType { ACCESS_TOKEN = 0; X509_CERTIFICATE = 1; + BASIC_MQTT = 2; } message KeyValueProto { @@ -254,10 +255,22 @@ message DeviceCredentialsProto { string credentialsValue = 5; } +message CredentialsDataProto { + ValidateDeviceTokenRequestMsg validateDeviceTokenRequestMsg = 1; + ValidateDeviceX509CertRequestMsg validateDeviceX509CertRequestMsg = 2; + ValidateBasicMqttCredRequestMsg validateBasicMqttCredRequestMsg = 3; +} + message ProvisionDeviceRequestMsg { string deviceName = 1; - string x509CertPubKey = 2; + CredentialsType credentialsType = 2; ProvisionDeviceCredentialsMsg provisionDeviceCredentialsMsg = 3; + CredentialsDataProto credentialsDataProto = 4; +} + +message GatewayProvisionRequestMsg { + int32 requestId = 1; + ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 2; } message ProvisionDeviceCredentialsMsg { @@ -270,6 +283,11 @@ message ProvisionDeviceResponseMsg { ProvisionResponseStatus provisionResponseStatus = 2; } +message GatewayProvisionResponseMsg { + int32 requestId = 1; + ProvisionDeviceResponseMsg provisionDeviceResponseMsg = 2; +} + enum ProvisionResponseStatus { UNKNOWN = 0; SUCCESS = 1; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index 82841d4307..2ef4085ac0 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -17,7 +17,6 @@ package org.thingsboard.server.transport.mqtt; import com.fasterxml.jackson.databind.JsonNode; import com.google.gson.JsonParseException; -import com.google.gson.JsonSyntaxException; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.codec.mqtt.MqttConnAckMessage; @@ -70,11 +69,10 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.Date; +import java.util.concurrent.TimeUnit; import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.CONNECTION_ACCEPTED; import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED; @@ -156,11 +154,13 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement if (topicName.equals(MqttTopics.DEVICE_PROVISION_REQUEST_TOPIC)) { try { TransportProtos.ProvisionDeviceRequestMsg provisionRequestMsg = deviceSessionCtx.getContext().getJsonMqttAdaptor().convertToProvisionRequestMsg(deviceSessionCtx, mqttMsg); + validateProvisionMessage(provisionRequestMsg); transportService.process(provisionRequestMsg, new DeviceProvisionCallback(ctx, msgId, provisionRequestMsg)); log.trace("[{}][{}] Processing provision publish msg [{}][{}]!", sessionId, deviceSessionCtx.getDeviceId(), topicName, msgId); } catch (Exception e) { if (e instanceof JsonParseException || (e.getCause() != null && e.getCause() instanceof JsonParseException)) { TransportProtos.ProvisionDeviceRequestMsg provisionRequestMsg = deviceSessionCtx.getContext().getProtoMqttAdaptor().convertToProvisionRequestMsg(deviceSessionCtx, mqttMsg); + validateProvisionMessage(provisionRequestMsg); transportService.process(provisionRequestMsg, new DeviceProvisionCallback(ctx, msgId, provisionRequestMsg)); deviceSessionCtx.setProvisionPayloadType(TransportPayloadType.PROTOBUF); log.trace("[{}][{}] Processing provision publish msg [{}][{}]!", sessionId, deviceSessionCtx.getDeviceId(), topicName, msgId); @@ -187,6 +187,13 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } } + private void validateProvisionMessage(TransportProtos.ProvisionDeviceRequestMsg provisionRequestMsg) { + if (provisionRequestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceKey() != null && + provisionRequestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceSecret() != null && + provisionRequestMsg.getDeviceName() != null) + throw new RuntimeException("Wrong credentials!"); + } + private void processRegularSessionMsg(ChannelHandlerContext ctx, MqttMessage msg) { switch (msg.fixedHeader().messageType()) { case PUBLISH: @@ -335,9 +342,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } else { deviceSessionCtx.getContext().getProtoMqttAdaptor().convertToPublish(deviceSessionCtx, provisionResponseMsg).ifPresent(deviceSessionCtx.getChannel()::writeAndFlush); } - - //TODO: close session with some delay. - //transportService.getScheduler().submit task with 60 seconds delay to close the session. + transportService.getSchedulerExecutor().schedule(() -> processDisconnect(ctx), 60, TimeUnit.SECONDS); } catch (Exception e) { log.trace("[{}] Failed to convert device attributes response to MQTT msg", sessionId, e); } @@ -379,7 +384,6 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement case MqttTopics.GATEWAY_ATTRIBUTES_TOPIC: case MqttTopics.GATEWAY_RPC_TOPIC: case MqttTopics.GATEWAY_ATTRIBUTES_RESPONSE_TOPIC: - case MqttTopics.GATEWAY_PROVISION_RESPONSE_TOPIC: case MqttTopics.DEVICE_PROVISION_RESPONSE_TOPIC: registerSubQoS(topic, grantedQoSList, reqQoS); break; @@ -447,7 +451,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement private void processConnect(ChannelHandlerContext ctx, MqttConnectMessage msg) { log.info("[{}] Processing connect msg for client: {}!", sessionId, msg.payload().clientIdentifier()); String userName = msg.payload().userName(); - if (DataConstants.PROVISION.equals(userName)) { + String clientId = msg.payload().clientIdentifier(); + if (DataConstants.PROVISION.equals(userName) || DataConstants.PROVISION.equals(clientId)) { deviceSessionCtx.setProvisionOnly(true); ctx.writeAndFlush(createMqttConnAckMsg(CONNECTION_ACCEPTED)); } else { diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java index 54f8075c24..0799d29c57 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java @@ -153,13 +153,6 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor { return Optional.of(createMqttPublishMsg(ctx, MqttTopics.DEVICE_PROVISION_RESPONSE_TOPIC, JsonConverter.toJson(provisionResponse))); } - @Override - public Optional convertToGatewayPublish(MqttDeviceAwareSessionContext ctx, String deviceName, TransportProtos.ProvisionDeviceResponseMsg responseMsg) { - return Optional.of(createMqttPublishMsg(ctx, - MqttTopics.GATEWAY_PROVISION_RESPONSE_TOPIC, - JsonConverter.toGatewayJson(deviceName, responseMsg))); - } - public static JsonElement validateJsonPayload(UUID sessionId, ByteBuf payloadData) throws AdaptorException { String payload = validatePayload(sessionId, payloadData, false); try { diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java index c0f1dd2369..bcb2401ff7 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java @@ -69,6 +69,4 @@ public interface MqttTransportAdaptor { Optional convertToPublish(MqttDeviceAwareSessionContext ctx, ProvisionDeviceResponseMsg provisionResponse) throws AdaptorException; - Optional convertToGatewayPublish(MqttDeviceAwareSessionContext ctx, String deviceName, ProvisionDeviceResponseMsg provisionResponse) throws AdaptorException; - } diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java index d5e9599812..1a0d33cde4 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java @@ -187,15 +187,6 @@ public class ProtoMqttAdaptor implements MqttTransportAdaptor { return Optional.of(createMqttPublishMsg(ctx, MqttTopics.GATEWAY_RPC_TOPIC, payloadBytes)); } - @Override - public Optional convertToGatewayPublish(MqttDeviceAwareSessionContext ctx, String deviceName, TransportProtos.ProvisionDeviceResponseMsg responseMsg) throws AdaptorException { - TransportApiProtos.GatewayProvisionResponseMsg.Builder builder = TransportApiProtos.GatewayProvisionResponseMsg.newBuilder(); - builder.setDeviceName(deviceName); - builder.setProvisionDeviceResponseMsg(responseMsg); - byte[] payloadBytes = builder.build().toByteArray(); - return Optional.of(createMqttPublishMsg(ctx, MqttTopics.GATEWAY_PROVISION_RESPONSE_TOPIC, payloadBytes)); - } - public static byte[] toBytes(ByteBuf inbound) { byte[] bytes = new byte[inbound.readableBytes()]; int readerIndex = inbound.readerIndex(); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java index 995b9eca91..775a91f720 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java @@ -40,6 +40,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateBasicMqttCre import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; +import java.util.concurrent.ScheduledExecutorService; + /** * Created by ashvayka on 04.10.18. */ @@ -88,6 +90,8 @@ public interface TransportService { void process(SessionInfoProto sessionInfo, ClaimDeviceMsg msg, TransportServiceCallback callback); + ScheduledExecutorService getSchedulerExecutor(); + void registerAsyncSession(SessionInfoProto sessionInfo, SessionMsgListener listener); void registerSyncSession(SessionInfoProto sessionInfo, SessionMsgListener listener, long timeout); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java index cd070e6927..a2cba83360 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java @@ -37,6 +37,8 @@ import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; +import org.thingsboard.server.gen.transport.TransportProtos.CredentialsDataProto.Builder; +import org.thingsboard.server.gen.transport.TransportProtos.CredentialsType; import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.KeyValueProto; import org.thingsboard.server.gen.transport.TransportProtos.KeyValueType; @@ -46,7 +48,11 @@ import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRespo import org.thingsboard.server.gen.transport.TransportProtos.ProvisionResponseStatus; import org.thingsboard.server.gen.transport.TransportProtos.TsKvListProto; import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; +import org.thingsboard.server.gen.transport.TransportProtos.ValidateBasicMqttCredRequestMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; +import javax.xml.crypto.Data; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -554,7 +560,17 @@ public class JsonConverter { private static TransportProtos.ProvisionDeviceRequestMsg buildProvisionRequestMsg(JsonObject jo) { return TransportProtos.ProvisionDeviceRequestMsg.newBuilder() .setDeviceName(getStrValue(jo, DataConstants.DEVICE_NAME, true)) - .setX509CertPubKey(getStrValue(jo, DataConstants.CERT_PUB_KEY, false)) + .setCredentialsType(TransportProtos.CredentialsType.valueOf(getStrValue(jo, DataConstants.CREDENTIALS_TYPE, false))) + .setCredentialsDataProto(TransportProtos.CredentialsDataProto.newBuilder() + .setValidateDeviceTokenRequestMsg(ValidateDeviceTokenRequestMsg.newBuilder().setToken(getStrValue(jo, DataConstants.TOKEN, false)).build()) + .setValidateBasicMqttCredRequestMsg(ValidateBasicMqttCredRequestMsg.newBuilder() + .setClientId(getStrValue(jo, DataConstants.CLIENT_ID, false)) + .setUserName(getStrValue(jo, DataConstants.USERNAME, false)) + .setPassword(getStrValue(jo, DataConstants.PASSWORD, false)) + .build()) + .setValidateDeviceX509CertRequestMsg(ValidateDeviceX509CertRequestMsg.newBuilder() + .setHash(getStrValue(jo, DataConstants.PASSWORD, false)).build()) + .build()) .setProvisionDeviceCredentialsMsg(buildProvisionDeviceCredentialsMsg( getStrValue(jo, DataConstants.PROVISION_KEY, true), getStrValue(jo, DataConstants.PROVISION_SECRET, true))) @@ -567,6 +583,8 @@ public class JsonConverter { .setProvisionDeviceSecret(provisionSecret) .build(); } + + private static String getStrValue(JsonObject jo, String field, boolean requiredField) { if (jo.has(field)) { return jo.get(field).getAsString(); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 58b06e696e..47abc07286 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -34,7 +34,6 @@ import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.msg.TbMsg; -import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.queue.ServiceQueue; import org.thingsboard.server.common.msg.queue.ServiceType; @@ -49,7 +48,6 @@ import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse; import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; -import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; import org.thingsboard.server.common.transport.util.JsonUtils; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; @@ -77,11 +75,9 @@ import org.thingsboard.server.common.stats.StatsType; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Random; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -93,7 +89,6 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; /** * Created by ashvayka on 17.10.18. @@ -236,6 +231,11 @@ public class DefaultTransportService implements TransportService { } } + @Override + public ScheduledExecutorService getSchedulerExecutor(){ + return this.schedulerExecutor; + } + @Override public void registerAsyncSession(TransportProtos.SessionInfoProto sessionInfo, SessionMsgListener listener) { sessions.putIfAbsent(toSessionId(sessionInfo), new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listener));