Commit 15be6d60a314d2dbaf9ad09dd4ed05a55349d364

Authored by zbeacon
1 parent d2282080

Added strategy checking

@@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.service.device; 16 package org.thingsboard.server.service.device;
17 17
18 -import com.datastax.oss.driver.api.core.uuid.Uuids;  
19 import com.fasterxml.jackson.core.JsonProcessingException; 18 import com.fasterxml.jackson.core.JsonProcessingException;
20 import com.fasterxml.jackson.databind.node.ObjectNode; 19 import com.fasterxml.jackson.databind.node.ObjectNode;
21 import com.google.common.util.concurrent.Futures; 20 import com.google.common.util.concurrent.Futures;
@@ -30,9 +29,11 @@ import org.thingsboard.server.common.data.Device; @@ -30,9 +29,11 @@ import org.thingsboard.server.common.data.Device;
30 import org.thingsboard.server.common.data.DeviceProfile; 29 import org.thingsboard.server.common.data.DeviceProfile;
31 import org.thingsboard.server.common.data.DeviceProfileType; 30 import org.thingsboard.server.common.data.DeviceProfileType;
32 import org.thingsboard.server.common.data.audit.ActionType; 31 import org.thingsboard.server.common.data.audit.ActionType;
  32 +import org.thingsboard.server.common.data.device.data.ProvisionDeviceConfiguration;
33 import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileConfiguration; 33 import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileConfiguration;
  34 +import org.thingsboard.server.common.data.device.profile.ProvisionRequestValidationStrategyType;
  35 +import org.thingsboard.server.common.data.id.CustomerId;
34 import org.thingsboard.server.common.data.id.TenantId; 36 import org.thingsboard.server.common.data.id.TenantId;
35 -import org.thingsboard.server.common.data.id.UserId;  
36 import org.thingsboard.server.common.data.kv.AttributeKvEntry; 37 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
37 import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; 38 import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
38 import org.thingsboard.server.common.data.kv.StringDataEntry; 39 import org.thingsboard.server.common.data.kv.StringDataEntry;
@@ -45,6 +46,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; @@ -45,6 +46,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
45 import org.thingsboard.server.dao.attributes.AttributesService; 46 import org.thingsboard.server.dao.attributes.AttributesService;
46 import org.thingsboard.server.dao.audit.AuditLogService; 47 import org.thingsboard.server.dao.audit.AuditLogService;
47 import org.thingsboard.server.dao.device.DeviceCredentialsService; 48 import org.thingsboard.server.dao.device.DeviceCredentialsService;
  49 +import org.thingsboard.server.dao.device.DeviceDao;
