Commit 59c55fb2c59c4005c0a6152aba3dba3b9d4e9854

Authored by Volodymyr Babak
1 parent b52d2aae

For devices from edge new id generated every time

... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.service.edge.rpc;
17 17
18 18 import com.datastax.driver.core.utils.UUIDs;
19 19 import com.fasterxml.jackson.databind.ObjectMapper;
  20 +import com.fasterxml.jackson.databind.node.ObjectNode;
20 21 import com.google.common.util.concurrent.FutureCallback;
21 22 import com.google.common.util.concurrent.Futures;
22 23 import com.google.common.util.concurrent.ListenableFuture;
... ... @@ -335,8 +336,8 @@ public final class EdgeGrpcSession implements Closeable {
335 336 case CREDENTIALS_REQUEST:
336 337 downlinkMsg = processCredentialsRequestMessage(edgeEvent);
337 338 break;
338   - case ENTITY_EXISTS_REQUEST:
339   - downlinkMsg = processEntityExistsRequestMessage(edgeEvent);
  339 + case ENTITY_MERGE_REQUEST:
  340 + downlinkMsg = processEntityMergeRequestMessage(edgeEvent);
340 341 break;
341 342 case RPC_CALL:
342 343 downlinkMsg = processRpcCallMsg(edgeEvent);
... ... @@ -352,13 +353,18 @@ public final class EdgeGrpcSession implements Closeable {
352 353 return result;
353 354 }
354 355
355   - private DownlinkMsg processEntityExistsRequestMessage(EdgeEvent edgeEvent) {
  356 + private DownlinkMsg processEntityMergeRequestMessage(EdgeEvent edgeEvent) {
356 357 DownlinkMsg downlinkMsg = null;
357 358 if (EdgeEventType.DEVICE.equals(edgeEvent.getType())) {
358 359 DeviceId deviceId = new DeviceId(edgeEvent.getEntityId());
359 360 Device device = ctx.getDeviceService().findDeviceById(edge.getTenantId(), deviceId);
360 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 368 downlinkMsg = DownlinkMsg.newBuilder()
363 369 .addAllDeviceUpdateMsg(Collections.singletonList(d))
364 370 .build();
... ... @@ -497,7 +503,7 @@ public final class EdgeGrpcSession implements Closeable {
497 503 if (device != null) {
498 504 CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device);
499 505 DeviceUpdateMsg deviceUpdateMsg =
500   - ctx.getDeviceMsgConstructor().constructDeviceUpdatedMsg(msgType, device, customerId);
  506 + ctx.getDeviceMsgConstructor().constructDeviceUpdatedMsg(msgType, device, customerId, null);
501 507 downlinkMsg = DownlinkMsg.newBuilder()
502 508 .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg))
503 509 .build();
... ...
... ... @@ -38,7 +38,7 @@ public class DeviceMsgConstructor {
38 38
39 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 42 DeviceUpdateMsg.Builder builder = DeviceUpdateMsg.newBuilder()
43 43 .setMsgType(msgType)
44 44 .setIdMSB(device.getId().getId().getMostSignificantBits())
... ... @@ -55,6 +55,9 @@ public class DeviceMsgConstructor {
55 55 if (device.getAdditionalInfo() != null) {
56 56 builder.setAdditionalInfo(JacksonUtil.toString(device.getAdditionalInfo()));
57 57 }
  58 + if (conflictName != null) {
  59 + builder.setConflictName(conflictName);
  60 + }
58 61 return builder.build();
59 62 }
60 63
... ...
... ... @@ -37,6 +37,7 @@ import org.thingsboard.server.dao.dashboard.DashboardService;
37 37 import org.thingsboard.server.dao.device.DeviceCredentialsService;
38 38 import org.thingsboard.server.dao.device.DeviceService;
39 39 import org.thingsboard.server.dao.edge.EdgeEventService;
  40 +import org.thingsboard.server.dao.edge.EdgeService;
40 41 import org.thingsboard.server.dao.entityview.EntityViewService;
41 42 import org.thingsboard.server.dao.relation.RelationService;
42 43 import org.thingsboard.server.dao.user.UserService;
... ... @@ -65,6 +66,9 @@ public abstract class BaseProcessor {
65 66 protected EntityViewService entityViewService;
66 67
67 68 @Autowired
  69 + protected EdgeService edgeService;
  70 +
  71 + @Autowired
68 72 protected CustomerService customerService;
69 73
70 74 @Autowired
... ...
... ... @@ -17,12 +17,15 @@ package org.thingsboard.server.service.edge.rpc.processor;
17 17
18 18 import com.fasterxml.jackson.core.JsonProcessingException;
19 19 import com.fasterxml.jackson.databind.node.ObjectNode;
  20 +import com.google.common.util.concurrent.FutureCallback;
20 21 import com.google.common.util.concurrent.Futures;
21 22 import com.google.common.util.concurrent.ListenableFuture;
22 23 import com.google.common.util.concurrent.SettableFuture;
23 24 import lombok.extern.slf4j.Slf4j;
24 25 import org.apache.commons.lang.RandomStringUtils;
25 26 import org.apache.commons.lang.StringUtils;
  27 +import org.checkerframework.checker.nullness.qual.Nullable;
  28 +import org.springframework.security.core.parameters.P;
26 29 import org.springframework.stereotype.Component;
27 30 import org.thingsboard.rule.engine.api.RpcError;
28 31 import org.thingsboard.server.common.data.DataConstants;
... ... @@ -52,6 +55,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent;
52 55 import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
53 56 import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg;
54 57
  58 +import java.util.List;
55 59 import java.util.UUID;
56 60 import java.util.concurrent.locks.ReentrantLock;
57 61
... ... @@ -64,36 +68,62 @@ public class DeviceProcessor extends BaseProcessor {
64 68
65 69 public ListenableFuture<Void> onDeviceUpdate(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) {
66 70 log.trace("[{}] onDeviceUpdate [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName());
67   - DeviceId edgeDeviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()));
68 71 switch (deviceUpdateMsg.getMsgType()) {
69 72 case ENTITY_CREATED_RPC_MESSAGE:
70 73 String deviceName = deviceUpdateMsg.getName();
71 74 Device device = deviceService.findDeviceByTenantIdAndName(tenantId, deviceName);
72 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 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 118 break;
90 119 case ENTITY_UPDATED_RPC_MESSAGE:
91 120 updateDevice(tenantId, edge, deviceUpdateMsg);
92 121 break;
93 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 125 if (deviceToDelete != null) {
96   - deviceService.unassignDeviceFromEdge(tenantId, edgeDeviceId, edge.getId());
  126 + deviceService.unassignDeviceFromEdge(tenantId, deviceId, edge.getId());
97 127 }
98 128 break;
99 129 case UNRECOGNIZED:
... ... @@ -103,7 +133,6 @@ public class DeviceProcessor extends BaseProcessor {
103 133 return Futures.immediateFuture(null);
104 134 }
105 135
106   -
107 136 public ListenableFuture<Void> onDeviceCredentialsUpdate(TenantId tenantId, DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg) {
108 137 log.debug("Executing onDeviceCredentialsUpdate, deviceCredentialsUpdateMsg [{}]", deviceCredentialsUpdateMsg);
109 138 DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsUpdateMsg.getDeviceIdMSB(), deviceCredentialsUpdateMsg.getDeviceIdLSB()));
... ... @@ -131,36 +160,34 @@ public class DeviceProcessor extends BaseProcessor {
131 160 private void updateDevice(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) {
132 161 DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()));
133 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 176 Device device;
145 177 try {
146 178 deviceCreationLock.lock();
147 179 log.debug("[{}] Creating device entity [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName());
148   - DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()));
149 180 device = new Device();
150 181 device.setTenantId(edge.getTenantId());
151 182 device.setCustomerId(edge.getCustomerId());
152   - device.setId(deviceId);
153   - device.setName(deviceUpdateMsg.getName());
  183 + device.setName(deviceName);
154 184 device.setType(deviceUpdateMsg.getType());
155 185 device.setLabel(deviceUpdateMsg.getLabel());
156 186 device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo()));
157 187 device = deviceService.saveDevice(device);
158   - createDeviceCredentials(device);
159 188 createRelationFromEdge(tenantId, edge.getId(), device.getId());
160 189 deviceStateService.onDeviceAdded(device);
161 190 pushDeviceCreatedEventToRuleEngine(tenantId, edge, device);
162   -
163   - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null);
164 191 } finally {
165 192 deviceCreationLock.unlock();
166 193 }
... ... @@ -176,14 +203,6 @@ public class DeviceProcessor extends BaseProcessor {
176 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 206 private void pushDeviceCreatedEventToRuleEngine(TenantId tenantId, Edge edge, Device device) {
188 207 try {
189 208 DeviceId deviceId = device.getId();
... ...
... ... @@ -26,6 +26,7 @@ import com.google.protobuf.AbstractMessage;
26 26 import com.google.protobuf.InvalidProtocolBufferException;
27 27 import com.google.protobuf.MessageLite;
28 28 import lombok.extern.slf4j.Slf4j;
  29 +import org.apache.commons.lang.RandomStringUtils;
29 30 import org.junit.After;
30 31 import org.junit.Assert;
31 32 import org.junit.Before;
... ... @@ -48,6 +49,7 @@ import org.thingsboard.server.common.data.edge.Edge;
48 49 import org.thingsboard.server.common.data.edge.EdgeEvent;
49 50 import org.thingsboard.server.common.data.edge.EdgeEventActionType;
50 51 import org.thingsboard.server.common.data.edge.EdgeEventType;
  52 +import org.thingsboard.server.common.data.id.DeviceId;
51 53 import org.thingsboard.server.common.data.id.EdgeId;
52 54 import org.thingsboard.server.common.data.id.EntityId;
53 55 import org.thingsboard.server.common.data.id.EntityIdFactory;
... ... @@ -964,6 +966,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
964 966 private void testSendMessagesToCloud() throws Exception {
965 967 log.info("Sending messages to cloud");
966 968 sendDevice();
  969 + sendDeviceWithNameThatAlreadyExistsOnCloud();
967 970 sendRelationRequest();
968 971 sendAlarm();
969 972 sendTelemetry();
... ... @@ -992,17 +995,66 @@ abstract public class BaseEdgeTest extends AbstractControllerTest {
992 995 uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build());
993 996
994 997 edgeImitator.expectResponsesAmount(1);
995   -
  998 + edgeImitator.expectMessageAmount(1);
996 999 testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder);
997 1000
998 1001 edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build());
  1002 +
999 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 1014 Assert.assertNotNull(device);
1003 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 1058 private void sendRelationRequest() throws Exception {
1007 1059 Device device = findDeviceByName("Edge Device 1");
1008 1060 Asset asset = findAssetByName("Edge Asset 1");
... ...
... ... @@ -34,5 +34,5 @@ public enum EdgeEventActionType {
34 34 ASSIGNED_TO_EDGE,
35 35 UNASSIGNED_FROM_EDGE,
36 36 CREDENTIALS_REQUEST,
37   - ENTITY_EXISTS_REQUEST
  37 + ENTITY_MERGE_REQUEST
38 38 }
\ No newline at end of file
... ...
... ... @@ -97,7 +97,7 @@ enum UpdateMsgType {
97 97 ENTITY_DELETED_RPC_MESSAGE = 2;
98 98 ALARM_ACK_RPC_MESSAGE = 3;
99 99 ALARM_CLEAR_RPC_MESSAGE = 4;
100   - DEVICE_CONFLICT_RPC_MESSAGE = 5;
  100 + ENTITY_MERGE_RPC_MESSAGE = 5;
101 101 }
102 102
103 103 message EntityDataProto {
... ... @@ -182,6 +182,7 @@ message DeviceUpdateMsg {
182 182 string type = 7;
183 183 string label = 8;
184 184 string additionalInfo = 9;
  185 + string conflictName = 10;
185 186 }
186 187
187 188 message DeviceCredentialsUpdateMsg {
... ...
... ... @@ -87,6 +87,7 @@ import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
87 87 import org.thingsboard.server.common.data.relation.RelationTypeGroup;
88 88 import org.thingsboard.server.common.data.rule.RuleChain;
89 89 import org.thingsboard.server.common.data.rule.RuleChainMetaData;
  90 +import org.thingsboard.server.common.data.rule.RuleChainType;
90 91 import org.thingsboard.server.common.data.security.DeviceCredentials;
91 92 import org.thingsboard.server.common.data.security.DeviceCredentialsType;
92 93 import org.thingsboard.server.common.data.security.model.SecuritySettings;
... ... @@ -97,6 +98,7 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle;
97 98 import java.io.Closeable;
98 99 import java.io.IOException;
99 100 import java.net.URI;
  101 +import java.util.Arrays;
100 102 import java.util.Collections;
101 103 import java.util.HashMap;
102 104 import java.util.List;
... ... @@ -626,22 +628,31 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable {
626 628 }
627 629
628 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 635 return restTemplate.exchange(
630   - baseURL + "/api/components?componentType={componentType}",
  636 + baseURL + "/api/components/" + componentType.name() + "/?ruleChainType={ruleChainType}",
631 637 HttpMethod.GET, HttpEntity.EMPTY,
632 638 new ParameterizedTypeReference<List<ComponentDescriptor>>() {
633 639 },
634   - componentType).getBody();
  640 + ruleChainType).getBody();
635 641 }
636 642
637 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 648 return restTemplate.exchange(
639   - baseURL + "/api/components?componentTypes={componentTypes}",
  649 + baseURL + "/api/components?componentTypes={componentTypes}&ruleChainType={ruleChainType}",
640 650 HttpMethod.GET,
641 651 HttpEntity.EMPTY,
642 652 new ParameterizedTypeReference<List<ComponentDescriptor>>() {
643 653 },
644   - listEnumToString(componentTypes))
  654 + listEnumToString(componentTypes),
  655 + ruleChainType)
645 656 .getBody();
646 657 }
647 658
... ...