Commit 995bac539c7c9fd3ffa9cf5e90fa2447a2680e3a

Authored by Volodymyr Babak
1 parent c5d93d17

Added findMissingToRelatedRuleChains method

... ... @@ -15,6 +15,9 @@
15 15 */
16 16 package org.thingsboard.server.controller;
17 17
  18 +import com.fasterxml.jackson.databind.ObjectMapper;
  19 +import com.fasterxml.jackson.databind.node.ArrayNode;
  20 +import com.fasterxml.jackson.databind.node.ObjectNode;
18 21 import com.google.common.util.concurrent.ListenableFuture;
19 22 import org.springframework.http.HttpStatus;
20 23 import org.springframework.security.access.prepost.PreAuthorize;
... ... @@ -54,6 +57,7 @@ import org.thingsboard.server.service.security.permission.Operation;
54 57 import org.thingsboard.server.service.security.permission.Resource;
55 58
56 59 import java.util.ArrayList;
  60 +import java.util.Arrays;
57 61 import java.util.List;
58 62 import java.util.stream.Collectors;
59 63
... ... @@ -486,14 +490,18 @@ public class EdgeController extends BaseController {
486 490 }
487 491
488 492 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
489   - @RequestMapping(value = "/edge/sync", method = RequestMethod.POST)
490   - public void syncEdge(@RequestBody EdgeId edgeId) throws ThingsboardException {
  493 + @RequestMapping(value = "/edge/sync/{edgeId}", method = RequestMethod.POST)
  494 + public void syncEdge(@PathVariable("edgeId") String strEdgeId) throws ThingsboardException {
  495 + checkParameter("edgeId", strEdgeId);
491 496 try {
492   - edgeId = checkNotNull(edgeId);
493 497 if (isEdgesEnabled()) {
494   - EdgeGrpcSession session = edgeGrpcService.getEdgeGrpcSessionById(edgeId);
  498 + EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
  499 + edgeId = checkNotNull(edgeId);
  500 + SecurityUser user = getCurrentUser();
  501 + TenantId tenantId = user.getTenantId();
  502 + EdgeGrpcSession session = edgeGrpcService.getEdgeGrpcSessionById(tenantId, edgeId);
495 503 Edge edge = session.getEdge();
496   - syncEdgeService.sync(edge);
  504 + syncEdgeService.sync(tenantId, edge);
497 505 } else {
498 506 throw new ThingsboardException("Edges support disabled", ThingsboardErrorCode.GENERAL);
499 507 }
... ... @@ -522,4 +530,19 @@ public class EdgeController extends BaseController {
522 530 throw new ThingsboardException(e, ThingsboardErrorCode.SUBSCRIPTION_VIOLATION);
523 531 }
524 532 }
  533 +
  534 + @PreAuthorize("hasAuthority('TENANT_ADMIN')")
  535 + @RequestMapping(value = "/edge/missingToRelatedRuleChains/{edgeId}", method = RequestMethod.GET)
  536 + @ResponseBody
  537 + public String findMissingToRelatedRuleChains(@PathVariable("edgeId") String strEdgeId) throws ThingsboardException {
  538 + try {
  539 + EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
  540 + edgeId = checkNotNull(edgeId);
  541 + SecurityUser user = getCurrentUser();
  542 + TenantId tenantId = user.getTenantId();
  543 + return edgeService.findMissingToRelatedRuleChains(tenantId, edgeId);
  544 + } catch (Exception e) {
  545 + throw handleException(e);
  546 + }
  547 + }
525 548 }
... ...
... ... @@ -113,11 +113,6 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
113 113 }
114 114
115 115 @Override
116   - public PageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) {
117   - return edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, true);
118   - }
119   -
120   - @Override
121 116 public Edge setEdgeRootRuleChain(TenantId tenantId, Edge edge, RuleChainId ruleChainId) throws IOException {
122 117 edge.setRootRuleChainId(ruleChainId);
123 118 Edge savedEdge = edgeService.saveEdge(edge);
... ...
... ... @@ -29,6 +29,7 @@ import org.thingsboard.server.dao.dashboard.DashboardService;
29 29 import org.thingsboard.server.dao.device.DeviceCredentialsService;
30 30 import org.thingsboard.server.dao.device.DeviceProfileService;
31 31 import org.thingsboard.server.dao.device.DeviceService;
  32 +import org.thingsboard.server.dao.edge.EdgeEventService;
32 33 import org.thingsboard.server.dao.edge.EdgeService;
33 34 import org.thingsboard.server.dao.entityview.EntityViewService;
34 35 import org.thingsboard.server.dao.relation.RelationService;
... ... @@ -76,7 +77,7 @@ public class EdgeContextComponent {
76 77
77 78 @Lazy
78 79 @Autowired
79   - private EdgeNotificationService edgeNotificationService;
  80 + private EdgeEventService edgeEventService;
80 81
81 82 @Lazy
82 83 @Autowired
... ...
... ... @@ -16,12 +16,8 @@
16 16 package org.thingsboard.server.service.edge;
17 17
18 18 import org.thingsboard.server.common.data.edge.Edge;
19   -import org.thingsboard.server.common.data.edge.EdgeEvent;
20   -import org.thingsboard.server.common.data.id.EdgeId;
21 19 import org.thingsboard.server.common.data.id.RuleChainId;
22 20 import org.thingsboard.server.common.data.id.TenantId;
23   -import org.thingsboard.server.common.data.page.PageData;
24   -import org.thingsboard.server.common.data.page.TimePageLink;
25 21 import org.thingsboard.server.common.msg.queue.TbCallback;
26 22 import org.thingsboard.server.gen.transport.TransportProtos;
27 23
... ... @@ -29,8 +25,6 @@ import java.io.IOException;
29 25
30 26 public interface EdgeNotificationService {
31 27
32   - PageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink);
33   -
34 28 Edge setEdgeRootRuleChain(TenantId tenantId, Edge edge, RuleChainId ruleChainId) throws IOException;
35 29
36 30 void pushNotificationToEdge(TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg, TbCallback callback);
... ...
... ... @@ -186,11 +186,12 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i
186 186 scheduleEdgeEventsCheck(edgeGrpcSession);
187 187 }
188 188
189   - public EdgeGrpcSession getEdgeGrpcSessionById(EdgeId edgeId) {
  189 + public EdgeGrpcSession getEdgeGrpcSessionById(TenantId tenantId, EdgeId edgeId) {
190 190 EdgeGrpcSession session = sessions.get(edgeId);
191 191 if (session != null && session.isConnected()) {
192 192 return session;
193 193 } else {
  194 + log.error("[{}] Edge is not connected [{}]", tenantId, edgeId);
194 195 throw new RuntimeException("Edge is not connected");
195 196 }
196 197 }
... ...
... ... @@ -170,7 +170,7 @@ public final class EdgeGrpcSession implements Closeable {
170 170 }
171 171 }
172 172 if (connected && requestMsg.getMsgType().equals(RequestMsgType.SYNC_REQUEST_RPC_MESSAGE)) {
173   - ctx.getSyncEdgeService().sync(edge);
  173 + ctx.getSyncEdgeService().sync(edge.getTenantId(), edge);
174 174 }
175 175 if (connected) {
176 176 if (requestMsg.getMsgType().equals(RequestMsgType.UPLINK_RPC_MESSAGE) && requestMsg.hasUplinkMsg()) {
... ... @@ -277,7 +277,7 @@ public final class EdgeGrpcSession implements Closeable {
277 277 UUID ifOffset = null;
278 278 boolean success = true;
279 279 do {
280   - pageData = ctx.getEdgeNotificationService().findEdgeEvents(edge.getTenantId(), edge.getId(), pageLink);
  280 + pageData = ctx.getEdgeEventService().findEdgeEvents(edge.getTenantId(), edge.getId(), pageLink, true);
281 281 if (isConnected() && !pageData.getData().isEmpty()) {
282 282 log.trace("[{}] [{}] event(s) are going to be processed.", this.sessionId, pageData.getData().size());
283 283 List<DownlinkMsg> downlinkMsgsPack = convertToDownlinkMsgsPack(pageData.getData());
... ... @@ -938,27 +938,27 @@ public final class EdgeGrpcSession implements Closeable {
938 938 }
939 939 if (uplinkMsg.getRuleChainMetadataRequestMsgCount() > 0) {
940 940 for (RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg : uplinkMsg.getRuleChainMetadataRequestMsgList()) {
941   - result.add(ctx.getSyncEdgeService().processRuleChainMetadataRequestMsg(edge, ruleChainMetadataRequestMsg));
  941 + result.add(ctx.getSyncEdgeService().processRuleChainMetadataRequestMsg(edge.getTenantId(), edge, ruleChainMetadataRequestMsg));
942 942 }
943 943 }
944 944 if (uplinkMsg.getAttributesRequestMsgCount() > 0) {
945 945 for (AttributesRequestMsg attributesRequestMsg : uplinkMsg.getAttributesRequestMsgList()) {
946   - result.add(ctx.getSyncEdgeService().processAttributesRequestMsg(edge, attributesRequestMsg));
  946 + result.add(ctx.getSyncEdgeService().processAttributesRequestMsg(edge.getTenantId(), edge, attributesRequestMsg));
947 947 }
948 948 }
949 949 if (uplinkMsg.getRelationRequestMsgCount() > 0) {
950 950 for (RelationRequestMsg relationRequestMsg : uplinkMsg.getRelationRequestMsgList()) {
951   - result.add(ctx.getSyncEdgeService().processRelationRequestMsg(edge, relationRequestMsg));
  951 + result.add(ctx.getSyncEdgeService().processRelationRequestMsg(edge.getTenantId(), edge, relationRequestMsg));
952 952 }
953 953 }
954 954 if (uplinkMsg.getUserCredentialsRequestMsgCount() > 0) {
955 955 for (UserCredentialsRequestMsg userCredentialsRequestMsg : uplinkMsg.getUserCredentialsRequestMsgList()) {
956   - result.add(ctx.getSyncEdgeService().processUserCredentialsRequestMsg(edge, userCredentialsRequestMsg));
  956 + result.add(ctx.getSyncEdgeService().processUserCredentialsRequestMsg(edge.getTenantId(), edge, userCredentialsRequestMsg));
957 957 }
958 958 }
959 959 if (uplinkMsg.getDeviceCredentialsRequestMsgCount() > 0) {
960 960 for (DeviceCredentialsRequestMsg deviceCredentialsRequestMsg : uplinkMsg.getDeviceCredentialsRequestMsgList()) {
961   - result.add(ctx.getSyncEdgeService().processDeviceCredentialsRequestMsg(edge, deviceCredentialsRequestMsg));
  961 + result.add(ctx.getSyncEdgeService().processDeviceCredentialsRequestMsg(edge.getTenantId(), edge, deviceCredentialsRequestMsg));
962 962 }
963 963 }
964 964 if (uplinkMsg.getDeviceRpcCallMsgCount() > 0) {
... ...
... ... @@ -148,35 +148,35 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
148 148 private TbClusterService tbClusterService;
149 149
150 150 @Override
151   - public void sync(Edge edge) {
152   - log.trace("[{}][{}] Staring edge sync process", edge.getTenantId(), edge.getId());
  151 + public void sync(TenantId tenantId, Edge edge) {
  152 + log.trace("[{}][{}] Staring edge sync process", tenantId, edge.getId());
153 153 try {
154   - syncWidgetsBundleAndWidgetTypes(edge);
  154 + syncWidgetsBundleAndWidgetTypes(tenantId, edge);
155 155 // TODO: voba - implement this functionality
156 156 // syncAdminSettings(edge);
157   - syncRuleChains(edge);
158   - syncDeviceProfiles(edge);
159   - syncUsers(edge);
160   - syncDevices(edge);
161   - syncAssets(edge);
162   - syncEntityViews(edge);
163   - syncDashboards(edge);
  157 + syncRuleChains(tenantId, edge);
  158 + syncDeviceProfiles(tenantId, edge);
  159 + syncUsers(tenantId, edge);
  160 + syncDevices(tenantId, edge);
  161 + syncAssets(tenantId, edge);
  162 + syncEntityViews(tenantId, edge);
  163 + syncDashboards(tenantId, edge);
164 164 } catch (Exception e) {
165   - log.error("[{}][{}] Exception during sync process", edge.getTenantId(), edge.getId(), e);
  165 + log.error("[{}][{}] Exception during sync process", tenantId, edge.getId(), e);
166 166 }
167 167 }
168 168
169   - private void syncRuleChains(Edge edge) {
170   - log.trace("[{}] syncRuleChains [{}]", edge.getTenantId(), edge.getName());
  169 + private void syncRuleChains(TenantId tenantId, Edge edge) {
  170 + log.trace("[{}] syncRuleChains [{}]", tenantId, edge.getName());
171 171 try {
172 172 TimePageLink pageLink = new TimePageLink(DEFAULT_LIMIT);
173 173 PageData<RuleChain> pageData;
174 174 do {
175   - pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
  175 + pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
176 176 if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
177 177 log.trace("[{}] [{}] rule chains(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
178 178 for (RuleChain ruleChain : pageData.getData()) {
179   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.RULE_CHAIN, EdgeEventActionType.ADDED, ruleChain.getId(), null);
  179 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, EdgeEventActionType.ADDED, ruleChain.getId(), null);
180 180 }
181 181 if (pageData.hasNext()) {
182 182 pageLink = pageLink.nextPageLink();
... ... @@ -188,17 +188,17 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
188 188 }
189 189 }
190 190
191   - private void syncDevices(Edge edge) {
192   - log.trace("[{}] syncDevices [{}]", edge.getTenantId(), edge.getName());
  191 + private void syncDevices(TenantId tenantId, Edge edge) {
  192 + log.trace("[{}] syncDevices [{}]", tenantId, edge.getName());
193 193 try {
194 194 TimePageLink pageLink = new TimePageLink(DEFAULT_LIMIT);
195 195 PageData<Device> pageData;
196 196 do {
197   - pageData = deviceService.findDevicesByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
  197 + pageData = deviceService.findDevicesByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
198 198 if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
199 199 log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
200 200 for (Device device : pageData.getData()) {
201   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ADDED, device.getId(), null);
  201 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ADDED, device.getId(), null);
202 202 }
203 203 if (pageData.hasNext()) {
204 204 pageLink = pageLink.nextPageLink();
... ... @@ -210,17 +210,17 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
210 210 }
211 211 }
212 212
213   - private void syncDeviceProfiles(Edge edge) {
214   - log.trace("[{}] syncDeviceProfiles [{}]", edge.getTenantId(), edge.getName());
  213 + private void syncDeviceProfiles(TenantId tenantId, Edge edge) {
  214 + log.trace("[{}] syncDeviceProfiles [{}]", tenantId, edge.getName());
215 215 try {
216 216 TimePageLink pageLink = new TimePageLink(DEFAULT_LIMIT);
217 217 PageData<DeviceProfile> pageData;
218 218 do {
219   - pageData = deviceProfileService.findDeviceProfiles(edge.getTenantId(), pageLink);
  219 + pageData = deviceProfileService.findDeviceProfiles(tenantId, pageLink);
220 220 if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
221 221 log.trace("[{}] [{}] user(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
222 222 for (DeviceProfile deviceProfile : pageData.getData()) {
223   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DEVICE_PROFILE, EdgeEventActionType.ADDED, deviceProfile.getId(), null);
  223 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE_PROFILE, EdgeEventActionType.ADDED, deviceProfile.getId(), null);
224 224 }
225 225 if (pageData.hasNext()) {
226 226 pageLink = pageLink.nextPageLink();
... ... @@ -232,17 +232,17 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
232 232 }
233 233 }
234 234
235   - private void syncAssets(Edge edge) {
236   - log.trace("[{}] syncAssets [{}]", edge.getTenantId(), edge.getName());
  235 + private void syncAssets(TenantId tenantId, Edge edge) {
  236 + log.trace("[{}] syncAssets [{}]", tenantId, edge.getName());
237 237 try {
238 238 TimePageLink pageLink = new TimePageLink(DEFAULT_LIMIT);
239 239 PageData<Asset> pageData;
240 240 do {
241   - pageData = assetService.findAssetsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
  241 + pageData = assetService.findAssetsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
242 242 if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
243 243 log.trace("[{}] [{}] asset(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
244 244 for (Asset asset : pageData.getData()) {
245   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ASSET, EdgeEventActionType.ADDED, asset.getId(), null);
  245 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ASSET, EdgeEventActionType.ADDED, asset.getId(), null);
246 246 }
247 247 if (pageData.hasNext()) {
248 248 pageLink = pageLink.nextPageLink();
... ... @@ -254,17 +254,17 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
254 254 }
255 255 }
256 256
257   - private void syncEntityViews(Edge edge) {
258   - log.trace("[{}] syncEntityViews [{}]", edge.getTenantId(), edge.getName());
  257 + private void syncEntityViews(TenantId tenantId, Edge edge) {
  258 + log.trace("[{}] syncEntityViews [{}]", tenantId, edge.getName());
259 259 try {
260 260 TimePageLink pageLink = new TimePageLink(DEFAULT_LIMIT);
261 261 PageData<EntityView> pageData;
262 262 do {
263   - pageData = entityViewService.findEntityViewsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
  263 + pageData = entityViewService.findEntityViewsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
264 264 if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
265 265 log.trace("[{}] [{}] entity view(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
266 266 for (EntityView entityView : pageData.getData()) {
267   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ENTITY_VIEW, EdgeEventActionType.ADDED, entityView.getId(), null);
  267 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ENTITY_VIEW, EdgeEventActionType.ADDED, entityView.getId(), null);
268 268 }
269 269 if (pageData.hasNext()) {
270 270 pageLink = pageLink.nextPageLink();
... ... @@ -276,17 +276,17 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
276 276 }
277 277 }
278 278
279   - private void syncDashboards(Edge edge) {
280   - log.trace("[{}] syncDashboards [{}]", edge.getTenantId(), edge.getName());
  279 + private void syncDashboards(TenantId tenantId, Edge edge) {
  280 + log.trace("[{}] syncDashboards [{}]", tenantId, edge.getName());
281 281 try {
282 282 TimePageLink pageLink = new TimePageLink(DEFAULT_LIMIT);
283 283 PageData<DashboardInfo> pageData;
284 284 do {
285   - pageData = dashboardService.findDashboardsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
  285 + pageData = dashboardService.findDashboardsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
286 286 if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
287 287 log.trace("[{}] [{}] dashboard(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
288 288 for (DashboardInfo dashboardInfo : pageData.getData()) {
289   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DASHBOARD, EdgeEventActionType.ADDED, dashboardInfo.getId(), null);
  289 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DASHBOARD, EdgeEventActionType.ADDED, dashboardInfo.getId(), null);
290 290 }
291 291 if (pageData.hasNext()) {
292 292 pageLink = pageLink.nextPageLink();
... ... @@ -298,32 +298,32 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
298 298 }
299 299 }
300 300
301   - private void syncUsers(Edge edge) {
302   - log.trace("[{}] syncUsers [{}]", edge.getTenantId(), edge.getName());
  301 + private void syncUsers(TenantId tenantId, Edge edge) {
  302 + log.trace("[{}] syncUsers [{}]", tenantId, edge.getName());
303 303 try {
304 304 TimePageLink pageLink = new TimePageLink(DEFAULT_LIMIT);
305 305 PageData<User> pageData;
306 306 do {
307   - pageData = userService.findTenantAdmins(edge.getTenantId(), pageLink);
308   - pushUsersToEdge(pageData, edge);
  307 + pageData = userService.findTenantAdmins(tenantId, pageLink);
  308 + pushUsersToEdge(tenantId, pageData, edge);
309 309 if (pageData.hasNext()) {
310 310 pageLink = pageLink.nextPageLink();
311 311 }
312 312 } while (pageData.hasNext());
313   - syncCustomerUsers(edge);
  313 + syncCustomerUsers(tenantId, edge);
314 314 } catch (Exception e) {
315 315 log.error("Exception during loading edge user(s) on sync!", e);
316 316 }
317 317 }
318 318
319   - private void syncCustomerUsers(Edge edge) {
  319 + private void syncCustomerUsers(TenantId tenantId, Edge edge) {
320 320 if (edge.getCustomerId() != null && !EntityId.NULL_UUID.equals(edge.getCustomerId().getId())) {
321   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, edge.getCustomerId(), null);
  321 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, edge.getCustomerId(), null);
322 322 TimePageLink pageLink = new TimePageLink(DEFAULT_LIMIT);
323 323 PageData<User> pageData;
324 324 do {
325   - pageData = userService.findCustomerUsers(edge.getTenantId(), edge.getCustomerId(), pageLink);
326   - pushUsersToEdge(pageData, edge);
  325 + pageData = userService.findCustomerUsers(tenantId, edge.getCustomerId(), pageLink);
  326 + pushUsersToEdge(tenantId, pageData, edge);
327 327 if (pageData != null && pageData.hasNext()) {
328 328 pageLink = pageLink.nextPageLink();
329 329 }
... ... @@ -331,45 +331,45 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
331 331 }
332 332 }
333 333
334   - private void pushUsersToEdge(PageData<User> pageData, Edge edge) {
  334 + private void pushUsersToEdge(TenantId tenantId, PageData<User> pageData, Edge edge) {
335 335 if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
336 336 log.trace("[{}] [{}] user(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
337 337 for (User user : pageData.getData()) {
338   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, EdgeEventActionType.ADDED, user.getId(), null);
  338 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER, EdgeEventActionType.ADDED, user.getId(), null);
339 339 }
340 340 }
341 341 }
342 342
343   - private void syncWidgetsBundleAndWidgetTypes(Edge edge) {
344   - log.trace("[{}] syncWidgetsBundleAndWidgetTypes [{}]", edge.getTenantId(), edge.getName());
  343 + private void syncWidgetsBundleAndWidgetTypes(TenantId tenantId, Edge edge) {
  344 + log.trace("[{}] syncWidgetsBundleAndWidgetTypes [{}]", tenantId, edge.getName());
345 345 List<WidgetsBundle> widgetsBundlesToPush = new ArrayList<>();
346 346 List<WidgetType> widgetTypesToPush = new ArrayList<>();
347   - widgetsBundlesToPush.addAll(widgetsBundleService.findAllTenantWidgetsBundlesByTenantId(edge.getTenantId()));
348   - widgetsBundlesToPush.addAll(widgetsBundleService.findSystemWidgetsBundles(edge.getTenantId()));
  347 + widgetsBundlesToPush.addAll(widgetsBundleService.findAllTenantWidgetsBundlesByTenantId(tenantId));
  348 + widgetsBundlesToPush.addAll(widgetsBundleService.findSystemWidgetsBundles(tenantId));
349 349 try {
350 350 for (WidgetsBundle widgetsBundle: widgetsBundlesToPush) {
351   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.WIDGETS_BUNDLE, EdgeEventActionType.ADDED, widgetsBundle.getId(), null);
  351 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGETS_BUNDLE, EdgeEventActionType.ADDED, widgetsBundle.getId(), null);
352 352 widgetTypesToPush.addAll(widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(widgetsBundle.getTenantId(), widgetsBundle.getAlias()));
353 353 }
354 354 for (WidgetType widgetType: widgetTypesToPush) {
355   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.WIDGET_TYPE, EdgeEventActionType.ADDED, widgetType.getId(), null);
  355 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGET_TYPE, EdgeEventActionType.ADDED, widgetType.getId(), null);
356 356 }
357 357 } catch (Exception e) {
358 358 log.error("Exception during loading widgets bundle(s) and widget type(s) on sync!", e);
359 359 }
360 360 }
361 361
362   - private void syncAdminSettings(Edge edge) {
363   - log.trace("[{}] syncAdminSettings [{}]", edge.getTenantId(), edge.getName());
  362 + private void syncAdminSettings(TenantId tenantId, Edge edge) {
  363 + log.trace("[{}] syncAdminSettings [{}]", tenantId, edge.getName());
364 364 try {
365 365 AdminSettings systemMailSettings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail");
366   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailSettings));
  366 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailSettings));
367 367 AdminSettings tenantMailSettings = convertToTenantAdminSettings(systemMailSettings.getKey(), (ObjectNode) systemMailSettings.getJsonValue());
368   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailSettings));
  368 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailSettings));
369 369 AdminSettings systemMailTemplates = loadMailTemplates();
370   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailTemplates));
  370 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailTemplates));
371 371 AdminSettings tenantMailTemplates = convertToTenantAdminSettings(systemMailTemplates.getKey(), (ObjectNode) systemMailTemplates.getJsonValue());
372   - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailTemplates));
  372 + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailTemplates));
373 373 } catch (Exception e) {
374 374 log.error("Can't load admin settings", e);
375 375 }
... ... @@ -428,13 +428,13 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
428 428 }
429 429
430 430 @Override
431   - public ListenableFuture<Void> processRuleChainMetadataRequestMsg(Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) {
432   - log.trace("[{}] processRuleChainMetadataRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), ruleChainMetadataRequestMsg);
  431 + public ListenableFuture<Void> processRuleChainMetadataRequestMsg(TenantId tenantId, Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) {
  432 + log.trace("[{}] processRuleChainMetadataRequestMsg [{}][{}]", tenantId, edge.getName(), ruleChainMetadataRequestMsg);
433 433 SettableFuture<Void> futureToSet = SettableFuture.create();
434 434 if (ruleChainMetadataRequestMsg.getRuleChainIdMSB() != 0 && ruleChainMetadataRequestMsg.getRuleChainIdLSB() != 0) {
435 435 RuleChainId ruleChainId =
436 436 new RuleChainId(new UUID(ruleChainMetadataRequestMsg.getRuleChainIdMSB(), ruleChainMetadataRequestMsg.getRuleChainIdLSB()));
437   - ListenableFuture<EdgeEvent> future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.RULE_CHAIN_METADATA, EdgeEventActionType.ADDED, ruleChainId, null);
  437 + ListenableFuture<EdgeEvent> future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN_METADATA, EdgeEventActionType.ADDED, ruleChainId, null);
438 438 Futures.addCallback(future, new FutureCallback<EdgeEvent>() {
439 439 @Override
440 440 public void onSuccess(@Nullable EdgeEvent result) {
... ... @@ -452,8 +452,8 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
452 452 }
453 453
454 454 @Override
455   - public ListenableFuture<Void> processAttributesRequestMsg(Edge edge, AttributesRequestMsg attributesRequestMsg) {
456   - log.trace("[{}] processAttributesRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), attributesRequestMsg);
  455 + public ListenableFuture<Void> processAttributesRequestMsg(TenantId tenantId, Edge edge, AttributesRequestMsg attributesRequestMsg) {
  456 + log.trace("[{}] processAttributesRequestMsg [{}][{}]", tenantId, edge.getName(), attributesRequestMsg);
457 457 EntityId entityId = EntityIdFactory.getByTypeAndUuid(
458 458 EntityType.valueOf(attributesRequestMsg.getEntityType()),
459 459 new UUID(attributesRequestMsg.getEntityIdMSB(), attributesRequestMsg.getEntityIdLSB()));
... ... @@ -461,7 +461,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
461 461 if (type != null) {
462 462 SettableFuture<Void> futureToSet = SettableFuture.create();
463 463 String scope = attributesRequestMsg.getScope();
464   - ListenableFuture<List<AttributeKvEntry>> ssAttrFuture = attributesService.findAll(edge.getTenantId(), entityId, scope);
  464 + ListenableFuture<List<AttributeKvEntry>> ssAttrFuture = attributesService.findAll(tenantId, entityId, scope);
465 465 Futures.addCallback(ssAttrFuture, new FutureCallback<List<AttributeKvEntry>>() {
466 466 @Override
467 467 public void onSuccess(@Nullable List<AttributeKvEntry> ssAttributes) {
... ... @@ -484,7 +484,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
484 484 entityData.put("scope", scope);
485 485 JsonNode body = mapper.valueToTree(entityData);
486 486 log.debug("Sending attributes data msg, entityId [{}], attributes [{}]", entityId, body);
487   - saveEdgeEvent(edge.getTenantId(),
  487 + saveEdgeEvent(tenantId,
488 488 edge.getId(),
489 489 type,
490 490 EdgeEventActionType.ATTRIBUTES_UPDATED,
... ... @@ -495,7 +495,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
495 495 throw new RuntimeException("[" + edge.getName() + "] Failed to send attribute updates to the edge", e);
496 496 }
497 497 } else {
498   - log.trace("[{}][{}] No attributes found for entity {} [{}]", edge.getTenantId(),
  498 + log.trace("[{}][{}] No attributes found for entity {} [{}]", tenantId,
499 499 edge.getName(),
500 500 entityId.getEntityType(),
501 501 entityId.getId());
... ... @@ -511,21 +511,21 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
511 511 }, dbCallbackExecutorService);
512 512 return futureToSet;
513 513 } else {
514   - log.warn("[{}] Type doesn't supported {}", edge.getTenantId(), entityId.getEntityType());
  514 + log.warn("[{}] Type doesn't supported {}", tenantId, entityId.getEntityType());
515 515 return Futures.immediateFuture(null);
516 516 }
517 517 }
518 518
519 519 @Override
520   - public ListenableFuture<Void> processRelationRequestMsg(Edge edge, RelationRequestMsg relationRequestMsg) {
521   - log.trace("[{}] processRelationRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), relationRequestMsg);
  520 + public ListenableFuture<Void> processRelationRequestMsg(TenantId tenantId, Edge edge, RelationRequestMsg relationRequestMsg) {
  521 + log.trace("[{}] processRelationRequestMsg [{}][{}]", tenantId, edge.getName(), relationRequestMsg);
522 522 EntityId entityId = EntityIdFactory.getByTypeAndUuid(
523 523 EntityType.valueOf(relationRequestMsg.getEntityType()),
524 524 new UUID(relationRequestMsg.getEntityIdMSB(), relationRequestMsg.getEntityIdLSB()));
525 525
526 526 List<ListenableFuture<List<EntityRelation>>> futures = new ArrayList<>();
527   - futures.add(findRelationByQuery(edge, entityId, EntitySearchDirection.FROM));
528   - futures.add(findRelationByQuery(edge, entityId, EntitySearchDirection.TO));
  527 + futures.add(findRelationByQuery(tenantId, edge, entityId, EntitySearchDirection.FROM));
  528 + futures.add(findRelationByQuery(tenantId, edge, entityId, EntitySearchDirection.TO));
529 529 ListenableFuture<List<List<EntityRelation>>> relationsListFuture = Futures.allAsList(futures);
530 530 SettableFuture<Void> futureToSet = SettableFuture.create();
531 531 Futures.addCallback(relationsListFuture, new FutureCallback<List<List<EntityRelation>>>() {
... ... @@ -539,7 +539,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
539 539 try {
540 540 if (!relation.getFrom().getEntityType().equals(EntityType.EDGE) &&
541 541 !relation.getTo().getEntityType().equals(EntityType.EDGE)) {
542   - saveEdgeEvent(edge.getTenantId(),
  542 + saveEdgeEvent(tenantId,
543 543 edge.getId(),
544 544 EdgeEventType.RELATION,
545 545 EdgeEventActionType.ADDED,
... ... @@ -563,26 +563,26 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
563 563
564 564 @Override
565 565 public void onFailure(Throwable t) {
566   - log.error("[{}] Can't find relation by query. Entity id [{}]", edge.getTenantId(), entityId, t);
  566 + log.error("[{}] Can't find relation by query. Entity id [{}]", tenantId, entityId, t);
567 567 futureToSet.setException(t);
568 568 }
569 569 }, dbCallbackExecutorService);
570 570 return futureToSet;
571 571 }
572 572
573   - private ListenableFuture<List<EntityRelation>> findRelationByQuery(Edge edge, EntityId entityId, EntitySearchDirection direction) {
  573 + private ListenableFuture<List<EntityRelation>> findRelationByQuery(TenantId tenantId, Edge edge, EntityId entityId, EntitySearchDirection direction) {
574 574 EntityRelationsQuery query = new EntityRelationsQuery();
575 575 query.setParameters(new RelationsSearchParameters(entityId, direction, -1, false));
576   - return relationService.findByQuery(edge.getTenantId(), query);
  576 + return relationService.findByQuery(tenantId, query);
577 577 }
578 578
579 579 @Override
580   - public ListenableFuture<Void> processDeviceCredentialsRequestMsg(Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg) {
581   - log.trace("[{}] processDeviceCredentialsRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), deviceCredentialsRequestMsg);
  580 + public ListenableFuture<Void> processDeviceCredentialsRequestMsg(TenantId tenantId, Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg) {
  581 + log.trace("[{}] processDeviceCredentialsRequestMsg [{}][{}]", tenantId, edge.getName(), deviceCredentialsRequestMsg);
582 582 SettableFuture<Void> futureToSet = SettableFuture.create();
583 583 if (deviceCredentialsRequestMsg.getDeviceIdMSB() != 0 && deviceCredentialsRequestMsg.getDeviceIdLSB() != 0) {
584 584 DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsRequestMsg.getDeviceIdMSB(), deviceCredentialsRequestMsg.getDeviceIdLSB()));
585   - ListenableFuture<EdgeEvent> future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_UPDATED, deviceId, null);
  585 + ListenableFuture<EdgeEvent> future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_UPDATED, deviceId, null);
586 586 Futures.addCallback(future, new FutureCallback<EdgeEvent>() {
587 587 @Override
588 588 public void onSuccess(@Nullable EdgeEvent result) {
... ... @@ -600,12 +600,12 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
600 600 }
601 601
602 602 @Override
603   - public ListenableFuture<Void> processUserCredentialsRequestMsg(Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg) {
604   - log.trace("[{}] processUserCredentialsRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), userCredentialsRequestMsg);
  603 + public ListenableFuture<Void> processUserCredentialsRequestMsg(TenantId tenantId, Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg) {
  604 + log.trace("[{}] processUserCredentialsRequestMsg [{}][{}]", tenantId, edge.getName(), userCredentialsRequestMsg);
605 605 SettableFuture<Void> futureToSet = SettableFuture.create();
606 606 if (userCredentialsRequestMsg.getUserIdMSB() != 0 && userCredentialsRequestMsg.getUserIdLSB() != 0) {
607 607 UserId userId = new UserId(new UUID(userCredentialsRequestMsg.getUserIdMSB(), userCredentialsRequestMsg.getUserIdLSB()));
608   - ListenableFuture<EdgeEvent> future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, EdgeEventActionType.CREDENTIALS_UPDATED, userId, null);
  608 + ListenableFuture<EdgeEvent> future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER, EdgeEventActionType.CREDENTIALS_UPDATED, userId, null);
609 609 Futures.addCallback(future, new FutureCallback<EdgeEvent>() {
610 610 @Override
611 611 public void onSuccess(@Nullable EdgeEvent result) {
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.service.edge.rpc.init;
17 17
18 18 import com.google.common.util.concurrent.ListenableFuture;
19 19 import org.thingsboard.server.common.data.edge.Edge;
  20 +import org.thingsboard.server.common.data.id.TenantId;
20 21 import org.thingsboard.server.gen.edge.AttributesRequestMsg;
21 22 import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg;
22 23 import org.thingsboard.server.gen.edge.RelationRequestMsg;
... ... @@ -25,15 +26,15 @@ import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg;
25 26
26 27 public interface SyncEdgeService {
27 28
28   - void sync(Edge edge);
  29 + void sync(TenantId tenantId, Edge edge);
29 30
30   - ListenableFuture<Void> processRuleChainMetadataRequestMsg(Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg);
  31 + ListenableFuture<Void> processRuleChainMetadataRequestMsg(TenantId tenantId, Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg);
31 32
32   - ListenableFuture<Void> processAttributesRequestMsg(Edge edge, AttributesRequestMsg attributesRequestMsg);
  33 + ListenableFuture<Void> processAttributesRequestMsg(TenantId tenantId, Edge edge, AttributesRequestMsg attributesRequestMsg);
33 34
34   - ListenableFuture<Void> processRelationRequestMsg(Edge edge, RelationRequestMsg relationRequestMsg);
  35 + ListenableFuture<Void> processRelationRequestMsg(TenantId tenantId, Edge edge, RelationRequestMsg relationRequestMsg);
35 36
36   - ListenableFuture<Void> processDeviceCredentialsRequestMsg(Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg);
  37 + ListenableFuture<Void> processDeviceCredentialsRequestMsg(TenantId tenantId, Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg);
37 38
38   - ListenableFuture<Void> processUserCredentialsRequestMsg(Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg);
  39 + ListenableFuture<Void> processUserCredentialsRequestMsg(TenantId tenantId, Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg);
39 40 }
... ...
... ... @@ -91,4 +91,6 @@ public interface EdgeService {
91 91 Object checkInstance(Object request);
92 92
93 93 Object activateInstance(String licenseSecret, String releaseDate);
  94 +
  95 + String findMissingToRelatedRuleChains(TenantId tenantId, EdgeId edgeId);
94 96 }
... ...
... ... @@ -15,6 +15,9 @@
15 15 */
16 16 package org.thingsboard.server.dao.edge;
17 17
  18 +import com.fasterxml.jackson.databind.ObjectMapper;
  19 +import com.fasterxml.jackson.databind.node.ArrayNode;
  20 +import com.fasterxml.jackson.databind.node.ObjectNode;
18 21 import com.google.common.base.Function;
19 22 import com.google.common.util.concurrent.FutureCallback;
20 23 import com.google.common.util.concurrent.Futures;
... ... @@ -43,6 +46,8 @@ import org.thingsboard.server.common.data.EntityType;
43 46 import org.thingsboard.server.common.data.Tenant;
44 47 import org.thingsboard.server.common.data.User;
45 48 import org.thingsboard.server.common.data.edge.Edge;
  49 +import org.thingsboard.server.common.data.edge.EdgeEventActionType;
  50 +import org.thingsboard.server.common.data.edge.EdgeEventType;
46 51 import org.thingsboard.server.common.data.edge.EdgeInfo;
47 52 import org.thingsboard.server.common.data.edge.EdgeSearchQuery;
48 53 import org.thingsboard.server.common.data.id.CustomerId;
... ... @@ -55,10 +60,12 @@ import org.thingsboard.server.common.data.id.TenantId;
55 60 import org.thingsboard.server.common.data.id.UserId;
56 61 import org.thingsboard.server.common.data.page.PageData;
57 62 import org.thingsboard.server.common.data.page.PageLink;
  63 +import org.thingsboard.server.common.data.page.TimePageLink;
58 64 import org.thingsboard.server.common.data.relation.EntityRelation;
59 65 import org.thingsboard.server.common.data.relation.EntitySearchDirection;
60 66 import org.thingsboard.server.common.data.relation.RelationTypeGroup;
61 67 import org.thingsboard.server.common.data.rule.RuleChain;
  68 +import org.thingsboard.server.common.data.rule.RuleChainConnectionInfo;
62 69 import org.thingsboard.server.dao.customer.CustomerDao;
63 70 import org.thingsboard.server.dao.entity.AbstractEntityService;
64 71 import org.thingsboard.server.dao.exception.DataValidationException;
... ... @@ -100,6 +107,8 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
100 107 public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId ";
101 108 public static final String INCORRECT_EDGE_ID = "Incorrect edgeId ";
102 109
  110 + private static final ObjectMapper mapper = new ObjectMapper();
  111 +
103 112 private static final int DEFAULT_LIMIT = 100;
104 113
105 114 private RestTemplate restTemplate;
... ... @@ -583,6 +592,52 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
583 592 return this.restTemplate.postForEntity(EDGE_LICENSE_SERVER_ENDPOINT + "/api/license/activateInstance?licenseSecret={licenseSecret}&releaseDate={releaseDate}", (Object) null, Object.class, params);
584 593 }
585 594
  595 + @Override
  596 + public String findMissingToRelatedRuleChains(TenantId tenantId, EdgeId edgeId) {
  597 + List<RuleChain> edgeRuleChains = findEdgeRuleChains(tenantId, edgeId);
  598 + List<RuleChainId> edgeRuleChainIds = edgeRuleChains.stream().map(IdBased::getId).collect(Collectors.toList());
  599 + ObjectNode result = mapper.createObjectNode();
  600 + for (RuleChain edgeRuleChain : edgeRuleChains) {
  601 + List<RuleChainConnectionInfo> connectionInfos =
  602 + ruleChainService.loadRuleChainMetaData(edgeRuleChain.getTenantId(), edgeRuleChain.getId()).getRuleChainConnections();
  603 + if (connectionInfos != null && !connectionInfos.isEmpty()) {
  604 + List<RuleChainId> connectedRuleChains =
  605 + connectionInfos.stream().map(RuleChainConnectionInfo::getTargetRuleChainId).collect(Collectors.toList());
  606 + List<String> missingRuleChains = new ArrayList<>();
  607 + for (RuleChainId connectedRuleChain : connectedRuleChains) {
  608 + if (!edgeRuleChainIds.contains(connectedRuleChain)) {
  609 + RuleChain ruleChainById = ruleChainService.findRuleChainById(tenantId, connectedRuleChain);
  610 + missingRuleChains.add(ruleChainById.getName());
  611 + }
  612 + }
  613 + if (!missingRuleChains.isEmpty()) {
  614 + ArrayNode array = mapper.createArrayNode();
  615 + for (String missingRuleChain : missingRuleChains) {
  616 + array.add(missingRuleChain);
  617 + }
  618 + result.set(edgeRuleChain.getName(), array);
  619 + }
  620 + }
  621 + }
  622 + return result.toString();
  623 + }
  624 +
  625 + private List<RuleChain> findEdgeRuleChains(TenantId tenantId, EdgeId edgeId) {
  626 + List<RuleChain> result = new ArrayList<>();
  627 + TimePageLink pageLink = new TimePageLink(DEFAULT_LIMIT);
  628 + PageData<RuleChain> pageData;
  629 + do {
  630 + pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edgeId, pageLink);
  631 + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
  632 + result.addAll(pageData.getData());
  633 + if (pageData.hasNext()) {
  634 + pageLink = pageLink.nextPageLink();
  635 + }
  636 + }
  637 + } while (pageData != null && pageData.hasNext());
  638 + return result;
  639 + }
  640 +
586 641 private void initRestTemplate() {
587 642 boolean jdkHttpClientEnabled = isNotEmpty(System.getProperty("tb.proxy.jdk")) && System.getProperty("tb.proxy.jdk").equalsIgnoreCase("true");
588 643 boolean systemProxyEnabled = isNotEmpty(System.getProperty("tb.proxy.system")) && System.getProperty("tb.proxy.system").equalsIgnoreCase("true");
... ...
... ... @@ -749,9 +749,9 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
749 749 }
750 750 }
751 751 if (ruleChain.isRoot() && RuleChainType.EDGE.equals(ruleChain.getType())) {
752   - RuleChain defaultRootEdgeRuleChain = getEdgeTemplateRootRuleChain(ruleChain.getTenantId());
753   - if (defaultRootEdgeRuleChain != null && !defaultRootEdgeRuleChain.getId().equals(ruleChain.getId())) {
754   - throw new DataValidationException("Another default root edge rule chain is present in scope of current tenant!");
  752 + RuleChain edgeTemplateRootRuleChain = getEdgeTemplateRootRuleChain(ruleChain.getTenantId());
  753 + if (edgeTemplateRootRuleChain != null && !edgeTemplateRootRuleChain.getId().equals(ruleChain.getId())) {
  754 + throw new DataValidationException("Another edge template root rule chain is present in scope of current tenant!");
755 755 }
756 756 }
757 757 }
... ...
... ... @@ -2678,7 +2678,7 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable {
2678 2678
2679 2679 public Optional<RuleChain> setAutoAssignToEdgeRuleChain(RuleChainId ruleChainId) {
2680 2680 try {
2681   - ResponseEntity<RuleChain> ruleChain = restTemplate.postForEntity(baseURL + "/api/ruleChain/{ruleChainId}/defaultEdge", null, RuleChain.class, ruleChainId.getId());
  2681 + ResponseEntity<RuleChain> ruleChain = restTemplate.postForEntity(baseURL + "/api/ruleChain/{ruleChainId}/autoAssignToEdge", null, RuleChain.class, ruleChainId.getId());
2682 2682 return Optional.ofNullable(ruleChain.getBody());
2683 2683 } catch (HttpClientErrorException exception) {
2684 2684 if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
... ... @@ -2691,7 +2691,7 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable {
2691 2691
2692 2692 public Optional<RuleChain> unsetAutoAssignToEdgeRuleChain(RuleChainId ruleChainId) {
2693 2693 try {
2694   - ResponseEntity<RuleChain> ruleChain = restTemplate.exchange(baseURL + "/api/ruleChain/{ruleChainId}/defaultEdge", HttpMethod.DELETE, HttpEntity.EMPTY, RuleChain.class, ruleChainId.getId());
  2694 + ResponseEntity<RuleChain> ruleChain = restTemplate.exchange(baseURL + "/api/ruleChain/{ruleChainId}/autoAssignToEdge", HttpMethod.DELETE, HttpEntity.EMPTY, RuleChain.class, ruleChainId.getId());
2695 2695 return Optional.ofNullable(ruleChain.getBody());
2696 2696 } catch (HttpClientErrorException exception) {
2697 2697 if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
... ... @@ -2703,7 +2703,7 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable {
2703 2703 }
2704 2704
2705 2705 public List<RuleChain> getAutoAssignToEdgeRuleChains() {
2706   - return restTemplate.exchange(baseURL + "/api/ruleChain/defaultEdgeRuleChains",
  2706 + return restTemplate.exchange(baseURL + "/api/ruleChain/autoAssignToEdgeRuleChains",
2707 2707 HttpMethod.GET,
2708 2708 HttpEntity.EMPTY,
2709 2709 new ParameterizedTypeReference<List<RuleChain>>() {
... ...
... ... @@ -97,7 +97,11 @@ export class EdgeService {
97 97 defaultHttpOptionsFromConfig(config));
98 98 }
99 99
100   - public syncEdge(edgeId: EdgeId, config?: RequestConfig) {
101   - return this.http.post(`/api/edge/sync`, edgeId, defaultHttpOptionsFromConfig(config));
  100 + public syncEdge(edgeId: string, config?: RequestConfig) {
  101 + return this.http.post(`/api/edge/sync/${edgeId}`, edgeId, defaultHttpOptionsFromConfig(config));
  102 + }
  103 +
  104 + public findMissingToRelatedRuleChains(edgeId: string, config?: RequestConfig): Observable<string> {
  105 + return this.http.get<string>(`/api/edge/missingToRelatedRuleChains/${edgeId}`, defaultHttpOptionsFromConfig(config));
102 106 }
103 107 }
... ...
... ... @@ -483,7 +483,7 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI
483 483 if ($event) {
484 484 $event.stopPropagation();
485 485 }
486   - this.edgeService.syncEdge(edge.id).subscribe(
  486 + this.edgeService.syncEdge(edge.id.id).subscribe(
487 487 () => {
488 488 this.store.dispatch(new ActionNotificationShow(
489 489 {
... ...
... ... @@ -45,10 +45,16 @@ import {
45 45 AddEntitiesToEdgeDialogData
46 46 } from "@home/dialogs/add-entities-to-edge-dialog.component";
47 47 import { MatDialog } from "@angular/material/dialog";
48   -import { isUndefined } from "@core/utils";
  48 +import { isNotEmptyStr, isUndefined } from "@core/utils";
49 49 import { PageLink } from "@shared/models/page/page-link";
50 50 import { Edge } from "@shared/models/edge.models";
51   -import { map, mergeMap } from "rxjs/operators";
  51 +import { mergeMap } from "rxjs/operators";
  52 +import {
  53 + ConnectorType,
  54 + createFormConfig,
  55 + GatewayFormConnectorModel
  56 +} from "@home/components/widget/lib/gateway/gateway-form.models";
  57 +import { formattedError } from "@angular/compiler";
52 58
53 59 @Injectable()
54 60 export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig<RuleChain>> {
... ... @@ -401,7 +407,28 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig<
401 407 }).afterClosed()
402 408 .subscribe((res) => {
403 409 if (res) {
404   - this.config.table.updateData();
  410 + this.edgeService.findMissingToRelatedRuleChains(this.config.componentsData.edgeId).subscribe(
  411 + (missingRuleChains) => {
  412 + if (missingRuleChains && Object.keys(missingRuleChains).length > 0) {
  413 + let formattedMissingRuleChains: Array<string> = new Array<string>();
  414 + for (const missingRuleChain of Object.keys(missingRuleChains)) {
  415 + const arrayOfMissingRuleChains = missingRuleChains[missingRuleChain];
  416 + const tmp = "- '" + missingRuleChain + "': '" + arrayOfMissingRuleChains.join("', ") + "'";
  417 + formattedMissingRuleChains.push(tmp);
  418 + }
  419 + const message = this.translate.instant('edge.missing-related-rule-chains-text',
  420 + {missingRuleChains: formattedMissingRuleChains.join("<br>")});
  421 + this.dialogService.alert(this.translate.instant('edge.missing-related-rule-chains-title'),
  422 + message, this.translate.instant('action.close'), true).subscribe(
  423 + () => {
  424 + this.config.table.updateData();
  425 + }
  426 + );
  427 + } else {
  428 + this.config.table.updateData();
  429 + }
  430 + }
  431 + )
405 432 }
406 433 }
407 434 )
... ...
... ... @@ -1210,7 +1210,9 @@
1210 1210 "pending": "Pending",
1211 1211 "downlinks": "Downlinks",
1212 1212 "no-downlinks-prompt": "No downlinks found",
1213   - "sync-process-started-successfully": "Sync process started successfully!"
  1213 + "sync-process-started-successfully": "Sync process started successfully!",
  1214 + "missing-related-rule-chains-title": "Edge has missing related rule chain(s)",
  1215 + "missing-related-rule-chains-text": "Assigned to edge rule chain(s) use rule nodes that forward message(s) to rule chain(s) that are not assigned to this edge. <br><br> List of missing rule chain(s): <br> {{missingRuleChains}}"
1214 1216 },
1215 1217 "edge-event": {
1216 1218 "type-dashboard": "Dashboard",
... ... @@ -2087,15 +2089,15 @@
2087 2089 "unassign-rulechains-from-edge-text": "After the confirmation all selected rulechains will be unassigned and won't be accessible by the edge.",
2088 2090 "assign-rulechain-to-edge-title": "Assign Rule Chain(s) To Edge",
2089 2091 "assign-rulechain-to-edge-text": "Please select the rulechains to assign to the edge",
2090   - "set-edge-template-root-rulechain": "Make rule chain edge template root",
  2092 + "set-edge-template-root-rulechain": "Make rule chain as edge template root",
2091 2093 "set-edge-template-root-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' edge template root?",
2092 2094 "set-edge-template-root-rulechain-text": "After the confirmation the rule chain will become edge template root and will be root rule chain for a newly created edges.",
2093 2095 "invalid-rulechain-type-error": "Unable to import rule chain: Invalid rule chain type. Expected type is {{expectedRuleChainType}}.",
2094 2096 "set-auto-assign-to-edge": "Assign rule chain to edge(s) on creation",
2095 2097 "set-auto-assign-to-edge-title": "Are you sure you want to assign the edge rule chain '{{ruleChainName}}' to edge(s) on creation?",
2096 2098 "set-auto-assign-to-edge-text": "After the confirmation the edge rule chain will be automatically assigned to edge(s) on creation.",
2097   - "unset-auto-assign-to-edge": "Unset assign rule chain to edge(s) on creation",
2098   - "unset-auto-assign-to-edge-title": "Are you sure you want to unset assign the edge rule chain '{{ruleChainName}}' to edge(s) on creation?",
  2099 + "unset-auto-assign-to-edge": "Do not assign rule chain to edge(s) on creation",
  2100 + "unset-auto-assign-to-edge-title": "Are you sure you do not want to assign the edge rule chain '{{ruleChainName}}' to edge(s) on creation?",
2099 2101 "unset-auto-assign-to-edge-text": "After the confirmation the edge rule chain will no longer be automatically assigned to edge(s) on creation.",
2100 2102 "unassign-rulechain-title": "Are you sure you want to unassign the rulechain '{{ruleChainName}}'?",
2101 2103 "unassign-rulechains": "Unassign rulechains"
... ...