Commit 59c55fb2c59c4005c0a6152aba3dba3b9d4e9854
1 parent
b52d2aae
For devices from edge new id generated every time
Showing
8 changed files
with
150 additions
and
54 deletions
@@ -17,6 +17,7 @@ package org.thingsboard.server.service.edge.rpc; | @@ -17,6 +17,7 @@ package org.thingsboard.server.service.edge.rpc; | ||
17 | 17 | ||
18 | import com.datastax.driver.core.utils.UUIDs; | 18 | import com.datastax.driver.core.utils.UUIDs; |
19 | import com.fasterxml.jackson.databind.ObjectMapper; | 19 | import com.fasterxml.jackson.databind.ObjectMapper; |
20 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
20 | import com.google.common.util.concurrent.FutureCallback; | 21 | import com.google.common.util.concurrent.FutureCallback; |
21 | import com.google.common.util.concurrent.Futures; | 22 | import com.google.common.util.concurrent.Futures; |
22 | import com.google.common.util.concurrent.ListenableFuture; | 23 | import com.google.common.util.concurrent.ListenableFuture; |
@@ -335,8 +336,8 @@ public final class EdgeGrpcSession implements Closeable { | @@ -335,8 +336,8 @@ public final class EdgeGrpcSession implements Closeable { | ||
335 | case CREDENTIALS_REQUEST: | 336 | case CREDENTIALS_REQUEST: |
336 | downlinkMsg = processCredentialsRequestMessage(edgeEvent); | 337 | downlinkMsg = processCredentialsRequestMessage(edgeEvent); |
337 | break; | 338 | break; |
338 | - case ENTITY_EXISTS_REQUEST: | ||
339 | - downlinkMsg = processEntityExistsRequestMessage(edgeEvent); | 339 | + case ENTITY_MERGE_REQUEST: |
340 | + downlinkMsg = processEntityMergeRequestMessage(edgeEvent); | ||
340 | break; | 341 | break; |
341 | case RPC_CALL: | 342 | case RPC_CALL: |
342 | downlinkMsg = processRpcCallMsg(edgeEvent); | 343 | downlinkMsg = processRpcCallMsg(edgeEvent); |
@@ -352,13 +353,18 @@ public final class EdgeGrpcSession implements Closeable { | @@ -352,13 +353,18 @@ public final class EdgeGrpcSession implements Closeable { | ||
352 | return result; | 353 | return result; |
353 | } | 354 | } |
354 | 355 | ||
355 | - private DownlinkMsg processEntityExistsRequestMessage(EdgeEvent edgeEvent) { | 356 | + private DownlinkMsg processEntityMergeRequestMessage(EdgeEvent edgeEvent) { |
356 | DownlinkMsg downlinkMsg = null; | 357 | DownlinkMsg downlinkMsg = null; |
357 | if (EdgeEventType.DEVICE.equals(edgeEvent.getType())) { | 358 | if (EdgeEventType.DEVICE.equals(edgeEvent.getType())) { |
358 | DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); | 359 | DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); |
359 | Device device = ctx.getDeviceService().findDeviceById(edge.getTenantId(), deviceId); | 360 | Device device = ctx.getDeviceService().findDeviceById(edge.getTenantId(), deviceId); |
360 | CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device); | 361 | CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device); |
361 | - DeviceUpdateMsg d = ctx.getDeviceMsgConstructor().constructDeviceUpdatedMsg(UpdateMsgType.DEVICE_CONFLICT_RPC_MESSAGE, device, customerId); | 362 | + String conflictName = null; |
363 | + if(edgeEvent.getBody() != null) { | ||
364 | + conflictName = edgeEvent.getBody().get("conflictName").asText(); | ||
365 | + } | ||
366 | + DeviceUpdateMsg d = ctx.getDeviceMsgConstructor() | ||
367 | + .constructDeviceUpdatedMsg(UpdateMsgType.ENTITY_MERGE_RPC_MESSAGE, device, customerId, conflictName); | ||
362 | downlinkMsg = DownlinkMsg.newBuilder() | 368 | downlinkMsg = DownlinkMsg.newBuilder() |
363 | .addAllDeviceUpdateMsg(Collections.singletonList(d)) | 369 | .addAllDeviceUpdateMsg(Collections.singletonList(d)) |
364 | .build(); | 370 | .build(); |
@@ -497,7 +503,7 @@ public final class EdgeGrpcSession implements Closeable { | @@ -497,7 +503,7 @@ public final class EdgeGrpcSession implements Closeable { | ||
497 | if (device != null) { | 503 | if (device != null) { |
498 | CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device); | 504 | CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device); |
499 | DeviceUpdateMsg deviceUpdateMsg = | 505 | DeviceUpdateMsg deviceUpdateMsg = |
500 | - ctx.getDeviceMsgConstructor().constructDeviceUpdatedMsg(msgType, device, customerId); | 506 | + ctx.getDeviceMsgConstructor().constructDeviceUpdatedMsg(msgType, device, customerId, null); |
501 | downlinkMsg = DownlinkMsg.newBuilder() | 507 | downlinkMsg = DownlinkMsg.newBuilder() |
502 | .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg)) | 508 | .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg)) |
503 | .build(); | 509 | .build(); |
@@ -38,7 +38,7 @@ public class DeviceMsgConstructor { | @@ -38,7 +38,7 @@ public class DeviceMsgConstructor { | ||
38 | 38 | ||
39 | protected static final ObjectMapper mapper = new ObjectMapper(); | 39 | protected static final ObjectMapper mapper = new ObjectMapper(); |
40 | 40 | ||
41 | - public DeviceUpdateMsg constructDeviceUpdatedMsg(UpdateMsgType msgType, Device device, CustomerId customerId) { | 41 | + public DeviceUpdateMsg constructDeviceUpdatedMsg(UpdateMsgType msgType, Device device, CustomerId customerId, String conflictName) { |
42 | DeviceUpdateMsg.Builder builder = DeviceUpdateMsg.newBuilder() | 42 | DeviceUpdateMsg.Builder builder = DeviceUpdateMsg.newBuilder() |
43 | .setMsgType(msgType) | 43 | .setMsgType(msgType) |
44 | .setIdMSB(device.getId().getId().getMostSignificantBits()) | 44 | .setIdMSB(device.getId().getId().getMostSignificantBits()) |
@@ -55,6 +55,9 @@ public class DeviceMsgConstructor { | @@ -55,6 +55,9 @@ public class DeviceMsgConstructor { | ||
55 | if (device.getAdditionalInfo() != null) { | 55 | if (device.getAdditionalInfo() != null) { |
56 | builder.setAdditionalInfo(JacksonUtil.toString(device.getAdditionalInfo())); | 56 | builder.setAdditionalInfo(JacksonUtil.toString(device.getAdditionalInfo())); |
57 | } | 57 | } |
58 | + if (conflictName != null) { | ||
59 | + builder.setConflictName(conflictName); | ||
60 | + } | ||
58 | return builder.build(); | 61 | return builder.build(); |
59 | } | 62 | } |
60 | 63 |
@@ -37,6 +37,7 @@ import org.thingsboard.server.dao.dashboard.DashboardService; | @@ -37,6 +37,7 @@ import org.thingsboard.server.dao.dashboard.DashboardService; | ||
37 | import org.thingsboard.server.dao.device.DeviceCredentialsService; | 37 | import org.thingsboard.server.dao.device.DeviceCredentialsService; |
38 | import org.thingsboard.server.dao.device.DeviceService; | 38 | import org.thingsboard.server.dao.device.DeviceService; |
39 | import org.thingsboard.server.dao.edge.EdgeEventService; | 39 | import org.thingsboard.server.dao.edge.EdgeEventService; |
40 | +import org.thingsboard.server.dao.edge.EdgeService; | ||
40 | import org.thingsboard.server.dao.entityview.EntityViewService; | 41 | import org.thingsboard.server.dao.entityview.EntityViewService; |
41 | import org.thingsboard.server.dao.relation.RelationService; | 42 | import org.thingsboard.server.dao.relation.RelationService; |
42 | import org.thingsboard.server.dao.user.UserService; | 43 | import org.thingsboard.server.dao.user.UserService; |
@@ -65,6 +66,9 @@ public abstract class BaseProcessor { | @@ -65,6 +66,9 @@ public abstract class BaseProcessor { | ||
65 | protected EntityViewService entityViewService; | 66 | protected EntityViewService entityViewService; |
66 | 67 | ||
67 | @Autowired | 68 | @Autowired |
69 | + protected EdgeService edgeService; | ||
70 | + | ||
71 | + @Autowired | ||
68 | protected CustomerService customerService; | 72 | protected CustomerService customerService; |
69 | 73 | ||
70 | @Autowired | 74 | @Autowired |
@@ -17,12 +17,15 @@ package org.thingsboard.server.service.edge.rpc.processor; | @@ -17,12 +17,15 @@ package org.thingsboard.server.service.edge.rpc.processor; | ||
17 | 17 | ||
18 | import com.fasterxml.jackson.core.JsonProcessingException; | 18 | import com.fasterxml.jackson.core.JsonProcessingException; |
19 | import com.fasterxml.jackson.databind.node.ObjectNode; | 19 | import com.fasterxml.jackson.databind.node.ObjectNode; |
20 | +import com.google.common.util.concurrent.FutureCallback; | ||
20 | import com.google.common.util.concurrent.Futures; | 21 | import com.google.common.util.concurrent.Futures; |
21 | import com.google.common.util.concurrent.ListenableFuture; | 22 | import com.google.common.util.concurrent.ListenableFuture; |
22 | import com.google.common.util.concurrent.SettableFuture; | 23 | import com.google.common.util.concurrent.SettableFuture; |
23 | import lombok.extern.slf4j.Slf4j; | 24 | import lombok.extern.slf4j.Slf4j; |
24 | import org.apache.commons.lang.RandomStringUtils; | 25 | import org.apache.commons.lang.RandomStringUtils; |
25 | import org.apache.commons.lang.StringUtils; | 26 | import org.apache.commons.lang.StringUtils; |
27 | +import org.checkerframework.checker.nullness.qual.Nullable; | ||
28 | +import org.springframework.security.core.parameters.P; | ||
26 | import org.springframework.stereotype.Component; | 29 | import org.springframework.stereotype.Component; |
27 | import org.thingsboard.rule.engine.api.RpcError; | 30 | import org.thingsboard.rule.engine.api.RpcError; |
28 | import org.thingsboard.server.common.data.DataConstants; | 31 | import org.thingsboard.server.common.data.DataConstants; |
@@ -52,6 +55,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | @@ -52,6 +55,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | ||
52 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | 55 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; |
53 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; | 56 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; |
54 | 57 | ||
58 | +import java.util.List; | ||
55 | import java.util.UUID; | 59 | import java.util.UUID; |
56 | import java.util.concurrent.locks.ReentrantLock; | 60 | import java.util.concurrent.locks.ReentrantLock; |
57 | 61 | ||
@@ -64,36 +68,62 @@ public class DeviceProcessor extends BaseProcessor { | @@ -64,36 +68,62 @@ public class DeviceProcessor extends BaseProcessor { | ||
64 | 68 | ||
65 | public ListenableFuture<Void> onDeviceUpdate(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { | 69 | public ListenableFuture<Void> onDeviceUpdate(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { |
66 | log.trace("[{}] onDeviceUpdate [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); | 70 | log.trace("[{}] onDeviceUpdate [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); |
67 | - DeviceId edgeDeviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); | ||
68 | switch (deviceUpdateMsg.getMsgType()) { | 71 | switch (deviceUpdateMsg.getMsgType()) { |
69 | case ENTITY_CREATED_RPC_MESSAGE: | 72 | case ENTITY_CREATED_RPC_MESSAGE: |
70 | String deviceName = deviceUpdateMsg.getName(); | 73 | String deviceName = deviceUpdateMsg.getName(); |
71 | Device device = deviceService.findDeviceByTenantIdAndName(tenantId, deviceName); | 74 | Device device = deviceService.findDeviceByTenantIdAndName(tenantId, deviceName); |
72 | if (device != null) { | 75 | if (device != null) { |
73 | - log.info("[{}] Device with name '{}' already exists on the cloud. Updating id of device entity on the edge", tenantId, deviceName); | ||
74 | - if (!device.getId().equals(edgeDeviceId)) { | ||
75 | - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_EXISTS_REQUEST, device.getId(), null); | ||
76 | - } | 76 | + ListenableFuture<List<EdgeId>> future = edgeService.findRelatedEdgeIdsByEntityId(tenantId, device.getId()); |
77 | + SettableFuture<Void> futureToSet = SettableFuture.create(); | ||
78 | + Futures.addCallback(future, new FutureCallback<List<EdgeId>>() { | ||
79 | + @Override | ||
80 | + public void onSuccess(@Nullable List<EdgeId> edgeIds) { | ||
81 | + boolean update = false; | ||
82 | + if (edgeIds != null && !edgeIds.isEmpty()) { | ||
83 | + if (edgeIds.contains(edge.getId())) { | ||
84 | + update = true; | ||
85 | + } | ||
86 | + } | ||
87 | + Device device; | ||
88 | + if (update) { | ||
89 | + log.info("[{}] Device with name '{}' already exists on the cloud, and related to this edge [{}]. " + | ||
90 | + "deviceUpdateMsg [{}], Updating device", tenantId, deviceName, edge.getId(), deviceUpdateMsg); | ||
91 | + updateDevice(tenantId, edge, deviceUpdateMsg); | ||
92 | + } else { | ||
93 | + log.info("[{}] Device with name '{}' already exists on the cloud, but not related to this edge [{}]. deviceUpdateMsg [{}]." + | ||
94 | + "Creating a new device with random prefix and relate to this edge", tenantId, deviceName, edge.getId(), deviceUpdateMsg); | ||
95 | + String newDeviceName = deviceUpdateMsg.getName() + "_" + RandomStringUtils.randomAlphabetic(15); | ||
96 | + device = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName); | ||
97 | + ObjectNode body = mapper.createObjectNode(); | ||
98 | + body.put("conflictName", deviceName); | ||
99 | + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, device.getId(), body); | ||
100 | + deviceService.assignDeviceToEdge(edge.getTenantId(), device.getId(), edge.getId()); | ||
101 | + } | ||
102 | + futureToSet.set(null); | ||
103 | + } | ||
104 | + | ||
105 | + @Override | ||
106 | + public void onFailure(Throwable t) { | ||
107 | + log.error("[{}] Failed to get related edge ids by device id [{}], edge [{}]", tenantId, deviceUpdateMsg, edge.getId(), t); | ||
108 | + futureToSet.setException(t); | ||
109 | + } | ||
110 | + }, dbCallbackExecutorService); | ||
111 | + return futureToSet; | ||
77 | } else { | 112 | } else { |
78 | - Device deviceById = deviceService.findDeviceById(edge.getTenantId(), edgeDeviceId); | ||
79 | - if (deviceById != null) { | ||
80 | - log.info("[{}] Device ID [{}] already used by other device on the cloud. Creating new device and replacing device entity on the edge", tenantId, edgeDeviceId.getId()); | ||
81 | - device = createDevice(tenantId, edge, deviceUpdateMsg); | ||
82 | - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_EXISTS_REQUEST, device.getId(), null); | ||
83 | - } else { | ||
84 | - device = createDevice(tenantId, edge, deviceUpdateMsg); | ||
85 | - } | 113 | + log.info("[{}] Creating new device and replacing device entity on the edge [{}]", tenantId, deviceUpdateMsg); |
114 | + device = createDevice(tenantId, edge, deviceUpdateMsg, deviceUpdateMsg.getName()); | ||
115 | + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, device.getId(), null); | ||
116 | + deviceService.assignDeviceToEdge(edge.getTenantId(), device.getId(), edge.getId()); | ||
86 | } | 117 | } |
87 | - // TODO: voba - assign device only in case device is not assigned yet. Missing functionality to check this relation prior assignment | ||
88 | - deviceService.assignDeviceToEdge(edge.getTenantId(), device.getId(), edge.getId()); | ||
89 | break; | 118 | break; |
90 | case ENTITY_UPDATED_RPC_MESSAGE: | 119 | case ENTITY_UPDATED_RPC_MESSAGE: |
91 | updateDevice(tenantId, edge, deviceUpdateMsg); | 120 | updateDevice(tenantId, edge, deviceUpdateMsg); |
92 | break; | 121 | break; |
93 | case ENTITY_DELETED_RPC_MESSAGE: | 122 | case ENTITY_DELETED_RPC_MESSAGE: |
94 | - Device deviceToDelete = deviceService.findDeviceById(tenantId, edgeDeviceId); | 123 | + DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); |
124 | + Device deviceToDelete = deviceService.findDeviceById(tenantId, deviceId); | ||
95 | if (deviceToDelete != null) { | 125 | if (deviceToDelete != null) { |
96 | - deviceService.unassignDeviceFromEdge(tenantId, edgeDeviceId, edge.getId()); | 126 | + deviceService.unassignDeviceFromEdge(tenantId, deviceId, edge.getId()); |
97 | } | 127 | } |
98 | break; | 128 | break; |
99 | case UNRECOGNIZED: | 129 | case UNRECOGNIZED: |
@@ -103,7 +133,6 @@ public class DeviceProcessor extends BaseProcessor { | @@ -103,7 +133,6 @@ public class DeviceProcessor extends BaseProcessor { | ||
103 | return Futures.immediateFuture(null); | 133 | return Futures.immediateFuture(null); |
104 | } | 134 | } |
105 | 135 | ||
106 | - | ||
107 | public ListenableFuture<Void> onDeviceCredentialsUpdate(TenantId tenantId, DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg) { | 136 | public ListenableFuture<Void> onDeviceCredentialsUpdate(TenantId tenantId, DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg) { |
108 | log.debug("Executing onDeviceCredentialsUpdate, deviceCredentialsUpdateMsg [{}]", deviceCredentialsUpdateMsg); | 137 | log.debug("Executing onDeviceCredentialsUpdate, deviceCredentialsUpdateMsg [{}]", deviceCredentialsUpdateMsg); |
109 | DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsUpdateMsg.getDeviceIdMSB(), deviceCredentialsUpdateMsg.getDeviceIdLSB())); | 138 | DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsUpdateMsg.getDeviceIdMSB(), deviceCredentialsUpdateMsg.getDeviceIdLSB())); |
@@ -131,36 +160,34 @@ public class DeviceProcessor extends BaseProcessor { | @@ -131,36 +160,34 @@ public class DeviceProcessor extends BaseProcessor { | ||
131 | private void updateDevice(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { | 160 | private void updateDevice(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { |
132 | DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); | 161 | DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); |
133 | Device device = deviceService.findDeviceById(tenantId, deviceId); | 162 | Device device = deviceService.findDeviceById(tenantId, deviceId); |
134 | - device.setName(deviceUpdateMsg.getName()); | ||
135 | - device.setType(deviceUpdateMsg.getType()); | ||
136 | - device.setLabel(deviceUpdateMsg.getLabel()); | ||
137 | - device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo())); | ||
138 | - deviceService.saveDevice(device); | ||
139 | - | ||
140 | - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null); | 163 | + if (device != null) { |
164 | + device.setName(deviceUpdateMsg.getName()); | ||
165 | + device.setType(deviceUpdateMsg.getType()); | ||
166 | + device.setLabel(deviceUpdateMsg.getLabel()); | ||
167 | + device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo())); | ||
168 | + deviceService.saveDevice(device); | ||
169 | + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null); | ||
170 | + } else { | ||
171 | + log.warn("[{}] can't find device [{}], edge [{}]", tenantId, deviceUpdateMsg, edge.getId()); | ||
172 | + } | ||
141 | } | 173 | } |
142 | 174 | ||
143 | - private Device createDevice(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { | 175 | + private Device createDevice(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg, String deviceName) { |
144 | Device device; | 176 | Device device; |
145 | try { | 177 | try { |
146 | deviceCreationLock.lock(); | 178 | deviceCreationLock.lock(); |
147 | log.debug("[{}] Creating device entity [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); | 179 | log.debug("[{}] Creating device entity [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); |
148 | - DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); | ||
149 | device = new Device(); | 180 | device = new Device(); |
150 | device.setTenantId(edge.getTenantId()); | 181 | device.setTenantId(edge.getTenantId()); |
151 | device.setCustomerId(edge.getCustomerId()); | 182 | device.setCustomerId(edge.getCustomerId()); |
152 | - device.setId(deviceId); | ||
153 | - device.setName(deviceUpdateMsg.getName()); | 183 | + device.setName(deviceName); |
154 | device.setType(deviceUpdateMsg.getType()); | 184 | device.setType(deviceUpdateMsg.getType()); |
155 | device.setLabel(deviceUpdateMsg.getLabel()); | 185 | device.setLabel(deviceUpdateMsg.getLabel()); |
156 | device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo())); | 186 | device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo())); |
157 | device = deviceService.saveDevice(device); | 187 | device = deviceService.saveDevice(device); |
158 | - createDeviceCredentials(device); | ||
159 | createRelationFromEdge(tenantId, edge.getId(), device.getId()); | 188 | createRelationFromEdge(tenantId, edge.getId(), device.getId()); |
160 | deviceStateService.onDeviceAdded(device); | 189 | deviceStateService.onDeviceAdded(device); |
161 | pushDeviceCreatedEventToRuleEngine(tenantId, edge, device); | 190 | pushDeviceCreatedEventToRuleEngine(tenantId, edge, device); |
162 | - | ||
163 | - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null); | ||
164 | } finally { | 191 | } finally { |
165 | deviceCreationLock.unlock(); | 192 | deviceCreationLock.unlock(); |
166 | } | 193 | } |
@@ -176,14 +203,6 @@ public class DeviceProcessor extends BaseProcessor { | @@ -176,14 +203,6 @@ public class DeviceProcessor extends BaseProcessor { | ||
176 | relationService.saveRelation(tenantId, relation); | 203 | relationService.saveRelation(tenantId, relation); |
177 | } | 204 | } |
178 | 205 | ||
179 | - private void createDeviceCredentials(Device device) { | ||
180 | - DeviceCredentials deviceCredentials = new DeviceCredentials(); | ||
181 | - deviceCredentials.setDeviceId(device.getId()); | ||
182 | - deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); | ||
183 | - deviceCredentials.setCredentialsId(RandomStringUtils.randomAlphanumeric(20)); | ||
184 | - deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials); | ||
185 | - } | ||
186 | - | ||
187 | private void pushDeviceCreatedEventToRuleEngine(TenantId tenantId, Edge edge, Device device) { | 206 | private void pushDeviceCreatedEventToRuleEngine(TenantId tenantId, Edge edge, Device device) { |
188 | try { | 207 | try { |
189 | DeviceId deviceId = device.getId(); | 208 | DeviceId deviceId = device.getId(); |
@@ -26,6 +26,7 @@ import com.google.protobuf.AbstractMessage; | @@ -26,6 +26,7 @@ import com.google.protobuf.AbstractMessage; | ||
26 | import com.google.protobuf.InvalidProtocolBufferException; | 26 | import com.google.protobuf.InvalidProtocolBufferException; |
27 | import com.google.protobuf.MessageLite; | 27 | import com.google.protobuf.MessageLite; |
28 | import lombok.extern.slf4j.Slf4j; | 28 | import lombok.extern.slf4j.Slf4j; |
29 | +import org.apache.commons.lang.RandomStringUtils; | ||
29 | import org.junit.After; | 30 | import org.junit.After; |
30 | import org.junit.Assert; | 31 | import org.junit.Assert; |
31 | import org.junit.Before; | 32 | import org.junit.Before; |
@@ -48,6 +49,7 @@ import org.thingsboard.server.common.data.edge.Edge; | @@ -48,6 +49,7 @@ import org.thingsboard.server.common.data.edge.Edge; | ||
48 | import org.thingsboard.server.common.data.edge.EdgeEvent; | 49 | import org.thingsboard.server.common.data.edge.EdgeEvent; |
49 | import org.thingsboard.server.common.data.edge.EdgeEventActionType; | 50 | import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
50 | import org.thingsboard.server.common.data.edge.EdgeEventType; | 51 | import org.thingsboard.server.common.data.edge.EdgeEventType; |
52 | +import org.thingsboard.server.common.data.id.DeviceId; | ||
51 | import org.thingsboard.server.common.data.id.EdgeId; | 53 | import org.thingsboard.server.common.data.id.EdgeId; |
52 | import org.thingsboard.server.common.data.id.EntityId; | 54 | import org.thingsboard.server.common.data.id.EntityId; |
53 | import org.thingsboard.server.common.data.id.EntityIdFactory; | 55 | import org.thingsboard.server.common.data.id.EntityIdFactory; |
@@ -964,6 +966,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -964,6 +966,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
964 | private void testSendMessagesToCloud() throws Exception { | 966 | private void testSendMessagesToCloud() throws Exception { |
965 | log.info("Sending messages to cloud"); | 967 | log.info("Sending messages to cloud"); |
966 | sendDevice(); | 968 | sendDevice(); |
969 | + sendDeviceWithNameThatAlreadyExistsOnCloud(); | ||
967 | sendRelationRequest(); | 970 | sendRelationRequest(); |
968 | sendAlarm(); | 971 | sendAlarm(); |
969 | sendTelemetry(); | 972 | sendTelemetry(); |
@@ -992,17 +995,66 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -992,17 +995,66 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
992 | uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); | 995 | uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); |
993 | 996 | ||
994 | edgeImitator.expectResponsesAmount(1); | 997 | edgeImitator.expectResponsesAmount(1); |
995 | - | 998 | + edgeImitator.expectMessageAmount(1); |
996 | testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); | 999 | testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); |
997 | 1000 | ||
998 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1001 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1002 | + | ||
999 | edgeImitator.waitForResponses(); | 1003 | edgeImitator.waitForResponses(); |
1004 | + edgeImitator.waitForMessages(); | ||
1005 | + | ||
1006 | + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | ||
1007 | + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); | ||
1008 | + DeviceUpdateMsg latestDeviceUpdateMsg = (DeviceUpdateMsg) latestMessage; | ||
1009 | + Assert.assertEquals("Edge Device 2", latestDeviceUpdateMsg.getName()); | ||
1010 | + | ||
1011 | + UUID newDeviceId = new UUID(latestDeviceUpdateMsg.getIdMSB(), latestDeviceUpdateMsg.getIdLSB()); | ||
1000 | 1012 | ||
1001 | - Device device = doGet("/api/device/" + uuid.toString(), Device.class); | 1013 | + Device device = doGet("/api/device/" + newDeviceId, Device.class); |
1002 | Assert.assertNotNull(device); | 1014 | Assert.assertNotNull(device); |
1003 | Assert.assertEquals("Edge Device 2", device.getName()); | 1015 | Assert.assertEquals("Edge Device 2", device.getName()); |
1004 | } | 1016 | } |
1005 | 1017 | ||
1018 | + private void sendDeviceWithNameThatAlreadyExistsOnCloud() throws Exception { | ||
1019 | + String deviceOnCloudName = RandomStringUtils.randomAlphanumeric(15); | ||
1020 | + Device deviceOnCloud = saveDevice(deviceOnCloudName); | ||
1021 | + | ||
1022 | + UUID uuid = UUIDs.timeBased(); | ||
1023 | + | ||
1024 | + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); | ||
1025 | + DeviceUpdateMsg.Builder deviceUpdateMsgBuilder = DeviceUpdateMsg.newBuilder(); | ||
1026 | + deviceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits()); | ||
1027 | + deviceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits()); | ||
1028 | + deviceUpdateMsgBuilder.setName(deviceOnCloudName); | ||
1029 | + deviceUpdateMsgBuilder.setType("test"); | ||
1030 | + deviceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE); | ||
1031 | + testAutoGeneratedCodeByProtobuf(deviceUpdateMsgBuilder); | ||
1032 | + uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); | ||
1033 | + | ||
1034 | + edgeImitator.expectResponsesAmount(1); | ||
1035 | + edgeImitator.expectMessageAmount(1); | ||
1036 | + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); | ||
1037 | + | ||
1038 | + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | ||
1039 | + | ||
1040 | + edgeImitator.waitForResponses(); | ||
1041 | + edgeImitator.waitForMessages(); | ||
1042 | + | ||
1043 | + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | ||
1044 | + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); | ||
1045 | + DeviceUpdateMsg latestDeviceUpdateMsg = (DeviceUpdateMsg) latestMessage; | ||
1046 | + Assert.assertNotEquals(deviceOnCloudName, latestDeviceUpdateMsg.getName()); | ||
1047 | + Assert.assertEquals(deviceOnCloudName, latestDeviceUpdateMsg.getConflictName()); | ||
1048 | + | ||
1049 | + UUID newDeviceId = new UUID(latestDeviceUpdateMsg.getIdMSB(), latestDeviceUpdateMsg.getIdLSB()); | ||
1050 | + | ||
1051 | + Assert.assertNotEquals(deviceOnCloud.getId().getId(), newDeviceId); | ||
1052 | + | ||
1053 | + Device device = doGet("/api/device/" + newDeviceId, Device.class); | ||
1054 | + Assert.assertNotNull(device); | ||
1055 | + Assert.assertNotEquals(deviceOnCloudName, device.getName()); | ||
1056 | + } | ||
1057 | + | ||
1006 | private void sendRelationRequest() throws Exception { | 1058 | private void sendRelationRequest() throws Exception { |
1007 | Device device = findDeviceByName("Edge Device 1"); | 1059 | Device device = findDeviceByName("Edge Device 1"); |
1008 | Asset asset = findAssetByName("Edge Asset 1"); | 1060 | Asset asset = findAssetByName("Edge Asset 1"); |
@@ -34,5 +34,5 @@ public enum EdgeEventActionType { | @@ -34,5 +34,5 @@ public enum EdgeEventActionType { | ||
34 | ASSIGNED_TO_EDGE, | 34 | ASSIGNED_TO_EDGE, |
35 | UNASSIGNED_FROM_EDGE, | 35 | UNASSIGNED_FROM_EDGE, |
36 | CREDENTIALS_REQUEST, | 36 | CREDENTIALS_REQUEST, |
37 | - ENTITY_EXISTS_REQUEST | 37 | + ENTITY_MERGE_REQUEST |
38 | } | 38 | } |
@@ -97,7 +97,7 @@ enum UpdateMsgType { | @@ -97,7 +97,7 @@ enum UpdateMsgType { | ||
97 | ENTITY_DELETED_RPC_MESSAGE = 2; | 97 | ENTITY_DELETED_RPC_MESSAGE = 2; |
98 | ALARM_ACK_RPC_MESSAGE = 3; | 98 | ALARM_ACK_RPC_MESSAGE = 3; |
99 | ALARM_CLEAR_RPC_MESSAGE = 4; | 99 | ALARM_CLEAR_RPC_MESSAGE = 4; |
100 | - DEVICE_CONFLICT_RPC_MESSAGE = 5; | 100 | + ENTITY_MERGE_RPC_MESSAGE = 5; |
101 | } | 101 | } |
102 | 102 | ||
103 | message EntityDataProto { | 103 | message EntityDataProto { |
@@ -182,6 +182,7 @@ message DeviceUpdateMsg { | @@ -182,6 +182,7 @@ message DeviceUpdateMsg { | ||
182 | string type = 7; | 182 | string type = 7; |
183 | string label = 8; | 183 | string label = 8; |
184 | string additionalInfo = 9; | 184 | string additionalInfo = 9; |
185 | + string conflictName = 10; | ||
185 | } | 186 | } |
186 | 187 | ||
187 | message DeviceCredentialsUpdateMsg { | 188 | message DeviceCredentialsUpdateMsg { |
@@ -87,6 +87,7 @@ import org.thingsboard.server.common.data.relation.EntityRelationsQuery; | @@ -87,6 +87,7 @@ import org.thingsboard.server.common.data.relation.EntityRelationsQuery; | ||
87 | import org.thingsboard.server.common.data.relation.RelationTypeGroup; | 87 | import org.thingsboard.server.common.data.relation.RelationTypeGroup; |
88 | import org.thingsboard.server.common.data.rule.RuleChain; | 88 | import org.thingsboard.server.common.data.rule.RuleChain; |
89 | import org.thingsboard.server.common.data.rule.RuleChainMetaData; | 89 | import org.thingsboard.server.common.data.rule.RuleChainMetaData; |
90 | +import org.thingsboard.server.common.data.rule.RuleChainType; | ||
90 | import org.thingsboard.server.common.data.security.DeviceCredentials; | 91 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
91 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; | 92 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; |
92 | import org.thingsboard.server.common.data.security.model.SecuritySettings; | 93 | import org.thingsboard.server.common.data.security.model.SecuritySettings; |
@@ -97,6 +98,7 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; | @@ -97,6 +98,7 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; | ||
97 | import java.io.Closeable; | 98 | import java.io.Closeable; |
98 | import java.io.IOException; | 99 | import java.io.IOException; |
99 | import java.net.URI; | 100 | import java.net.URI; |
101 | +import java.util.Arrays; | ||
100 | import java.util.Collections; | 102 | import java.util.Collections; |
101 | import java.util.HashMap; | 103 | import java.util.HashMap; |
102 | import java.util.List; | 104 | import java.util.List; |
@@ -626,22 +628,31 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { | @@ -626,22 +628,31 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { | ||
626 | } | 628 | } |
627 | 629 | ||
628 | public List<ComponentDescriptor> getComponentDescriptorsByType(ComponentType componentType) { | 630 | public List<ComponentDescriptor> getComponentDescriptorsByType(ComponentType componentType) { |
631 | + return getComponentDescriptorsByType(componentType, RuleChainType.CORE); | ||
632 | + } | ||
633 | + | ||
634 | + public List<ComponentDescriptor> getComponentDescriptorsByType(ComponentType componentType, RuleChainType ruleChainType) { | ||
629 | return restTemplate.exchange( | 635 | return restTemplate.exchange( |
630 | - baseURL + "/api/components?componentType={componentType}", | 636 | + baseURL + "/api/components/" + componentType.name() + "/?ruleChainType={ruleChainType}", |
631 | HttpMethod.GET, HttpEntity.EMPTY, | 637 | HttpMethod.GET, HttpEntity.EMPTY, |
632 | new ParameterizedTypeReference<List<ComponentDescriptor>>() { | 638 | new ParameterizedTypeReference<List<ComponentDescriptor>>() { |
633 | }, | 639 | }, |
634 | - componentType).getBody(); | 640 | + ruleChainType).getBody(); |
635 | } | 641 | } |
636 | 642 | ||
637 | public List<ComponentDescriptor> getComponentDescriptorsByTypes(List<ComponentType> componentTypes) { | 643 | public List<ComponentDescriptor> getComponentDescriptorsByTypes(List<ComponentType> componentTypes) { |
644 | + return getComponentDescriptorsByTypes(componentTypes, RuleChainType.CORE); | ||
645 | + } | ||
646 | + | ||
647 | + public List<ComponentDescriptor> getComponentDescriptorsByTypes(List<ComponentType> componentTypes, RuleChainType ruleChainType) { | ||
638 | return restTemplate.exchange( | 648 | return restTemplate.exchange( |
639 | - baseURL + "/api/components?componentTypes={componentTypes}", | 649 | + baseURL + "/api/components?componentTypes={componentTypes}&ruleChainType={ruleChainType}", |
640 | HttpMethod.GET, | 650 | HttpMethod.GET, |
641 | HttpEntity.EMPTY, | 651 | HttpEntity.EMPTY, |
642 | new ParameterizedTypeReference<List<ComponentDescriptor>>() { | 652 | new ParameterizedTypeReference<List<ComponentDescriptor>>() { |
643 | }, | 653 | }, |
644 | - listEnumToString(componentTypes)) | 654 | + listEnumToString(componentTypes), |
655 | + ruleChainType) | ||
645 | .getBody(); | 656 | .getBody(); |
646 | } | 657 | } |
647 | 658 |