48 import org.thingsboard.server.dao.device.DeviceProfileDao; 50 import org.thingsboard.server.dao.device.DeviceProfileDao;
49 import org.thingsboard.server.dao.device.DeviceProvisionService; 51 import org.thingsboard.server.dao.device.DeviceProvisionService;
50 import org.thingsboard.server.dao.device.DeviceService; 52 import org.thingsboard.server.dao.device.DeviceService;
@@ -65,8 +67,6 @@ import java.util.List; @@ -65,8 +67,6 @@ import java.util.List;
65 import java.util.Optional; 67 import java.util.Optional;
66 import java.util.concurrent.locks.ReentrantLock; 68 import java.util.concurrent.locks.ReentrantLock;
67 69
68 -import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;  
69 -  
70 70
71 @Service 71 @Service
72 @Slf4j 72 @Slf4j
@@ -77,11 +77,12 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { @@ -77,11 +77,12 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
77 private static final String DEVICE_PROVISION_STATE = "provisionState"; 77 private static final String DEVICE_PROVISION_STATE = "provisionState";
78 private static final String PROVISIONED_STATE = "provisioned"; 78 private static final String PROVISIONED_STATE = "provisioned";
79 79
80 - private static final UserId PROVISION_USER_ID = UserId.fromString(NULL_UUID.toString());  
81 -  
82 private final ReentrantLock deviceCreationLock = new ReentrantLock(); 80 private final ReentrantLock deviceCreationLock = new ReentrantLock();
83 81
84 @Autowired 82 @Autowired
  83 + DeviceDao deviceDao;
  84 +
  85 + @Autowired
85 DeviceProfileDao deviceProfileDao; 86 DeviceProfileDao deviceProfileDao;
86 87
87 @Autowired 88 @Autowired
@@ -105,39 +106,52 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { @@ -105,39 +106,52 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
105 106
106 @Override 107 @Override
107 public ListenableFuture<ProvisionResponse> provisionDevice(ProvisionRequest provisionRequest) { 108 public ListenableFuture<ProvisionResponse> provisionDevice(ProvisionRequest provisionRequest) {
108 - DeviceProfile targetProfile = deviceProfileDao.findProfileByTenantIdAndProfileDataProvisionConfigurationPair( 109 + Device targetDevice = deviceDao.findDeviceByTenantIdAndDeviceDataProvisionConfigurationPair(
109 TenantId.SYS_TENANT_ID, 110 TenantId.SYS_TENANT_ID,
110 provisionRequest.getCredentials().getProvisionDeviceKey(), 111 provisionRequest.getCredentials().getProvisionDeviceKey(),
111 provisionRequest.getCredentials().getProvisionDeviceSecret()); 112 provisionRequest.getCredentials().getProvisionDeviceSecret());
112 113
113 - if (targetProfile.getProfileData().getConfiguration().getType() != DeviceProfileType.PROVISION) {  
114 - return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND));  
115 - } 114 + if (targetDevice != null) {
  115 + if (targetDevice.getDeviceData().getConfiguration().getType() != DeviceProfileType.PROVISION) {
  116 + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND));
  117 + }
116 118
117 - ProvisionDeviceProfileConfiguration currentProfileConfiguration = (ProvisionDeviceProfileConfiguration) targetProfile.getProfileData().getConfiguration();  
118 - if (!new ProvisionDeviceProfileConfiguration(provisionRequest.getCredentials().getProvisionDeviceKey(), provisionRequest.getCredentials().getProvisionDeviceSecret()).equals(currentProfileConfiguration)) {  
119 - return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND));  
120 - } 119 + DeviceProfile targetProfile = deviceProfileDao.findById(TenantId.SYS_TENANT_ID, targetDevice.getDeviceProfileId().getId());
121 120
122 - Device device = deviceService.findDeviceByTenantIdAndName(targetProfile.getTenantId(), provisionRequest.getDeviceName());  
123 - switch (currentProfileConfiguration.getStrategy()) {  
124 - case CHECK_NEW_DEVICE:  
125 - if (device == null) {  
126 - return createDevice(provisionRequest, targetProfile);  
127 - } else {  
128 - log.warn("[{}] The device is present and could not be provisioned once more!", device.getName());  
129 - notify(device, provisionRequest, DataConstants.PROVISION_FAILURE, false); 121 + ProvisionDeviceConfiguration currentProfileConfiguration = (ProvisionDeviceConfiguration) targetDevice.getDeviceData().getConfiguration();
  122 + if (!new ProvisionDeviceConfiguration(provisionRequest.getCredentials().getProvisionDeviceKey(), provisionRequest.getCredentials().getProvisionDeviceSecret()).equals(currentProfileConfiguration)) {
  123 + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND));
  124 + }
  125 + ProvisionRequestValidationStrategyType targetStrategy = getStrategy(targetProfile);
  126 + switch (targetStrategy) {
  127 + case CHECK_NEW_DEVICE:
  128 + log.warn("[{}] The device is present and could not be provisioned once more!", targetDevice.getName());
  129 + notify(targetDevice, provisionRequest, DataConstants.PROVISION_FAILURE, false);
130 return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE)); 130 return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE));
131 - }  
132 - case CHECK_PRE_PROVISIONED_DEVICE:  
133 - if (device == null) { 131 + case CHECK_PRE_PROVISIONED_DEVICE:
  132 + return processProvision(targetDevice, provisionRequest);
  133 + default:
  134 + throw new RuntimeException("Strategy is not supported - " + targetStrategy.name());
  135 + }
  136 + } else {
  137 + DeviceProfile targetProfile = deviceProfileDao.findProfileByTenantIdAndProfileDataProvisionConfigurationPair(
  138 + TenantId.SYS_TENANT_ID,
  139 + provisionRequest.getCredentials().getProvisionDeviceKey(),
  140 + provisionRequest.getCredentials().getProvisionDeviceSecret()
  141 + );
  142 + if (targetProfile.getProfileData().getConfiguration().getType() != DeviceProfileType.PROVISION) {
  143 + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND));
  144 + }
  145 + ProvisionRequestValidationStrategyType targetStrategy = getStrategy(targetProfile);
  146 + switch (targetStrategy) {
  147 + case CHECK_NEW_DEVICE:
  148 + return createDevice(provisionRequest, targetProfile);
  149 + case CHECK_PRE_PROVISIONED_DEVICE:
134 log.warn("[{}] Failed to find pre provisioned device!", provisionRequest.getDeviceName()); 150 log.warn("[{}] Failed to find pre provisioned device!", provisionRequest.getDeviceName());
135 return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE)); 151 return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE));
136 - } else {  
137 - return processProvision(device, provisionRequest);  
138 - }  
139 - default:  
140 - throw new RuntimeException("Strategy is not supported - " + currentProfileConfiguration.getStrategy().name()); 152 + default:
  153 + throw new RuntimeException("Strategy is not supported - " + targetStrategy.name());
  154 + }
