...
|
...
|
@@ -15,7 +15,6 @@ |
15
|
15
|
*/
|
16
|
16
|
package org.thingsboard.server.service.device;
|
17
|
17
|
|
18
|
|
-import com.datastax.oss.driver.api.core.uuid.Uuids;
|
19
|
18
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
20
|
19
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
21
|
20
|
import com.google.common.util.concurrent.Futures;
|
...
|
...
|
@@ -30,9 +29,11 @@ import org.thingsboard.server.common.data.Device; |
30
|
29
|
import org.thingsboard.server.common.data.DeviceProfile;
|
31
|
30
|
import org.thingsboard.server.common.data.DeviceProfileType;
|
32
|
31
|
import org.thingsboard.server.common.data.audit.ActionType;
|
|
32
|
+import org.thingsboard.server.common.data.device.data.ProvisionDeviceConfiguration;
|
33
|
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
|
36
|
import org.thingsboard.server.common.data.id.TenantId;
|
35
|
|
-import org.thingsboard.server.common.data.id.UserId;
|
36
|
37
|
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
|
37
|
38
|
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
|
38
|
39
|
import org.thingsboard.server.common.data.kv.StringDataEntry;
|
...
|
...
|
@@ -45,6 +46,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
45
|
46
|
import org.thingsboard.server.dao.attributes.AttributesService;
|
46
|
47
|
import org.thingsboard.server.dao.audit.AuditLogService;
|
47
|
48
|
import org.thingsboard.server.dao.device.DeviceCredentialsService;
|
|
49
|
+import org.thingsboard.server.dao.device.DeviceDao;
|
48
|
50
|
import org.thingsboard.server.dao.device.DeviceProfileDao;
|
49
|
51
|
import org.thingsboard.server.dao.device.DeviceProvisionService;
|
50
|
52
|
import org.thingsboard.server.dao.device.DeviceService;
|
...
|
...
|
@@ -65,8 +67,6 @@ import java.util.List; |
65
|
67
|
import java.util.Optional;
|
66
|
68
|
import java.util.concurrent.locks.ReentrantLock;
|
67
|
69
|
|
68
|
|
-import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
|
69
|
|
-
|
70
|
70
|
|
71
|
71
|
@Service
|
72
|
72
|
@Slf4j
|
...
|
...
|
@@ -77,11 +77,12 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { |
77
|
77
|
private static final String DEVICE_PROVISION_STATE = "provisionState";
|
78
|
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
|
80
|
private final ReentrantLock deviceCreationLock = new ReentrantLock();
|
83
|
81
|
|
84
|
82
|
@Autowired
|
|
83
|
+ DeviceDao deviceDao;
|
|
84
|
+
|
|
85
|
+ @Autowired
|
85
|
86
|
DeviceProfileDao deviceProfileDao;
|
86
|
87
|
|
87
|
88
|
@Autowired
|
...
|
...
|
@@ -105,39 +106,52 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { |
105
|
106
|
|
106
|
107
|
@Override
|
107
|
108
|
public ListenableFuture<ProvisionResponse> provisionDevice(ProvisionRequest provisionRequest) {
|
108
|
|
- DeviceProfile targetProfile = deviceProfileDao.findProfileByTenantIdAndProfileDataProvisionConfigurationPair(
|
|
109
|
+ Device targetDevice = deviceDao.findDeviceByTenantIdAndDeviceDataProvisionConfigurationPair(
|
109
|
110
|
TenantId.SYS_TENANT_ID,
|
110
|
111
|
provisionRequest.getCredentials().getProvisionDeviceKey(),
|
111
|
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
|
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
|
150
|
log.warn("[{}] Failed to find pre provisioned device!", provisionRequest.getDeviceName());
|
135
|
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
|
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
|
205
|
private ListenableFuture<ProvisionResponse> processCreateDevice(ProvisionRequest provisionRequest, DeviceProfile profile) {
|
182
|
206
|
Device device = deviceService.findDeviceByTenantIdAndName(profile.getTenantId(), provisionRequest.getDeviceName());
|
183
|
207
|
if (device == null) {
|
...
|
...
|
@@ -221,15 +245,10 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { |
221
|
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
|
248
|
private void pushProvisionEventToRuleEngine(ProvisionRequest request, Device device, String type) {
|
230
|
249
|
try {
|
231
|
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
|
252
|
sendToRuleEngine(device.getTenantId(), msg, null);
|
234
|
253
|
} catch (JsonProcessingException | IllegalArgumentException e) {
|
235
|
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
|
258
|
private void pushDeviceCreatedEventToRuleEngine(Device device) {
|
240
|
259
|
try {
|
241
|
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
|
262
|
sendToRuleEngine(device.getTenantId(), msg, null);
|
244
|
263
|
} catch (JsonProcessingException | IllegalArgumentException e) {
|
245
|
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
|
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
|
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
|
} |
...
|
...
|
|