Commit 8a8695f260e0b98615c711a4c0d6b77819a2c26a
1 parent
15be6d60
Working version for provision feature with provision credentials on device level
Showing
19 changed files
with
267 additions
and
105 deletions
... | ... | @@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileC |
34 | 34 | import org.thingsboard.server.common.data.device.profile.ProvisionRequestValidationStrategyType; |
35 | 35 | import org.thingsboard.server.common.data.id.CustomerId; |
36 | 36 | import org.thingsboard.server.common.data.id.TenantId; |
37 | +import org.thingsboard.server.common.data.id.UserId; | |
37 | 38 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
38 | 39 | import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
39 | 40 | import org.thingsboard.server.common.data.kv.StringDataEntry; |
... | ... | @@ -60,6 +61,7 @@ import org.thingsboard.server.queue.TbQueueCallback; |
60 | 61 | import org.thingsboard.server.queue.TbQueueProducer; |
61 | 62 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
62 | 63 | import org.thingsboard.server.queue.discovery.PartitionService; |
64 | +import org.thingsboard.server.queue.provider.TbQueueProducerProvider; | |
63 | 65 | import org.thingsboard.server.service.state.DeviceStateService; |
64 | 66 | |
65 | 67 | import java.util.Collections; |
... | ... | @@ -103,55 +105,88 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { |
103 | 105 | @Autowired |
104 | 106 | PartitionService partitionService; |
105 | 107 | |
108 | + public DeviceProvisionServiceImpl(TbQueueProducerProvider producerProvider) { | |
109 | + ruleEngineMsgProducer = producerProvider.getRuleEngineMsgProducer(); | |
110 | + } | |
106 | 111 | |
107 | 112 | @Override |
108 | 113 | public ListenableFuture<ProvisionResponse> provisionDevice(ProvisionRequest provisionRequest) { |
109 | - Device targetDevice = deviceDao.findDeviceByTenantIdAndDeviceDataProvisionConfigurationPair( | |
110 | - TenantId.SYS_TENANT_ID, | |
111 | - provisionRequest.getCredentials().getProvisionDeviceKey(), | |
112 | - provisionRequest.getCredentials().getProvisionDeviceSecret()); | |
114 | + String provisionRequestKey = provisionRequest.getCredentials().getProvisionDeviceKey(); | |
115 | + String provisionRequestSecret = provisionRequest.getCredentials().getProvisionDeviceSecret(); | |
113 | 116 | |
114 | - if (targetDevice != null) { | |
115 | - if (targetDevice.getDeviceData().getConfiguration().getType() != DeviceProfileType.PROVISION) { | |
116 | - return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND)); | |
117 | - } | |
117 | + if (StringUtils.isEmpty(provisionRequestKey) || StringUtils.isEmpty(provisionRequestSecret)) { | |
118 | + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND)); | |
119 | + } | |
118 | 120 | |
119 | - DeviceProfile targetProfile = deviceProfileDao.findById(TenantId.SYS_TENANT_ID, targetDevice.getDeviceProfileId().getId()); | |
121 | + Device targetDevice = deviceDao.findDeviceByProfileNameAndDeviceDataProvisionConfigurationPair( | |
122 | + provisionRequest.getDeviceType(), | |
123 | + provisionRequestKey, | |
124 | + provisionRequestSecret | |
125 | + ).orElse(null); | |
120 | 126 | |
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)); | |
131 | - case CHECK_PRE_PROVISIONED_DEVICE: | |
132 | - return processProvision(targetDevice, provisionRequest); | |
133 | - default: | |
134 | - throw new RuntimeException("Strategy is not supported - " + targetStrategy.name()); | |
135 | - } | |
127 | + if (targetDevice != null) { | |
128 | + return processProvisionDeviceWithKeySecretPairExists(provisionRequest, provisionRequestKey, provisionRequestSecret, targetDevice); | |
136 | 129 | } 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: | |
150 | - log.warn("[{}] Failed to find pre provisioned device!", provisionRequest.getDeviceName()); | |
151 | - return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE)); | |
152 | - default: | |
153 | - throw new RuntimeException("Strategy is not supported - " + targetStrategy.name()); | |
154 | - } | |
130 | + return processProvisionDeviceWithKeySecretPairNotExists(provisionRequest, provisionRequestKey, provisionRequestSecret); | |
131 | + } | |
132 | + } | |
133 | + | |
134 | + private ListenableFuture<ProvisionResponse> processProvisionDeviceWithKeySecretPairExists(ProvisionRequest provisionRequest, String provisionRequestKey, String provisionRequestSecret, Device targetDevice) { | |
135 | + if (targetDevice.getDeviceData().getConfiguration().getType() != DeviceProfileType.PROVISION) { | |
136 | + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND)); | |
137 | + } | |
138 | + | |
139 | + DeviceProfile targetProfile = deviceProfileDao.findById(targetDevice.getTenantId(), targetDevice.getDeviceProfileId().getId()); | |
140 | + | |
141 | + if (targetProfile == null || targetProfile.getProfileData().getConfiguration().getType() != DeviceProfileType.PROVISION) { | |
142 | + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND)); | |
143 | + } | |
144 | + | |
145 | + ProvisionDeviceConfiguration currentDeviceConfiguration = (ProvisionDeviceConfiguration) targetDevice.getDeviceData().getConfiguration(); | |
146 | + | |
147 | + if (!new ProvisionDeviceConfiguration(provisionRequestKey, provisionRequestSecret).equals(currentDeviceConfiguration)) { | |
148 | + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND)); | |
149 | + } | |
150 | + | |
151 | + ProvisionRequestValidationStrategyType targetStrategy = getStrategy(targetProfile); | |
152 | + switch (targetStrategy) { | |
153 | + case CHECK_NEW_DEVICE: | |
154 | + log.warn("[{}] The device is present and could not be provisioned once more!", targetDevice.getName()); | |
155 | + notify(targetDevice, provisionRequest, DataConstants.PROVISION_FAILURE, false); | |
156 | + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE)); | |
157 | + case CHECK_PRE_PROVISIONED_DEVICE: | |
158 | + return processProvision(targetDevice, provisionRequest); | |
159 | + default: | |
160 | + throw new RuntimeException("Strategy is not supported - " + targetStrategy.name()); | |
161 | + } | |
162 | + } | |
163 | + | |
164 | + private ListenableFuture<ProvisionResponse> processProvisionDeviceWithKeySecretPairNotExists(ProvisionRequest provisionRequest, String provisionRequestKey, String provisionRequestSecret){ | |
165 | + DeviceProfile targetProfile = deviceProfileDao.findProfileByProfileNameAndProfileDataProvisionConfigurationPair( | |
166 | + provisionRequest.getDeviceType(), | |
167 | + provisionRequestKey, | |
168 | + provisionRequestSecret | |
169 | + ); | |
170 | + | |
171 | + if (targetProfile == null || targetProfile.getProfileData().getConfiguration().getType() != DeviceProfileType.PROVISION) { | |
172 | + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND)); | |
173 | + } | |
174 | + ProvisionRequestValidationStrategyType targetStrategy = getStrategy(targetProfile); | |
175 | + switch (targetStrategy) { | |
176 | + case CHECK_NEW_DEVICE: | |
177 | + return createDevice(provisionRequest, targetProfile); | |
178 | + case CHECK_PRE_PROVISIONED_DEVICE: | |
179 | + ProvisionDeviceProfileConfiguration currentDeviceProfileConfiguration = (ProvisionDeviceProfileConfiguration) targetProfile.getProfileData().getConfiguration(); | |
180 | + if(new ProvisionDeviceProfileConfiguration(provisionRequestKey, provisionRequestSecret).equals(currentDeviceProfileConfiguration)) { | |
181 | + Optional<Device> optionalDevice = deviceDao.findDeviceByTenantIdAndName(targetProfile.getTenantId().getId(), provisionRequest.getDeviceName()); | |
182 | + if (optionalDevice.isPresent()) { | |
183 | + return processProvision(optionalDevice.get(), provisionRequest); | |
184 | + } | |
185 | + } | |
186 | + log.warn("[{}] Failed to find pre provisioned device!", provisionRequest.getDeviceName()); | |
187 | + return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE)); | |
188 | + default: | |
189 | + throw new RuntimeException("Strategy is not supported - " + targetStrategy.name()); | |
155 | 190 | } |
156 | 191 | } |
157 | 192 | |
... | ... | @@ -281,6 +316,6 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { |
281 | 316 | |
282 | 317 | private void logAction(TenantId tenantId, CustomerId customerId, Device device, boolean success, ProvisionRequest provisionRequest) { |
283 | 318 | ActionType actionType = success ? ActionType.PROVISION_SUCCESS : ActionType.PROVISION_FAILURE; |
284 | - auditLogService.logEntityAction(tenantId, customerId, null, device.getName(), device.getId(), device, actionType, null, provisionRequest); | |
319 | + auditLogService.logEntityAction(tenantId, customerId, new UserId(UserId.NULL_UUID), device.getName(), device.getId(), device, actionType, null, provisionRequest); | |
285 | 320 | } |
286 | 321 | } | ... | ... |
... | ... | @@ -22,6 +22,7 @@ import com.google.common.util.concurrent.Futures; |
22 | 22 | import com.google.common.util.concurrent.ListenableFuture; |
23 | 23 | import com.google.common.util.concurrent.MoreExecutors; |
24 | 24 | import com.google.protobuf.ByteString; |
25 | +import com.google.protobuf.InvalidProtocolBufferException; | |
25 | 26 | import lombok.extern.slf4j.Slf4j; |
26 | 27 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
27 | 28 | import org.springframework.stereotype.Service; |
... | ... | @@ -31,6 +32,7 @@ import org.thingsboard.server.common.data.Device; |
31 | 32 | import org.thingsboard.server.common.data.DeviceProfile; |
32 | 33 | import org.thingsboard.server.common.data.TenantProfile; |
33 | 34 | import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; |
35 | +import org.thingsboard.server.common.data.device.data.ProvisionDeviceConfiguration; | |
34 | 36 | import org.thingsboard.server.common.data.id.CustomerId; |
35 | 37 | import org.thingsboard.server.common.data.id.DeviceId; |
36 | 38 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
... | ... | @@ -45,17 +47,24 @@ import org.thingsboard.server.common.msg.TbMsgMetaData; |
45 | 47 | import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; |
46 | 48 | import org.thingsboard.server.dao.device.DeviceCredentialsService; |
47 | 49 | import org.thingsboard.server.dao.device.DeviceProfileService; |
50 | +import org.thingsboard.server.dao.device.DeviceProvisionService; | |
48 | 51 | import org.thingsboard.server.dao.device.DeviceService; |
52 | +import org.thingsboard.server.dao.device.provision.ProvisionRequest; | |
53 | +import org.thingsboard.server.dao.device.provision.ProvisionResponse; | |
54 | +import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus; | |
49 | 55 | import org.thingsboard.server.dao.relation.RelationService; |
50 | 56 | import org.thingsboard.server.dao.tenant.TenantProfileService; |
51 | 57 | import org.thingsboard.server.dao.tenant.TenantService; |
52 | 58 | import org.thingsboard.server.dao.util.mapping.JacksonUtil; |
53 | 59 | import org.thingsboard.server.gen.transport.TransportProtos; |
60 | +import org.thingsboard.server.gen.transport.TransportProtos.CredentialsType; | |
54 | 61 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; |
55 | 62 | import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; |
56 | 63 | import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayResponseMsg; |
57 | 64 | import org.thingsboard.server.gen.transport.TransportProtos.GetTenantRoutingInfoRequestMsg; |
58 | 65 | import org.thingsboard.server.gen.transport.TransportProtos.GetTenantRoutingInfoResponseMsg; |
66 | +import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceCredentialsMsg; | |
67 | +import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; | |
59 | 68 | import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg; |
60 | 69 | import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg; |
61 | 70 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; |
... | ... | @@ -94,6 +103,7 @@ public class DefaultTransportApiService implements TransportApiService { |
94 | 103 | private final DbCallbackExecutorService dbCallbackExecutorService; |
95 | 104 | private final TbClusterService tbClusterService; |
96 | 105 | private final DataDecodingEncodingService dataDecodingEncodingService; |
106 | + private final DeviceProvisionService deviceProvisionService; | |
97 | 107 | |
98 | 108 | |
99 | 109 | private final ConcurrentMap<String, ReentrantLock> deviceCreationLocks = new ConcurrentHashMap<>(); |
... | ... | @@ -102,7 +112,8 @@ public class DefaultTransportApiService implements TransportApiService { |
102 | 112 | TenantProfileService tenantProfileService, DeviceService deviceService, |
103 | 113 | RelationService relationService, DeviceCredentialsService deviceCredentialsService, |
104 | 114 | DeviceStateService deviceStateService, DbCallbackExecutorService dbCallbackExecutorService, |
105 | - TbClusterService tbClusterService, DataDecodingEncodingService dataDecodingEncodingService) { | |
115 | + TbClusterService tbClusterService, DataDecodingEncodingService dataDecodingEncodingService, | |
116 | + DeviceProvisionService deviceProvisionService) { | |
106 | 117 | this.deviceProfileService = deviceProfileService; |
107 | 118 | this.tenantService = tenantService; |
108 | 119 | this.tenantProfileService = tenantProfileService; |
... | ... | @@ -113,6 +124,7 @@ public class DefaultTransportApiService implements TransportApiService { |
113 | 124 | this.dbCallbackExecutorService = dbCallbackExecutorService; |
114 | 125 | this.tbClusterService = tbClusterService; |
115 | 126 | this.dataDecodingEncodingService = dataDecodingEncodingService; |
127 | + this.deviceProvisionService = deviceProvisionService; | |
116 | 128 | } |
117 | 129 | |
118 | 130 | @Override |
... | ... | @@ -139,6 +151,9 @@ public class DefaultTransportApiService implements TransportApiService { |
139 | 151 | } else if (transportApiRequestMsg.hasGetDeviceProfileRequestMsg()) { |
140 | 152 | return Futures.transform(handle(transportApiRequestMsg.getGetDeviceProfileRequestMsg()), |
141 | 153 | value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); |
154 | + } else if (transportApiRequestMsg.hasProvisionDeviceRequestMsg()) { | |
155 | + return Futures.transform(handle(transportApiRequestMsg.getProvisionDeviceRequestMsg()), | |
156 | + value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); | |
142 | 157 | } |
143 | 158 | return Futures.transform(getEmptyTransportApiResponseFuture(), |
144 | 159 | value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); |
... | ... | @@ -261,6 +276,47 @@ public class DefaultTransportApiService implements TransportApiService { |
261 | 276 | }, dbCallbackExecutorService); |
262 | 277 | } |
263 | 278 | |
279 | + | |
280 | + private ListenableFuture<TransportApiResponseMsg> handle(ProvisionDeviceRequestMsg requestMsg) { | |
281 | + ListenableFuture<ProvisionResponse> provisionResponseFuture = null; | |
282 | + provisionResponseFuture = deviceProvisionService.provisionDevice( | |
283 | + new ProvisionRequest( | |
284 | + requestMsg.getDeviceName(), | |
285 | + requestMsg.getDeviceType(), | |
286 | + requestMsg.getX509CertPubKey(), | |
287 | + new ProvisionDeviceConfiguration( | |
288 | + requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceKey(), | |
289 | + requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceSecret()))); | |
290 | + return Futures.transform(provisionResponseFuture, provisionResponse -> { | |
291 | + if (provisionResponse.getResponseStatus() == ProvisionResponseStatus.NOT_FOUND) { | |
292 | + return getTransportApiResponseMsg(TransportProtos.DeviceCredentialsProto.getDefaultInstance(), TransportProtos.ProvisionResponseStatus.NOT_FOUND); | |
293 | + } else if (provisionResponse.getResponseStatus() == ProvisionResponseStatus.FAILURE) { | |
294 | + return getTransportApiResponseMsg(TransportProtos.DeviceCredentialsProto.getDefaultInstance(), TransportProtos.ProvisionResponseStatus.FAILURE); | |
295 | + } else { | |
296 | + return getTransportApiResponseMsg(getDeviceCredentials(provisionResponse.getDeviceCredentials()), TransportProtos.ProvisionResponseStatus.SUCCESS); | |
297 | + } | |
298 | + }, dbCallbackExecutorService); | |
299 | + } | |
300 | + | |
301 | + private TransportApiResponseMsg getTransportApiResponseMsg(TransportProtos.DeviceCredentialsProto deviceCredentials, TransportProtos.ProvisionResponseStatus status) { | |
302 | + return TransportApiResponseMsg.newBuilder() | |
303 | + .setProvisionDeviceResponseMsg(TransportProtos.ProvisionDeviceResponseMsg.newBuilder() | |
304 | + .setDeviceCredentials(deviceCredentials) | |
305 | + .setProvisionResponseStatus(status) | |
306 | + .build()) | |
307 | + .build(); | |
308 | + } | |
309 | + | |
310 | + private TransportProtos.DeviceCredentialsProto getDeviceCredentials(DeviceCredentials deviceCredentials) { | |
311 | + return TransportProtos.DeviceCredentialsProto.newBuilder() | |
312 | + .setDeviceIdMSB(deviceCredentials.getDeviceId().getId().getMostSignificantBits()) | |
313 | + .setDeviceIdLSB(deviceCredentials.getDeviceId().getId().getLeastSignificantBits()) | |
314 | + .setCredentialsType(deviceCredentials.getCredentialsType() == DeviceCredentialsType.ACCESS_TOKEN ? | |
315 | + CredentialsType.ACCESS_TOKEN : CredentialsType.X509_CERTIFICATE) | |
316 | + .setCredentialsId(deviceCredentials.getCredentialsId()) | |
317 | + .setCredentialsValue(deviceCredentials.getCredentialsValue() != null ? deviceCredentials.getCredentialsValue() : "") | |
318 | + .build(); | |
319 | + } | |
264 | 320 | private ListenableFuture<TransportApiResponseMsg> handle(GetTenantRoutingInfoRequestMsg requestMsg) { |
265 | 321 | TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); |
266 | 322 | // TODO: Tenant Profile from cache | ... | ... |
... | ... | @@ -473,7 +473,9 @@ spring: |
473 | 473 | enabled: "true" |
474 | 474 | jpa: |
475 | 475 | open-in-view: "false" |
476 | + show-sql: "true" | |
476 | 477 | hibernate: |
478 | + format_sql: "true" | |
477 | 479 | ddl-auto: "none" |
478 | 480 | database-platform: "${SPRING_JPA_DATABASE_PLATFORM:org.hibernate.dialect.PostgreSQLDialect}" |
479 | 481 | datasource: | ... | ... |
... | ... | @@ -27,7 +27,8 @@ import org.thingsboard.server.common.data.DeviceProfileType; |
27 | 27 | include = JsonTypeInfo.As.PROPERTY, |
28 | 28 | property = "type") |
29 | 29 | @JsonSubTypes({ |
30 | - @JsonSubTypes.Type(value = DefaultDeviceConfiguration.class, name = "DEFAULT")}) | |
30 | + @JsonSubTypes.Type(value = DefaultDeviceConfiguration.class, name = "DEFAULT"), | |
31 | + @JsonSubTypes.Type(value = ProvisionDeviceConfiguration.class, name = "PROVISION")}) | |
31 | 32 | public interface DeviceConfiguration { |
32 | 33 | |
33 | 34 | @JsonIgnore | ... | ... |
... | ... | @@ -477,7 +477,7 @@ message TransportApiRequestMsg { |
477 | 477 | GetTenantRoutingInfoRequestMsg getTenantRoutingInfoRequestMsg = 4; |
478 | 478 | GetDeviceProfileRequestMsg getDeviceProfileRequestMsg = 5; |
479 | 479 | ValidateBasicMqttCredRequestMsg validateBasicMqttCredRequestMsg = 6; |
480 | -// ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7; | |
480 | + ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7; | |
481 | 481 | } |
482 | 482 | |
483 | 483 | /* Response from ThingsBoard Core Service to Transport Service */ |
... | ... | @@ -486,7 +486,7 @@ message TransportApiResponseMsg { |
486 | 486 | GetOrCreateDeviceFromGatewayResponseMsg getOrCreateDeviceResponseMsg = 2; |
487 | 487 | GetTenantRoutingInfoResponseMsg getTenantRoutingInfoResponseMsg = 4; |
488 | 488 | GetDeviceProfileResponseMsg getDeviceProfileResponseMsg = 5; |
489 | -// ProvisionDeviceResponseMsg provisionDeviceResponseMsg = 6; | |
489 | + ProvisionDeviceResponseMsg provisionDeviceResponseMsg = 6; | |
490 | 490 | } |
491 | 491 | |
492 | 492 | /* Messages that are handled by ThingsBoard Core Service */ | ... | ... |
common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java
... | ... | @@ -24,6 +24,7 @@ import org.eclipse.californium.core.network.ExchangeObserver; |
24 | 24 | import org.eclipse.californium.core.server.resources.CoapExchange; |
25 | 25 | import org.eclipse.californium.core.server.resources.Resource; |
26 | 26 | import org.springframework.util.ReflectionUtils; |
27 | +import org.thingsboard.server.common.data.DataConstants; | |
27 | 28 | import org.thingsboard.server.common.data.DeviceTransportType; |
28 | 29 | import org.thingsboard.server.common.data.security.DeviceTokenCredentials; |
29 | 30 | import org.thingsboard.server.common.msg.session.FeatureType; |
... | ... | @@ -33,9 +34,11 @@ import org.thingsboard.server.common.transport.TransportContext; |
33 | 34 | import org.thingsboard.server.common.transport.TransportService; |
34 | 35 | import org.thingsboard.server.common.transport.TransportServiceCallback; |
35 | 36 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; |
37 | +import org.thingsboard.server.common.transport.adaptor.JsonConverter; | |
36 | 38 | import org.thingsboard.server.common.transport.auth.SessionInfoCreator; |
37 | 39 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
38 | 40 | import org.thingsboard.server.gen.transport.TransportProtos; |
41 | +import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; | |
39 | 42 | |
40 | 43 | import java.lang.reflect.Field; |
41 | 44 | import java.util.List; |
... | ... | @@ -130,10 +133,25 @@ public class CoapTransportResource extends CoapResource { |
130 | 133 | case CLAIM: |
131 | 134 | processRequest(exchange, SessionMsgType.CLAIM_REQUEST); |
132 | 135 | break; |
136 | + case PROVISION: | |
137 | + processProvision(exchange); | |
138 | + break; | |
133 | 139 | } |
134 | 140 | } |
135 | 141 | } |
136 | 142 | |
143 | + private void processProvision(CoapExchange exchange) { | |
144 | + log.trace("Processing {}", exchange.advanced().getRequest()); | |
145 | + exchange.accept(); | |
146 | + try { | |
147 | + transportService.process(transportContext.getAdaptor().convertToProvisionRequestMsg(UUID.randomUUID(), exchange.advanced().getRequest()), | |
148 | + new DeviceProvisionCallback(exchange)); | |
149 | + } catch (AdaptorException e) { | |
150 | + log.trace("Failed to decode message: ", e); | |
151 | + exchange.respond(ResponseCode.BAD_REQUEST); | |
152 | + } | |
153 | + } | |
154 | + | |
137 | 155 | private void processRequest(CoapExchange exchange, SessionMsgType type) { |
138 | 156 | log.trace("Processing {}", exchange.advanced().getRequest()); |
139 | 157 | exchange.accept(); |
... | ... | @@ -274,6 +292,8 @@ public class CoapTransportResource extends CoapResource { |
274 | 292 | try { |
275 | 293 | if (uriPath.size() >= FEATURE_TYPE_POSITION) { |
276 | 294 | return Optional.of(FeatureType.valueOf(uriPath.get(FEATURE_TYPE_POSITION - 1).toUpperCase())); |
295 | + } else if (uriPath.size() == 3 && uriPath.contains(DataConstants.PROVISION)) { | |
296 | + return Optional.of(FeatureType.valueOf(DataConstants.PROVISION.toUpperCase())); | |
277 | 297 | } |
278 | 298 | } catch (RuntimeException e) { |
279 | 299 | log.warn("Failed to decode feature type: {}", uriPath); |
... | ... | @@ -325,6 +345,25 @@ public class CoapTransportResource extends CoapResource { |
325 | 345 | } |
326 | 346 | } |
327 | 347 | |
348 | + private static class DeviceProvisionCallback implements TransportServiceCallback<ProvisionDeviceResponseMsg> { | |
349 | + private final CoapExchange exchange; | |
350 | + | |
351 | + DeviceProvisionCallback(CoapExchange exchange) { | |
352 | + this.exchange = exchange; | |
353 | + } | |
354 | + | |
355 | + @Override | |
356 | + public void onSuccess(TransportProtos.ProvisionDeviceResponseMsg msg) { | |
357 | + exchange.respond(JsonConverter.toJson(msg).toString()); | |
358 | + } | |
359 | + | |
360 | + @Override | |
361 | + public void onError(Throwable e) { | |
362 | + log.warn("Failed to process request", e); | |
363 | + exchange.respond(ResponseCode.INTERNAL_SERVER_ERROR); | |
364 | + } | |
365 | + } | |
366 | + | |
328 | 367 | private static class CoapOkCallback implements TransportServiceCallback<Void> { |
329 | 368 | private final CoapExchange exchange; |
330 | 369 | ... | ... |
... | ... | @@ -19,6 +19,7 @@ import org.eclipse.californium.core.coap.Request; |
19 | 19 | import org.eclipse.californium.core.coap.Response; |
20 | 20 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; |
21 | 21 | import org.thingsboard.server.gen.transport.TransportProtos; |
22 | +import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; | |
22 | 23 | import org.thingsboard.server.transport.coap.CoapTransportResource; |
23 | 24 | |
24 | 25 | import java.util.UUID; |
... | ... | @@ -45,4 +46,6 @@ public interface CoapTransportAdaptor { |
45 | 46 | |
46 | 47 | Response convertToPublish(CoapTransportResource.CoapSessionListener coapSessionListener, TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException; |
47 | 48 | |
49 | + ProvisionDeviceRequestMsg convertToProvisionRequestMsg(UUID sessionId, Request inbound) throws AdaptorException; | |
50 | + | |
48 | 51 | } | ... | ... |
... | ... | @@ -124,6 +124,16 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { |
124 | 124 | } |
125 | 125 | |
126 | 126 | @Override |
127 | + public TransportProtos.ProvisionDeviceRequestMsg convertToProvisionRequestMsg(UUID sessionId, Request inbound) throws AdaptorException { | |
128 | + String payload = validatePayload(sessionId, inbound, false); | |
129 | + try { | |
130 | + return JsonConverter.convertToProvisionRequestMsg(payload); | |
131 | + } catch (IllegalStateException | JsonSyntaxException ex) { | |
132 | + throw new AdaptorException(ex); | |
133 | + } | |
134 | + } | |
135 | + | |
136 | + @Override | |
127 | 137 | public Response convertToPublish(CoapTransportResource.CoapSessionListener session, TransportProtos.GetAttributeResponseMsg msg) throws AdaptorException { |
128 | 138 | if (msg.getClientAttributeListCount() == 0 && msg.getSharedAttributeListCount() == 0) { |
129 | 139 | return new Response(CoAP.ResponseCode.NOT_FOUND); | ... | ... |
... | ... | @@ -44,6 +44,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotif |
44 | 44 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; |
45 | 45 | import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg; |
46 | 46 | import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponseMsg; |
47 | +import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; | |
47 | 48 | import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotificationProto; |
48 | 49 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; |
49 | 50 | import org.thingsboard.server.gen.transport.TransportProtos.SubscribeToAttributeUpdatesMsg; |
... | ... | @@ -203,6 +204,14 @@ public class DeviceApiController { |
203 | 204 | return responseWriter; |
204 | 205 | } |
205 | 206 | |
207 | + @RequestMapping(value = "/provision", method = RequestMethod.POST) | |
208 | + public DeferredResult<ResponseEntity> provisionDevice(@RequestBody String json, HttpServletRequest httpRequest) { | |
209 | + DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>(); | |
210 | + transportContext.getTransportService().process(JsonConverter.convertToProvisionRequestMsg(json), | |
211 | + new DeviceProvisionCallback(responseWriter)); | |
212 | + return responseWriter; | |
213 | + } | |
214 | + | |
206 | 215 | private static class DeviceAuthCallback implements TransportServiceCallback<ValidateDeviceCredentialsResponse> { |
207 | 216 | private final TransportContext transportContext; |
208 | 217 | private final DeferredResult<ResponseEntity> responseWriter; |
... | ... | @@ -230,6 +239,25 @@ public class DeviceApiController { |
230 | 239 | } |
231 | 240 | } |
232 | 241 | |
242 | + private static class DeviceProvisionCallback implements TransportServiceCallback<ProvisionDeviceResponseMsg> { | |
243 | + private final DeferredResult<ResponseEntity> responseWriter; | |
244 | + | |
245 | + DeviceProvisionCallback(DeferredResult<ResponseEntity> responseWriter) { | |
246 | + this.responseWriter = responseWriter; | |
247 | + } | |
248 | + | |
249 | + @Override | |
250 | + public void onSuccess(ProvisionDeviceResponseMsg msg) { | |
251 | + responseWriter.setResult(new ResponseEntity<>(JsonConverter.toJson(msg).toString(), HttpStatus.OK)); | |
252 | + } | |
253 | + | |
254 | + @Override | |
255 | + public void onError(Throwable e) { | |
256 | + log.warn("Failed to process request", e); | |
257 | + responseWriter.setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); | |
258 | + } | |
259 | + } | |
260 | + | |
233 | 261 | private static class SessionCloseOnErrorCallback implements TransportServiceCallback<Void> { |
234 | 262 | private final TransportService transportService; |
235 | 263 | private final SessionInfoProto sessionInfo; | ... | ... |
... | ... | @@ -154,7 +154,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement |
154 | 154 | try { |
155 | 155 | if (topicName.equals(MqttTopics.DEVICE_PROVISION_REQUEST_TOPIC)) { |
156 | 156 | TransportProtos.ProvisionDeviceRequestMsg provisionRequestMsg = adaptor.convertToProvisionRequestMsg(deviceSessionCtx, mqttMsg); |
157 | - transportService.process(deviceSessionCtx.getSessionInfo(), provisionRequestMsg, (TransportServiceCallback) new DeviceProvisionCallback(ctx, msgId, provisionRequestMsg)); | |
157 | + transportService.process(provisionRequestMsg, new DeviceProvisionCallback(ctx, msgId, provisionRequestMsg)); | |
158 | 158 | log.trace("[{}][{}] Processing publish msg [{}][{}]!", sessionId, deviceSessionCtx.getDeviceId(), topicName, msgId); |
159 | 159 | } else { |
160 | 160 | throw new RuntimeException("Unsupported topic for provisioning requests!"); |
... | ... | @@ -167,6 +167,10 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement |
167 | 167 | case PINGREQ: |
168 | 168 | ctx.writeAndFlush(new MqttMessage(new MqttFixedHeader(PINGRESP, false, AT_MOST_ONCE, false, 0))); |
169 | 169 | break; |
170 | +// case SUBSCRIBE: | |
171 | +// deviceSessionCtx.setDeviceInfo(TransportDeviceInfo); | |
172 | +// processSubscribe(ctx, (MqttSubscribeMessage) msg); | |
173 | +// break; | |
170 | 174 | case DISCONNECT: |
171 | 175 | ctx.close(); |
172 | 176 | break; |
... | ... | @@ -425,7 +429,6 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement |
425 | 429 | log.info("[{}] Processing connect msg for client: {}!", sessionId, msg.payload().clientIdentifier()); |
426 | 430 | String userName = msg.payload().userName(); |
427 | 431 | if (DataConstants.PROVISION.equals(userName)) { |
428 | - deviceSessionCtx.setDeviceInfo(new TransportDeviceInfo()); | |
429 | 432 | deviceSessionCtx.setProvisionOnly(true); |
430 | 433 | ctx.writeAndFlush(createMqttConnAckMsg(CONNECTION_ACCEPTED)); |
431 | 434 | } else { | ... | ... |
... | ... | @@ -28,6 +28,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetTenantRoutingInfo |
28 | 28 | import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; |
29 | 29 | import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg; |
30 | 30 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; |
31 | +import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; | |
31 | 32 | import org.thingsboard.server.gen.transport.TransportProtos.SessionEventMsg; |
32 | 33 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; |
33 | 34 | import org.thingsboard.server.gen.transport.TransportProtos.SubscribeToAttributeUpdatesMsg; |
... | ... | @@ -58,6 +59,9 @@ public interface TransportService { |
58 | 59 | void process(GetOrCreateDeviceFromGatewayRequestMsg msg, |
59 | 60 | TransportServiceCallback<GetOrCreateDeviceFromGatewayResponse> callback); |
60 | 61 | |
62 | + void process(ProvisionDeviceRequestMsg msg, | |
63 | + TransportServiceCallback<ProvisionDeviceResponseMsg> callback); | |
64 | + | |
61 | 65 | void getDeviceProfile(DeviceProfileId deviceProfileId, TransportServiceCallback<DeviceProfile> callback); |
62 | 66 | |
63 | 67 | void onProfileUpdate(DeviceProfile deviceProfile); |
... | ... | @@ -84,8 +88,6 @@ public interface TransportService { |
84 | 88 | |
85 | 89 | void process(SessionInfoProto sessionInfo, ClaimDeviceMsg msg, TransportServiceCallback<Void> callback); |
86 | 90 | |
87 | - void process(SessionInfoProto sessionInfo, ProvisionDeviceRequestMsg msg, TransportServiceCallback<Void> deviceProvisionCallback); | |
88 | - | |
89 | 91 | void registerAsyncSession(SessionInfoProto sessionInfo, SessionMsgListener listener); |
90 | 92 | |
91 | 93 | void registerSyncSession(SessionInfoProto sessionInfo, SessionMsgListener listener, long timeout); | ... | ... |
... | ... | @@ -52,6 +52,8 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes |
52 | 52 | import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; |
53 | 53 | import org.thingsboard.server.common.transport.util.JsonUtils; |
54 | 54 | import org.thingsboard.server.gen.transport.TransportProtos; |
55 | +import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; | |
56 | +import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; | |
55 | 57 | import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; |
56 | 58 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; |
57 | 59 | import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; |
... | ... | @@ -333,6 +335,16 @@ public class DefaultTransportService implements TransportService { |
333 | 335 | } |
334 | 336 | |
335 | 337 | @Override |
338 | + public void process(ProvisionDeviceRequestMsg requestMsg, TransportServiceCallback<ProvisionDeviceResponseMsg> callback) { | |
339 | + log.trace("Processing msg: {}", requestMsg); | |
340 | + TbProtoQueueMsg<TransportApiRequestMsg> protoMsg = new TbProtoQueueMsg<>(UUID.randomUUID(), TransportApiRequestMsg.newBuilder().setProvisionDeviceRequestMsg(requestMsg).build()); | |
341 | + ListenableFuture<ProvisionDeviceResponseMsg> response = Futures.transform(transportApiRequestTemplate.send(protoMsg), tmp -> | |
342 | + tmp.getValue().getProvisionDeviceResponseMsg() | |
343 | + , MoreExecutors.directExecutor()); | |
344 | + AsyncCallbackTemplate.withCallback(response, callback::onSuccess, callback::onError, transportCallbackExecutor); | |
345 | + } | |
346 | + | |
347 | + @Override | |
336 | 348 | public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.SubscriptionInfoProto msg, TransportServiceCallback<Void> callback) { |
337 | 349 | if (log.isTraceEnabled()) { |
338 | 350 | log.trace("[{}] Processing msg: {}", toSessionId(sessionInfo), msg); |
... | ... | @@ -485,15 +497,6 @@ public class DefaultTransportService implements TransportService { |
485 | 497 | } |
486 | 498 | |
487 | 499 | @Override |
488 | - public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ProvisionDeviceRequestMsg msg, TransportServiceCallback<Void> callback) { | |
489 | - if (checkLimits(sessionInfo, msg, callback)) { | |
490 | - reportActivityInternal(sessionInfo); | |
491 | - sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo) | |
492 | - .setProvisionDevice(msg).build(), callback); | |
493 | - } | |
494 | - } | |
495 | - | |
496 | - @Override | |
497 | 500 | public void reportActivity(TransportProtos.SessionInfoProto sessionInfo) { |
498 | 501 | reportActivityInternal(sessionInfo); |
499 | 502 | } | ... | ... |
... | ... | @@ -215,6 +215,6 @@ public interface DeviceDao extends Dao<Device> { |
215 | 215 | */ |
216 | 216 | PageData<Device> findDevicesByTenantIdAndProfileId(UUID tenantId, UUID profileId, PageLink pageLink); |
217 | 217 | |
218 | - Device findDeviceByTenantIdAndDeviceDataProvisionConfigurationPair(TenantId tenantId, String provisionDeviceKey, String provisionDeviceSecret); | |
218 | + Optional<Device> findDeviceByProfileNameAndDeviceDataProvisionConfigurationPair(String profileName, String provisionDeviceKey, String provisionDeviceSecret); | |
219 | 219 | |
220 | 220 | } | ... | ... |
... | ... | @@ -22,6 +22,7 @@ import org.thingsboard.server.common.data.page.PageData; |
22 | 22 | import org.thingsboard.server.common.data.page.PageLink; |
23 | 23 | import org.thingsboard.server.dao.Dao; |
24 | 24 | |
25 | +import java.util.Optional; | |
25 | 26 | import java.util.UUID; |
26 | 27 | |
27 | 28 | public interface DeviceProfileDao extends Dao<DeviceProfile> { |
... | ... | @@ -38,9 +39,7 @@ public interface DeviceProfileDao extends Dao<DeviceProfile> { |
38 | 39 | |
39 | 40 | DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId); |
40 | 41 | |
41 | - DeviceProfileInfo findProfileInfoByTenantIdAndProfileDataProvisionConfigurationPair(TenantId tenantId, String provisionDeviceKey, String provisionDeviceSecret); | |
42 | - | |
43 | - DeviceProfile findProfileByTenantIdAndProfileDataProvisionConfigurationPair(TenantId tenantId, String provisionDeviceKey, String provisionDeviceSecret); | |
42 | + DeviceProfile findProfileByProfileNameAndProfileDataProvisionConfigurationPair(String profileName, String provisionDeviceKey, String provisionDeviceSecret); | |
44 | 43 | |
45 | 44 | DeviceProfile findByName(TenantId tenantId, String profileName); |
46 | 45 | } | ... | ... |
... | ... | @@ -20,9 +20,7 @@ import org.springframework.data.domain.Pageable; |
20 | 20 | import org.springframework.data.jpa.repository.Query; |
21 | 21 | import org.springframework.data.repository.PagingAndSortingRepository; |
22 | 22 | import org.springframework.data.repository.query.Param; |
23 | -import org.thingsboard.server.common.data.DeviceProfile; | |
24 | 23 | import org.thingsboard.server.common.data.DeviceProfileInfo; |
25 | -import org.thingsboard.server.common.data.DeviceProfileType; | |
26 | 24 | import org.thingsboard.server.dao.model.sql.DeviceProfileEntity; |
27 | 25 | |
28 | 26 | import java.util.UUID; |
... | ... | @@ -58,23 +56,14 @@ public interface DeviceProfileRepository extends PagingAndSortingRepository<Devi |
58 | 56 | |
59 | 57 | DeviceProfileEntity findByTenantIdAndName(UUID id, String profileName); |
60 | 58 | |
61 | - @Query(value = "SELECT d FROM DeviceProfileEntity d " + | |
62 | - "WHERE d.tenantId = :tenantId " + | |
63 | - "AND d.profileData::jsonb->>{'configuration', 'provisionDeviceKey'} = :provisionDeviceKey " + | |
64 | - "AND d.profileData::jsonb->>{'configuration', 'provisionDeviceSecret' = :provisionDeviceSecret}", | |
59 | + @Query(value = "SELECT d.* FROM device_profile as d " + | |
60 | + "WHERE d.name = :profileName " + | |
61 | + "AND d.profile_data->'configuration'->>'provisionDeviceKey' IS NOT NULL " + | |
62 | + "AND d.profile_data->'configuration'->>'provisionDeviceSecret' IS NOT NULL " + | |
63 | + "AND d.profile_data->'configuration'->>'provisionDeviceKey' = :provisionDeviceKey " + | |
64 | + "AND d.profile_data->'configuration'->>'provisionDeviceSecret' = :provisionDeviceSecret", | |
65 | 65 | nativeQuery = true) |
66 | - DeviceProfileEntity findProfileByTenantIdAndProfileDataProvisionConfigurationPair(@Param("tenantId") UUID tenantId, | |
67 | - @Param("provisionDeviceKey") String provisionDeviceKey, | |
68 | - @Param("provisionDeviceSecret") String provisionDeviceSecret); | |
69 | - | |
70 | - @Query(value = "SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.type, d.transportType) " + | |
71 | - " FROM DeviceProfileEntity d " + | |
72 | - "WHERE d.tenantId = :tenantId " + | |
73 | - "AND d.profileData::jsonb->>{'configuration', 'provisionDeviceKey'} = :provisionDeviceKey " + | |
74 | - "AND d.profileData::jsonb->>{'configuration', 'provisionDeviceSecret' = :provisionDeviceSecret}", | |
75 | - nativeQuery = true) | |
76 | - DeviceProfileInfo findProfileInfoByTenantIdAndProfileDataProvisionConfigurationPair(@Param("tenantId") UUID tenantId, | |
77 | - @Param("provisionDeviceKey") String provisionDeviceKey, | |
78 | - @Param("provisionDeviceSecret") String provisionDeviceSecret); | |
79 | - | |
66 | + DeviceProfileEntity findProfileByProfileNameAndProfileDataProvisionConfigurationPair(@Param("profileName") String profileName, | |
67 | + @Param("provisionDeviceKey") String provisionDeviceKey, | |
68 | + @Param("provisionDeviceSecret") String provisionDeviceSecret); | |
80 | 69 | } | ... | ... |
... | ... | @@ -20,10 +20,8 @@ import org.springframework.data.domain.Pageable; |
20 | 20 | import org.springframework.data.jpa.repository.Query; |
21 | 21 | import org.springframework.data.repository.PagingAndSortingRepository; |
22 | 22 | import org.springframework.data.repository.query.Param; |
23 | -import org.thingsboard.server.common.data.DeviceProfileInfo; | |
24 | 23 | import org.thingsboard.server.dao.model.sql.DeviceEntity; |
25 | 24 | import org.thingsboard.server.dao.model.sql.DeviceInfoEntity; |
26 | -import org.thingsboard.server.dao.model.sql.DeviceProfileEntity; | |
27 | 25 | |
28 | 26 | import java.util.List; |
29 | 27 | import java.util.UUID; |
... | ... | @@ -171,12 +169,12 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit |
171 | 169 | |
172 | 170 | Long countByDeviceProfileId(UUID deviceProfileId); |
173 | 171 | |
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", | |
172 | + @Query(value = "SELECT * FROM Device as d " + | |
173 | + "WHERE d.device_data->'configuration'->>'provisionDeviceKey' = :provisionDeviceKey " + | |
174 | + "AND d.device_data->'configuration'->>'provisionDeviceSecret' = :provisionDeviceSecret " + | |
175 | + "AND d.type = :profileName", | |
178 | 176 | nativeQuery = true) |
179 | - DeviceEntity findDeviceByTenantIdAndDeviceDataProvisionConfigurationPair(@Param("tenantId") UUID tenantId, | |
180 | - @Param("provisionDeviceKey") String provisionDeviceKey, | |
181 | - @Param("provisionDeviceSecret") String provisionDeviceSecret); | |
177 | + DeviceEntity findDeviceByProfileNameAndDeviceDataProvisionConfigurationPair(@Param("profileName") String profileName, | |
178 | + @Param("provisionDeviceKey") String provisionDeviceKey, | |
179 | + @Param("provisionDeviceSecret") String provisionDeviceSecret); | |
182 | 180 | } | ... | ... |
... | ... | @@ -22,8 +22,6 @@ import org.springframework.stereotype.Component; |
22 | 22 | import org.springframework.util.StringUtils; |
23 | 23 | import org.thingsboard.server.common.data.Device; |
24 | 24 | import org.thingsboard.server.common.data.DeviceInfo; |
25 | -import org.thingsboard.server.common.data.DeviceProfile; | |
26 | -import org.thingsboard.server.common.data.DeviceProfileInfo; | |
27 | 25 | import org.thingsboard.server.common.data.EntitySubtype; |
28 | 26 | import org.thingsboard.server.common.data.EntityType; |
29 | 27 | import org.thingsboard.server.common.data.id.TenantId; |
... | ... | @@ -222,8 +220,8 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> |
222 | 220 | } |
223 | 221 | |
224 | 222 | @Override |
225 | - public Device findDeviceByTenantIdAndDeviceDataProvisionConfigurationPair(TenantId tenantId, String provisionDeviceKey, String provisionDeviceSecret) { | |
226 | - return DaoUtil.getData(deviceRepository.findDeviceByTenantIdAndDeviceDataProvisionConfigurationPair(tenantId.getId(), provisionDeviceKey, provisionDeviceSecret)); | |
223 | + public Optional<Device> findDeviceByProfileNameAndDeviceDataProvisionConfigurationPair(String profileName, String provisionDeviceKey, String provisionDeviceSecret) { | |
224 | + return Optional.ofNullable(DaoUtil.getData(deviceRepository.findDeviceByProfileNameAndDeviceDataProvisionConfigurationPair(profileName, provisionDeviceKey, provisionDeviceSecret))); | |
227 | 225 | } |
228 | 226 | |
229 | 227 | private List<EntitySubtype> convertTenantDeviceTypesToDto(UUID tenantId, List<String> types) { | ... | ... |
... | ... | @@ -29,6 +29,7 @@ import org.thingsboard.server.dao.model.sql.DeviceProfileEntity; |
29 | 29 | import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; |
30 | 30 | |
31 | 31 | import java.util.Objects; |
32 | +import java.util.Optional; | |
32 | 33 | import java.util.UUID; |
33 | 34 | |
34 | 35 | @Component |
... | ... | @@ -81,13 +82,8 @@ public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao<DeviceProfileE |
81 | 82 | } |
82 | 83 | |
83 | 84 | @Override |
84 | - public DeviceProfile findProfileByTenantIdAndProfileDataProvisionConfigurationPair(TenantId tenantId, String provisionDeviceKey, String provisionDeviceSecret) { | |
85 | - return DaoUtil.getData(deviceProfileRepository.findProfileByTenantIdAndProfileDataProvisionConfigurationPair(tenantId.getId(), provisionDeviceKey, provisionDeviceSecret)); | |
86 | - } | |
87 | - | |
88 | - @Override | |
89 | - public DeviceProfileInfo findProfileInfoByTenantIdAndProfileDataProvisionConfigurationPair(TenantId tenantId, String provisionDeviceKey, String provisionDeviceSecret) { | |
90 | - return deviceProfileRepository.findProfileInfoByTenantIdAndProfileDataProvisionConfigurationPair(tenantId.getId(), provisionDeviceKey, provisionDeviceSecret); | |
85 | + public DeviceProfile findProfileByProfileNameAndProfileDataProvisionConfigurationPair(String profileName, String provisionDeviceKey, String provisionDeviceSecret) { | |
86 | + return DaoUtil.getData(deviceProfileRepository.findProfileByProfileNameAndProfileDataProvisionConfigurationPair(profileName, provisionDeviceKey, provisionDeviceSecret)); | |
91 | 87 | } |
92 | 88 | |
93 | 89 | @Override | ... | ... |