141 } 155 }
142 } 156 }
143 157
@@ -178,6 +192,16 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { @@ -178,6 +192,16 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
178 } 192 }
179 } 193 }
180 194
  195 + private void notify(Device device, ProvisionRequest provisionRequest, String type, boolean success) {
  196 + pushProvisionEventToRuleEngine(provisionRequest, device, type);
  197 + logAction(device.getTenantId(), device.getCustomerId(), device, success, provisionRequest);
  198 + }
  199 +
  200 + private ProvisionRequestValidationStrategyType getStrategy(DeviceProfile profile) {
  201 + return ((ProvisionDeviceProfileConfiguration) profile.getProfileData().getConfiguration()).getStrategy();
  202 +
  203 + }
  204 +
181 private ListenableFuture<ProvisionResponse> processCreateDevice(ProvisionRequest provisionRequest, DeviceProfile profile) { 205 private ListenableFuture<ProvisionResponse> processCreateDevice(ProvisionRequest provisionRequest, DeviceProfile profile) {
182 Device device = deviceService.findDeviceByTenantIdAndName(profile.getTenantId(), provisionRequest.getDeviceName()); 206 Device device = deviceService.findDeviceByTenantIdAndName(profile.getTenantId(), provisionRequest.getDeviceName());
183 if (device == null) { 207 if (device == null) {
@@ -221,15 +245,10 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { @@ -221,15 +245,10 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
221 return credentials; 245 return credentials;
222 } 246 }
223 247
224 - private void notify(Device device, ProvisionRequest provisionRequest, String type, boolean success) {  
225 - pushProvisionEventToRuleEngine(provisionRequest, device, type);  
226 - logAction(device.getTenantId(), device, success, provisionRequest);  
227 - }  
228 -  
229 private void pushProvisionEventToRuleEngine(ProvisionRequest request, Device device, String type) { 248 private void pushProvisionEventToRuleEngine(ProvisionRequest request, Device device, String type) {
230 try { 249 try {
231 ObjectNode entityNode = JacksonUtil.OBJECT_MAPPER.valueToTree(request); 250 ObjectNode entityNode = JacksonUtil.OBJECT_MAPPER.valueToTree(request);
232 - TbMsg msg = new TbMsg(Uuids.timeBased(), type, device.getId(), createTbMsgMetaData(device), JacksonUtil.OBJECT_MAPPER.writeValueAsString(entityNode), null, null, 0L); 251 + TbMsg msg = TbMsg.newMsg(type, device.getId(), createTbMsgMetaData(device), JacksonUtil.OBJECT_MAPPER.writeValueAsString(entityNode));
233 sendToRuleEngine(device.getTenantId(), msg, null); 252 sendToRuleEngine(device.getTenantId(), msg, null);
234 } catch (JsonProcessingException | IllegalArgumentException e) { 253 } catch (JsonProcessingException | IllegalArgumentException e) {
235 log.warn("[{}] Failed to push device action to rule engine: {}", device.getId(), type, e); 254 log.warn("[{}] Failed to push device action to rule engine: {}", device.getId(), type, e);
@@ -239,7 +258,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { @@ -239,7 +258,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
239 private void pushDeviceCreatedEventToRuleEngine(Device device) { 258 private void pushDeviceCreatedEventToRuleEngine(Device device) {
240 try { 259 try {
241 ObjectNode entityNode = JacksonUtil.OBJECT_MAPPER.valueToTree(device); 260 ObjectNode entityNode = JacksonUtil.OBJECT_MAPPER.valueToTree(device);
242 - TbMsg msg = new TbMsg(Uuids.timeBased(), DataConstants.ENTITY_CREATED, device.getId(), createTbMsgMetaData(device), JacksonUtil.OBJECT_MAPPER.writeValueAsString(entityNode), null, null, 0L); 261 + TbMsg msg = TbMsg.newMsg(DataConstants.ENTITY_CREATED, device.getId(), createTbMsgMetaData(device), JacksonUtil.OBJECT_MAPPER.writeValueAsString(entityNode));
243 sendToRuleEngine(device.getTenantId(), msg, null); 262 sendToRuleEngine(device.getTenantId(), msg, null);
244 } catch (JsonProcessingException | IllegalArgumentException e) { 263 } catch (JsonProcessingException | IllegalArgumentException e) {
245 log.warn("[{}] Failed to push device action to rule engine: {}", device.getId(), DataConstants.ENTITY_CREATED, e); 264 log.warn("[{}] Failed to push device action to rule engine: {}", device.getId(), DataConstants.ENTITY_CREATED, e);
@@ -260,8 +279,8 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { @@ -260,8 +279,8 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
260 return metaData; 279 return metaData;
261 } 280 }
262 281
263 - private void logAction(TenantId tenantId, Device device, boolean success, ProvisionRequest provisionRequest) { 282 + private void logAction(TenantId tenantId, CustomerId customerId, Device device, boolean success, ProvisionRequest provisionRequest) {
264 ActionType actionType = success ? ActionType.PROVISION_SUCCESS : ActionType.PROVISION_FAILURE; 283 ActionType actionType = success ? ActionType.PROVISION_SUCCESS : ActionType.PROVISION_FAILURE;
265 - auditLogService.logEntityAction(tenantId, null, null, device.getName(), device.getId(), device, actionType, null, provisionRequest); 284 + auditLogService.logEntityAction(tenantId, customerId, null, device.getName(), device.getId(), device, actionType, null, provisionRequest);
266 } 285 }
267 } 286 }
@@ -17,7 +17,7 @@ package org.thingsboard.server.dao.device.provision; @@ -17,7 +17,7 @@ package org.thingsboard.server.dao.device.provision;
17 17
18 import lombok.AllArgsConstructor; 18 import lombok.AllArgsConstructor;
19 import lombok.Data; 19 import lombok.Data;
20 -import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileConfiguration; 20 +import org.thingsboard.server.common.data.device.data.ProvisionDeviceConfiguration;
21 21
22 @Data 22 @Data
23 @AllArgsConstructor 23 @AllArgsConstructor
@@ -25,5 +25,5 @@ public class ProvisionRequest { @@ -25,5 +25,5 @@ public class ProvisionRequest {
25 private String deviceName; 25 private String deviceName;
26 private String deviceType; 26 private String deviceType;
27 private String x509CertPubKey; 27 private String x509CertPubKey;
28 - private ProvisionDeviceProfileConfiguration credentials; 28 + private ProvisionDeviceConfiguration credentials;
29 } 29 }
@@ -72,11 +72,12 @@ public class DataConstants { @@ -72,11 +72,12 @@ public class DataConstants {
72 public static final String SECRET_KEY_FIELD_NAME = "secretKey"; 72 public static final String SECRET_KEY_FIELD_NAME = "secretKey";
73 public static final String DURATION_MS_FIELD_NAME = "durationMs"; 73 public static final String DURATION_MS_FIELD_NAME = "durationMs";
74 74
  75 + public static final String PROVISION = "provision";
  76 + public static final String PROVISION_KEY = "provisionDeviceKey";
  77 + public static final String PROVISION_SECRET = "provisionDeviceSecret";
  78 +
75 public static final String DEVICE_NAME = "deviceName"; 79 public static final String DEVICE_NAME = "deviceName";
76 public static final String DEVICE_TYPE = "deviceType"; 80 public static final String DEVICE_TYPE = "deviceType";
77 public static final String CERT_PUB_KEY = "x509CertPubKey"; 81 public static final String CERT_PUB_KEY = "x509CertPubKey";
78 82
79 - public static final String PROVISION_KEY = "provisionDeviceKey";  
80 - public static final String PROVISION_SECRET = "provisionDeviceSecret";  
81 -  
82 } 83 }
  1 +/**
  2 + * Copyright © 2016-2020 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.device.data;
  17 +
  18 +import com.fasterxml.jackson.annotation.JsonCreator;
  19 +import com.fasterxml.jackson.annotation.JsonProperty;
  20 +import lombok.Data;
  21 +import org.thingsboard.server.common.data.DeviceProfileType;
  22 +import org.thingsboard.server.common.data.device.profile.DeviceProfileConfiguration;
  23 +import org.thingsboard.server.common.data.device.profile.ProvisionRequestValidationStrategyType;
  24 +
  25 +import java.util.Objects;
  26 +
  27 +@Data
  28 +public class ProvisionDeviceConfiguration implements DeviceConfiguration {
  29 +
  30 + private String provisionDeviceKey;
  31 + private String provisionDeviceSecret;
  32 +
  33 + @Override
  34 + public DeviceProfileType getType() {
  35 + return DeviceProfileType.PROVISION;
  36 + }
  37 +
  38 + @JsonCreator
  39 + public ProvisionDeviceConfiguration(@JsonProperty("provisionDeviceKey") String provisionProfileKey, @JsonProperty("provisionDeviceSecret") String provisionProfileSecret) {
  40 + this.provisionDeviceKey = provisionProfileKey;
  41 + this.provisionDeviceSecret = provisionProfileSecret;
  42 + }
  43 +
  44 + @Override
  45 + public boolean equals(Object o) {
  46 + if (this == o) return true;
  47 + if (o == null || getClass() != o.getClass()) return false;
  48 + ProvisionDeviceConfiguration that = (ProvisionDeviceConfiguration) o;
  49 + return provisionDeviceKey.equals(that.provisionDeviceKey) &&
  50 + provisionDeviceSecret.equals(that.provisionDeviceSecret);
  51 + }
  52 +
  53 + @Override
  54 + public int hashCode() {
  55 + return Objects.hash(provisionDeviceKey, provisionDeviceSecret);
  56 + }
  57 +}
@@ -19,6 +19,8 @@ import com.fasterxml.jackson.annotation.JsonCreator; @@ -19,6 +19,8 @@ import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonProperty; 19 import com.fasterxml.jackson.annotation.JsonProperty;
20 import lombok.Data; 20 import lombok.Data;
21 import org.thingsboard.server.common.data.DeviceProfileType; 21 import org.thingsboard.server.common.data.DeviceProfileType;
  22 +import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
  23 +import org.thingsboard.server.common.data.device.data.ProvisionDeviceConfiguration;
22 24
23 import java.util.Objects; 25 import java.util.Objects;
24 26
@@ -34,10 +34,12 @@ import io.netty.handler.codec.mqtt.MqttSubscribeMessage; @@ -34,10 +34,12 @@ import io.netty.handler.codec.mqtt.MqttSubscribeMessage;
34 import io.netty.handler.codec.mqtt.MqttTopicSubscription; 34 import io.netty.handler.codec.mqtt.MqttTopicSubscription;
35 import io.netty.handler.codec.mqtt.MqttUnsubscribeMessage; 35 import io.netty.handler.codec.mqtt.MqttUnsubscribeMessage;
36 import io.netty.handler.ssl.SslHandler; 36 import io.netty.handler.ssl.SslHandler;
  37 +import io.netty.util.CharsetUtil;
37 import io.netty.util.ReferenceCountUtil; 38 import io.netty.util.ReferenceCountUtil;
38 import io.netty.util.concurrent.Future; 39 import io.netty.util.concurrent.Future;
39 import io.netty.util.concurrent.GenericFutureListener; 40 import io.netty.util.concurrent.GenericFutureListener;
40 import lombok.extern.slf4j.Slf4j; 41 import lombok.extern.slf4j.Slf4j;
  42 +import org.thingsboard.server.common.data.DataConstants;
41 import org.thingsboard.server.common.data.DeviceProfile; 43 import org.thingsboard.server.common.data.DeviceProfile;
42 import org.thingsboard.server.common.data.DeviceTransportType; 44 import org.thingsboard.server.common.data.DeviceTransportType;
43 import org.thingsboard.server.common.data.device.profile.MqttTopics; 45 import org.thingsboard.server.common.data.device.profile.MqttTopics;
@@ -51,6 +53,7 @@ import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; @@ -51,6 +53,7 @@ import org.thingsboard.server.common.transport.auth.TransportDeviceInfo;
51 import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; 53 import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
52 import org.thingsboard.server.common.transport.service.DefaultTransportService; 54 import org.thingsboard.server.common.transport.service.DefaultTransportService;
53 import org.thingsboard.server.gen.transport.TransportProtos; 55 import org.thingsboard.server.gen.transport.TransportProtos;
  56 +import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto;
54 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; 57 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg;
55 import org.thingsboard.server.gen.transport.TransportProtos.SessionEvent; 58 import org.thingsboard.server.gen.transport.TransportProtos.SessionEvent;
56 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; 59 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg;
@@ -420,11 +423,19 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement @@ -420,11 +423,19 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
420 423
421 private void processConnect(ChannelHandlerContext ctx, MqttConnectMessage msg) { 424 private void processConnect(ChannelHandlerContext ctx, MqttConnectMessage msg) {
422 log.info("[{}] Processing connect msg for client: {}!", sessionId, msg.payload().clientIdentifier()); 425 log.info("[{}] Processing connect msg for client: {}!", sessionId, msg.payload().clientIdentifier());
423 - X509Certificate cert;  
424 - if (sslHandler != null && (cert = getX509Certificate()) != null) {  
425 - processX509CertConnect(ctx, cert); 426 + String userName = msg.payload().userName();
  427 + if (DataConstants.PROVISION.equals(userName)) {
  428 + deviceSessionCtx.setDeviceInfo(new TransportDeviceInfo());
  429 + deviceSessionCtx.setProvisionOnly(true);
  430 + ctx.writeAndFlush(createMqttConnAckMsg(CONNECTION_ACCEPTED));
426 } else { 431 } else {
427 - processAuthTokenConnect(ctx, msg); 432 + X509Certificate cert;
  433 +
  434 + if (sslHandler != null && (cert = getX509Certificate()) != null) {
  435 + processX509CertConnect(ctx, cert);
  436 + } else {
  437 + processAuthTokenConnect(ctx, msg);
  438 + }
428 } 439 }
429 } 440 }
430 441
@@ -215,4 +215,6 @@ public interface DeviceDao extends Dao<Device> { @@ -215,4 +215,6 @@ public interface DeviceDao extends Dao<Device> {
215 */ 215 */
216 PageData<Device> findDevicesByTenantIdAndProfileId(UUID tenantId, UUID profileId, PageLink pageLink); 216 PageData<Device> findDevicesByTenantIdAndProfileId(UUID tenantId, UUID profileId, PageLink pageLink);
217 217
  218 + Device findDeviceByTenantIdAndDeviceDataProvisionConfigurationPair(TenantId tenantId, String provisionDeviceKey, String provisionDeviceSecret);
  219 +
218 } 220 }
@@ -20,8 +20,10 @@ import org.springframework.data.domain.Pageable; @@ -20,8 +20,10 @@ 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.DeviceProfileInfo;
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;
  26 +import org.thingsboard.server.dao.model.sql.DeviceProfileEntity;
25 27
26 import java.util.List; 28 import java.util.List;
27 import java.util.UUID; 29 import java.util.UUID;
@@ -169,4 +171,12 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit @@ -169,4 +171,12 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit
169 171
170 Long countByDeviceProfileId(UUID deviceProfileId); 172 Long countByDeviceProfileId(UUID deviceProfileId);
171 173
  174 + @Query(value = "SELECT d FROM Device d " +
  175 + "WHERE d.tenant_id = :tenantId " +
  176 + "AND d.device_data::jsonb->>('configuration', 'provisionDeviceKey') = :provisionDeviceKey " +
  177 + "AND d.device_data::jsonb->>('configuration', 'provisionDeviceSecret') = :provisionDeviceSecret",
  178 + nativeQuery = true)
  179 + DeviceEntity findDeviceByTenantIdAndDeviceDataProvisionConfigurationPair(@Param("tenantId") UUID tenantId,
  180 + @Param("provisionDeviceKey") String provisionDeviceKey,
  181 + @Param("provisionDeviceSecret") String provisionDeviceSecret);
172 } 182 }
@@ -22,6 +22,8 @@ import org.springframework.stereotype.Component; @@ -22,6 +22,8 @@ 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.DeviceProfile;
  26 +import org.thingsboard.server.common.data.DeviceProfileInfo;
25 import org.thingsboard.server.common.data.EntitySubtype; 27 import org.thingsboard.server.common.data.EntitySubtype;
26 import org.thingsboard.server.common.data.EntityType; 28 import org.thingsboard.server.common.data.EntityType;
27 import org.thingsboard.server.common.data.id.TenantId; 29 import org.thingsboard.server.common.data.id.TenantId;
@@ -219,6 +221,11 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> @@ -219,6 +221,11 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device>
219 return deviceRepository.countByDeviceProfileId(deviceProfileId); 221 return deviceRepository.countByDeviceProfileId(deviceProfileId);
220 } 222 }
221 223
  224 + @Override
  225 + public Device findDeviceByTenantIdAndDeviceDataProvisionConfigurationPair(TenantId tenantId, String provisionDeviceKey, String provisionDeviceSecret) {
  226 + return DaoUtil.getData(deviceRepository.findDeviceByTenantIdAndDeviceDataProvisionConfigurationPair(tenantId.getId(), provisionDeviceKey, provisionDeviceSecret));
  227 + }
  228 +
222 private List<EntitySubtype> convertTenantDeviceTypesToDto(UUID tenantId, List<String> types) { 229 private List<EntitySubtype> convertTenantDeviceTypesToDto(UUID tenantId, List<String> types) {
223 List<EntitySubtype> list = Collections.emptyList(); 230 List<EntitySubtype> list = Collections.emptyList();
224 if (types != null && !types.isEmpty()) { 231 if (types != null && !types.isEmpty()) {