Commit e7906375a6fac21eeb41b94085acc4b4df0116aa
Committed by
GitHub
Merge pull request #30 from BohdanSmetanyuk/feature/widgets_bundle_fetch
WidgetsBundle fetch + WidgetTypes fetch
Showing
12 changed files
with
313 additions
and
18 deletions
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.controller; | 16 | package org.thingsboard.server.controller; |
17 | 17 | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
18 | import org.springframework.http.HttpStatus; | 19 | import org.springframework.http.HttpStatus; |
19 | import org.springframework.security.access.prepost.PreAuthorize; | 20 | import org.springframework.security.access.prepost.PreAuthorize; |
20 | import org.springframework.web.bind.annotation.PathVariable; | 21 | import org.springframework.web.bind.annotation.PathVariable; |
@@ -25,6 +26,7 @@ import org.springframework.web.bind.annotation.RequestParam; | @@ -25,6 +26,7 @@ import org.springframework.web.bind.annotation.RequestParam; | ||
25 | import org.springframework.web.bind.annotation.ResponseBody; | 26 | import org.springframework.web.bind.annotation.ResponseBody; |
26 | import org.springframework.web.bind.annotation.ResponseStatus; | 27 | import org.springframework.web.bind.annotation.ResponseStatus; |
27 | import org.springframework.web.bind.annotation.RestController; | 28 | import org.springframework.web.bind.annotation.RestController; |
29 | +import org.thingsboard.server.common.data.audit.ActionType; | ||
28 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 30 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
29 | import org.thingsboard.server.common.data.id.TenantId; | 31 | import org.thingsboard.server.common.data.id.TenantId; |
30 | import org.thingsboard.server.common.data.id.WidgetTypeId; | 32 | import org.thingsboard.server.common.data.id.WidgetTypeId; |
@@ -37,6 +39,7 @@ import org.thingsboard.server.service.security.permission.Resource; | @@ -37,6 +39,7 @@ import org.thingsboard.server.service.security.permission.Resource; | ||
37 | 39 | ||
38 | import java.util.List; | 40 | import java.util.List; |
39 | 41 | ||
42 | +@Slf4j | ||
40 | @RestController | 43 | @RestController |
41 | @TbCoreComponent | 44 | @TbCoreComponent |
42 | @RequestMapping("/api") | 45 | @RequestMapping("/api") |
@@ -67,8 +70,11 @@ public class WidgetTypeController extends BaseController { | @@ -67,8 +70,11 @@ public class WidgetTypeController extends BaseController { | ||
67 | } | 70 | } |
68 | 71 | ||
69 | checkEntity(widgetType.getId(), widgetType, Resource.WIDGET_TYPE); | 72 | checkEntity(widgetType.getId(), widgetType, Resource.WIDGET_TYPE); |
73 | + WidgetType savedWidgetType = widgetTypeService.saveWidgetType(widgetType); | ||
70 | 74 | ||
71 | - return checkNotNull(widgetTypeService.saveWidgetType(widgetType)); | 75 | + sendNotificationMsgToEdgeService(getTenantId(), savedWidgetType.getId(), widgetType.getId() == null ? ActionType.ADDED : ActionType.UPDATED); |
76 | + | ||
77 | + return checkNotNull(savedWidgetType); | ||
72 | } catch (Exception e) { | 78 | } catch (Exception e) { |
73 | throw handleException(e); | 79 | throw handleException(e); |
74 | } | 80 | } |
@@ -83,6 +89,9 @@ public class WidgetTypeController extends BaseController { | @@ -83,6 +89,9 @@ public class WidgetTypeController extends BaseController { | ||
83 | WidgetTypeId widgetTypeId = new WidgetTypeId(toUUID(strWidgetTypeId)); | 89 | WidgetTypeId widgetTypeId = new WidgetTypeId(toUUID(strWidgetTypeId)); |
84 | checkWidgetTypeId(widgetTypeId, Operation.DELETE); | 90 | checkWidgetTypeId(widgetTypeId, Operation.DELETE); |
85 | widgetTypeService.deleteWidgetType(getCurrentUser().getTenantId(), widgetTypeId); | 91 | widgetTypeService.deleteWidgetType(getCurrentUser().getTenantId(), widgetTypeId); |
92 | + | ||
93 | + sendNotificationMsgToEdgeService(getTenantId(), widgetTypeId, ActionType.DELETED); | ||
94 | + | ||
86 | } catch (Exception e) { | 95 | } catch (Exception e) { |
87 | throw handleException(e); | 96 | throw handleException(e); |
88 | } | 97 | } |
@@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestParam; | @@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestParam; | ||
25 | import org.springframework.web.bind.annotation.ResponseBody; | 25 | import org.springframework.web.bind.annotation.ResponseBody; |
26 | import org.springframework.web.bind.annotation.ResponseStatus; | 26 | import org.springframework.web.bind.annotation.ResponseStatus; |
27 | import org.springframework.web.bind.annotation.RestController; | 27 | import org.springframework.web.bind.annotation.RestController; |
28 | +import org.thingsboard.server.common.data.audit.ActionType; | ||
28 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 29 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
29 | import org.thingsboard.server.common.data.id.TenantId; | 30 | import org.thingsboard.server.common.data.id.TenantId; |
30 | import org.thingsboard.server.common.data.id.WidgetsBundleId; | 31 | import org.thingsboard.server.common.data.id.WidgetsBundleId; |
@@ -68,7 +69,11 @@ public class WidgetsBundleController extends BaseController { | @@ -68,7 +69,11 @@ public class WidgetsBundleController extends BaseController { | ||
68 | } | 69 | } |
69 | 70 | ||
70 | checkEntity(widgetsBundle.getId(), widgetsBundle, Resource.WIDGETS_BUNDLE); | 71 | checkEntity(widgetsBundle.getId(), widgetsBundle, Resource.WIDGETS_BUNDLE); |
71 | - return checkNotNull(widgetsBundleService.saveWidgetsBundle(widgetsBundle)); | 72 | + WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); |
73 | + | ||
74 | + sendNotificationMsgToEdgeService(getTenantId(), savedWidgetsBundle.getId(), widgetsBundle.getId() == null ? ActionType.ADDED : ActionType.UPDATED); | ||
75 | + | ||
76 | + return checkNotNull(savedWidgetsBundle); | ||
72 | } catch (Exception e) { | 77 | } catch (Exception e) { |
73 | throw handleException(e); | 78 | throw handleException(e); |
74 | } | 79 | } |
@@ -83,6 +88,9 @@ public class WidgetsBundleController extends BaseController { | @@ -83,6 +88,9 @@ public class WidgetsBundleController extends BaseController { | ||
83 | WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); | 88 | WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); |
84 | checkWidgetsBundleId(widgetsBundleId, Operation.DELETE); | 89 | checkWidgetsBundleId(widgetsBundleId, Operation.DELETE); |
85 | widgetsBundleService.deleteWidgetsBundle(getTenantId(), widgetsBundleId); | 90 | widgetsBundleService.deleteWidgetsBundle(getTenantId(), widgetsBundleId); |
91 | + | ||
92 | + sendNotificationMsgToEdgeService(getTenantId(), widgetsBundleId, ActionType.DELETED); | ||
93 | + | ||
86 | } catch (Exception e) { | 94 | } catch (Exception e) { |
87 | throw handleException(e); | 95 | throw handleException(e); |
88 | } | 96 | } |
@@ -157,6 +157,8 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { | @@ -157,6 +157,8 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { | ||
157 | case ENTITY_VIEW: | 157 | case ENTITY_VIEW: |
158 | case DASHBOARD: | 158 | case DASHBOARD: |
159 | case RULE_CHAIN: | 159 | case RULE_CHAIN: |
160 | + case WIDGETS_BUNDLE: | ||
161 | + case WIDGET_TYPE: | ||
160 | processEntity(tenantId, edgeNotificationMsg); | 162 | processEntity(tenantId, edgeNotificationMsg); |
161 | break; | 163 | break; |
162 | case ALARM: | 164 | case ALARM: |
@@ -182,23 +184,32 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { | @@ -182,23 +184,32 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { | ||
182 | EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(edgeEventType, new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); | 184 | EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(edgeEventType, new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); |
183 | switch (edgeEventActionType) { | 185 | switch (edgeEventActionType) { |
184 | // TODO: voba - ADDED is not required for CE version ? | 186 | // TODO: voba - ADDED is not required for CE version ? |
185 | - // case ADDED: | 187 | + case ADDED: |
186 | case UPDATED: | 188 | case UPDATED: |
187 | case CREDENTIALS_UPDATED: | 189 | case CREDENTIALS_UPDATED: |
188 | - ListenableFuture<List<EdgeId>> edgeIdsFuture = findRelatedEdgeIdsByEntityId(tenantId, entityId); | ||
189 | - Futures.transform(edgeIdsFuture, edgeIds -> { | ||
190 | - if (edgeIds != null && !edgeIds.isEmpty()) { | ||
191 | - for (EdgeId edgeId : edgeIds) { | ||
192 | - try { | ||
193 | - saveEdgeEvent(tenantId, edgeId, edgeEventType, edgeEventActionType, entityId, null); | ||
194 | - } catch (Exception e) { | ||
195 | - log.error("[{}] Failed to push event to edge, edgeId [{}], edgeEventType [{}], edgeEventActionType [{}], entityId [{}]", | ||
196 | - tenantId, edgeId, edgeEventType, edgeEventActionType, entityId, e); | ||
197 | - } | 190 | + if (edgeEventType.equals(EdgeEventType.WIDGETS_BUNDLE) || edgeEventType.equals(EdgeEventType.WIDGET_TYPE)) { |
191 | + TextPageData<Edge> edgesByTenantId = edgeService.findEdgesByTenantId(tenantId, new TextPageLink(Integer.MAX_VALUE)); | ||
192 | + if (edgesByTenantId != null && edgesByTenantId.getData() != null && !edgesByTenantId.getData().isEmpty()) { | ||
193 | + for (Edge edge : edgesByTenantId.getData()) { | ||
194 | + saveEdgeEvent(tenantId, edge.getId(), edgeEventType, edgeEventActionType, entityId, null); | ||
198 | } | 195 | } |
199 | } | 196 | } |
200 | - return null; | ||
201 | - }, dbCallbackExecutorService); | 197 | + } else { |
198 | + ListenableFuture<List<EdgeId>> edgeIdsFuture = findRelatedEdgeIdsByEntityId(tenantId, entityId); | ||
199 | + Futures.transform(edgeIdsFuture, edgeIds -> { | ||
200 | + if (edgeIds != null && !edgeIds.isEmpty()) { | ||
201 | + for (EdgeId edgeId : edgeIds) { | ||
202 | + try { | ||
203 | + saveEdgeEvent(tenantId, edgeId, edgeEventType, edgeEventActionType, entityId, null); | ||
204 | + } catch (Exception e) { | ||
205 | + log.error("[{}] Failed to push event to edge, edgeId [{}], edgeEventType [{}], edgeEventActionType [{}], entityId [{}]", | ||
206 | + tenantId, edgeId, edgeEventType, edgeEventActionType, entityId, e); | ||
207 | + } | ||
208 | + } | ||
209 | + } | ||
210 | + return null; | ||
211 | + }, dbCallbackExecutorService); | ||
212 | + } | ||
202 | break; | 213 | break; |
203 | case DELETED: | 214 | case DELETED: |
204 | TextPageData<Edge> edgesByTenantId = edgeService.findEdgesByTenantId(tenantId, new TextPageLink(Integer.MAX_VALUE)); | 215 | TextPageData<Edge> edgesByTenantId = edgeService.findEdgesByTenantId(tenantId, new TextPageLink(Integer.MAX_VALUE)); |
@@ -33,6 +33,8 @@ import org.thingsboard.server.dao.entityview.EntityViewService; | @@ -33,6 +33,8 @@ import org.thingsboard.server.dao.entityview.EntityViewService; | ||
33 | import org.thingsboard.server.dao.relation.RelationService; | 33 | import org.thingsboard.server.dao.relation.RelationService; |
34 | import org.thingsboard.server.dao.rule.RuleChainService; | 34 | import org.thingsboard.server.dao.rule.RuleChainService; |
35 | import org.thingsboard.server.dao.user.UserService; | 35 | import org.thingsboard.server.dao.user.UserService; |
36 | +import org.thingsboard.server.dao.widget.WidgetTypeService; | ||
37 | +import org.thingsboard.server.dao.widget.WidgetsBundleService; | ||
36 | import org.thingsboard.server.queue.discovery.PartitionService; | 38 | import org.thingsboard.server.queue.discovery.PartitionService; |
37 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; | 39 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; |
38 | import org.thingsboard.server.queue.util.TbCoreComponent; | 40 | import org.thingsboard.server.queue.util.TbCoreComponent; |
@@ -46,6 +48,8 @@ import org.thingsboard.server.service.edge.rpc.constructor.EntityViewUpdateMsgCo | @@ -46,6 +48,8 @@ import org.thingsboard.server.service.edge.rpc.constructor.EntityViewUpdateMsgCo | ||
46 | import org.thingsboard.server.service.edge.rpc.constructor.RelationUpdateMsgConstructor; | 48 | import org.thingsboard.server.service.edge.rpc.constructor.RelationUpdateMsgConstructor; |
47 | import org.thingsboard.server.service.edge.rpc.constructor.RuleChainUpdateMsgConstructor; | 49 | import org.thingsboard.server.service.edge.rpc.constructor.RuleChainUpdateMsgConstructor; |
48 | import org.thingsboard.server.service.edge.rpc.constructor.UserUpdateMsgConstructor; | 50 | import org.thingsboard.server.service.edge.rpc.constructor.UserUpdateMsgConstructor; |
51 | +import org.thingsboard.server.service.edge.rpc.constructor.WidgetTypeUpdateMsgConstructor; | ||
52 | +import org.thingsboard.server.service.edge.rpc.constructor.WidgetsBundleUpdateMsgConstructor; | ||
49 | import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService; | 53 | import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService; |
50 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; | 54 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; |
51 | import org.thingsboard.server.service.queue.TbClusterService; | 55 | import org.thingsboard.server.service.queue.TbClusterService; |
@@ -121,6 +125,14 @@ public class EdgeContextComponent { | @@ -121,6 +125,14 @@ public class EdgeContextComponent { | ||
121 | 125 | ||
122 | @Lazy | 126 | @Lazy |
123 | @Autowired | 127 | @Autowired |
128 | + private WidgetsBundleService widgetsBundleService; | ||
129 | + | ||
130 | + @Lazy | ||
131 | + @Autowired | ||
132 | + private WidgetTypeService widgetTypeService; | ||
133 | + | ||
134 | + @Lazy | ||
135 | + @Autowired | ||
124 | private DeviceStateService deviceStateService; | 136 | private DeviceStateService deviceStateService; |
125 | 137 | ||
126 | @Lazy | 138 | @Lazy |
@@ -165,6 +177,14 @@ public class EdgeContextComponent { | @@ -165,6 +177,14 @@ public class EdgeContextComponent { | ||
165 | 177 | ||
166 | @Lazy | 178 | @Lazy |
167 | @Autowired | 179 | @Autowired |
180 | + private WidgetsBundleUpdateMsgConstructor widgetsBundleUpdateMsgConstructor; | ||
181 | + | ||
182 | + @Lazy | ||
183 | + @Autowired | ||
184 | + private WidgetTypeUpdateMsgConstructor widgetTypeUpdateMsgConstructor; | ||
185 | + | ||
186 | + @Lazy | ||
187 | + @Autowired | ||
168 | private EntityDataMsgConstructor entityDataMsgConstructor; | 188 | private EntityDataMsgConstructor entityDataMsgConstructor; |
169 | 189 | ||
170 | @Lazy | 190 | @Lazy |
@@ -54,6 +54,8 @@ import org.thingsboard.server.common.data.id.EntityViewId; | @@ -54,6 +54,8 @@ import org.thingsboard.server.common.data.id.EntityViewId; | ||
54 | import org.thingsboard.server.common.data.id.RuleChainId; | 54 | import org.thingsboard.server.common.data.id.RuleChainId; |
55 | import org.thingsboard.server.common.data.id.TenantId; | 55 | import org.thingsboard.server.common.data.id.TenantId; |
56 | import org.thingsboard.server.common.data.id.UserId; | 56 | import org.thingsboard.server.common.data.id.UserId; |
57 | +import org.thingsboard.server.common.data.id.WidgetTypeId; | ||
58 | +import org.thingsboard.server.common.data.id.WidgetsBundleId; | ||
57 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; | 59 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
58 | import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; | 60 | import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
59 | import org.thingsboard.server.common.data.kv.LongDataEntry; | 61 | import org.thingsboard.server.common.data.kv.LongDataEntry; |
@@ -66,6 +68,8 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; | @@ -66,6 +68,8 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; | ||
66 | import org.thingsboard.server.common.data.security.DeviceCredentials; | 68 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
67 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; | 69 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; |
68 | import org.thingsboard.server.common.data.security.UserCredentials; | 70 | import org.thingsboard.server.common.data.security.UserCredentials; |
71 | +import org.thingsboard.server.common.data.widget.WidgetType; | ||
72 | +import org.thingsboard.server.common.data.widget.WidgetsBundle; | ||
69 | import org.thingsboard.server.common.msg.TbMsg; | 73 | import org.thingsboard.server.common.msg.TbMsg; |
70 | import org.thingsboard.server.common.msg.TbMsgMetaData; | 74 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
71 | import org.thingsboard.server.common.msg.queue.ServiceType; | 75 | import org.thingsboard.server.common.msg.queue.ServiceType; |
@@ -99,6 +103,8 @@ import org.thingsboard.server.gen.edge.UplinkMsg; | @@ -99,6 +103,8 @@ import org.thingsboard.server.gen.edge.UplinkMsg; | ||
99 | import org.thingsboard.server.gen.edge.UplinkResponseMsg; | 103 | import org.thingsboard.server.gen.edge.UplinkResponseMsg; |
100 | import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; | 104 | import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; |
101 | import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; | 105 | import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; |
106 | +import org.thingsboard.server.gen.edge.WidgetTypeUpdateMsg; | ||
107 | +import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; | ||
102 | import org.thingsboard.server.gen.transport.TransportProtos; | 108 | import org.thingsboard.server.gen.transport.TransportProtos; |
103 | import org.thingsboard.server.queue.TbQueueCallback; | 109 | import org.thingsboard.server.queue.TbQueueCallback; |
104 | import org.thingsboard.server.queue.TbQueueMsgMetadata; | 110 | import org.thingsboard.server.queue.TbQueueMsgMetadata; |
@@ -355,6 +361,12 @@ public final class EdgeGrpcSession implements Closeable { | @@ -355,6 +361,12 @@ public final class EdgeGrpcSession implements Closeable { | ||
355 | case RELATION: | 361 | case RELATION: |
356 | processRelation(edgeEvent, msgType); | 362 | processRelation(edgeEvent, msgType); |
357 | break; | 363 | break; |
364 | + case WIDGETS_BUNDLE: | ||
365 | + processWidgetsBundle(edgeEvent, msgType, edgeEventAction); | ||
366 | + break; | ||
367 | + case WIDGET_TYPE: | ||
368 | + processWidgetType(edgeEvent, msgType, edgeEventAction); | ||
369 | + break; | ||
358 | } | 370 | } |
359 | } | 371 | } |
360 | 372 | ||
@@ -608,6 +620,66 @@ public final class EdgeGrpcSession implements Closeable { | @@ -608,6 +620,66 @@ public final class EdgeGrpcSession implements Closeable { | ||
608 | } | 620 | } |
609 | } | 621 | } |
610 | 622 | ||
623 | + private void processWidgetsBundle(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) { | ||
624 | + WidgetsBundleId widgetsBundleId = new WidgetsBundleId(edgeEvent.getEntityId()); | ||
625 | + EntityUpdateMsg entityUpdateMsg = null; | ||
626 | + switch (edgeActionType) { | ||
627 | + case ADDED: | ||
628 | + case UPDATED: | ||
629 | + WidgetsBundle widgetsBundle = ctx.getWidgetsBundleService().findWidgetsBundleById(edgeEvent.getTenantId(), widgetsBundleId); | ||
630 | + if (widgetsBundle != null) { | ||
631 | + WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = | ||
632 | + ctx.getWidgetsBundleUpdateMsgConstructor().constructWidgetsBundleUpdateMsg(msgType, widgetsBundle); | ||
633 | + entityUpdateMsg = EntityUpdateMsg.newBuilder() | ||
634 | + .setWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg) | ||
635 | + .build(); | ||
636 | + } | ||
637 | + break; | ||
638 | + case DELETED: | ||
639 | + WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = | ||
640 | + ctx.getWidgetsBundleUpdateMsgConstructor().constructWidgetsBundleDeleteMsg(widgetsBundleId); | ||
641 | + entityUpdateMsg = EntityUpdateMsg.newBuilder() | ||
642 | + .setWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg) | ||
643 | + .build(); | ||
644 | + break; | ||
645 | + } | ||
646 | + if (entityUpdateMsg != null) { | ||
647 | + outputStream.onNext(ResponseMsg.newBuilder() | ||
648 | + .setEntityUpdateMsg(entityUpdateMsg) | ||
649 | + .build()); | ||
650 | + } | ||
651 | + } | ||
652 | + | ||
653 | + private void processWidgetType(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) { | ||
654 | + WidgetTypeId widgetTypeId = new WidgetTypeId(edgeEvent.getEntityId()); | ||
655 | + EntityUpdateMsg entityUpdateMsg = null; | ||
656 | + switch (edgeActionType) { | ||
657 | + case ADDED: | ||
658 | + case UPDATED: | ||
659 | + WidgetType widgetType = ctx.getWidgetTypeService().findWidgetTypeById(edgeEvent.getTenantId(), widgetTypeId); | ||
660 | + if (widgetType != null) { | ||
661 | + WidgetTypeUpdateMsg widgetTypeUpdateMsg = | ||
662 | + ctx.getWidgetTypeUpdateMsgConstructor().constructWidgetTypeUpdateMsg(msgType, widgetType); | ||
663 | + entityUpdateMsg = EntityUpdateMsg.newBuilder() | ||
664 | + .setWidgetTypeUpdateMsg(widgetTypeUpdateMsg) | ||
665 | + .build(); | ||
666 | + } | ||
667 | + break; | ||
668 | + case DELETED: | ||
669 | + WidgetTypeUpdateMsg widgetTypeUpdateMsg = | ||
670 | + ctx.getWidgetTypeUpdateMsgConstructor().constructWidgetTypeDeleteMsg(widgetTypeId); | ||
671 | + entityUpdateMsg = EntityUpdateMsg.newBuilder() | ||
672 | + .setWidgetTypeUpdateMsg(widgetTypeUpdateMsg) | ||
673 | + .build(); | ||
674 | + break; | ||
675 | + } | ||
676 | + if (entityUpdateMsg != null) { | ||
677 | + outputStream.onNext(ResponseMsg.newBuilder() | ||
678 | + .setEntityUpdateMsg(entityUpdateMsg) | ||
679 | + .build()); | ||
680 | + } | ||
681 | + } | ||
682 | + | ||
611 | private UpdateMsgType getResponseMsgType(ActionType actionType) { | 683 | private UpdateMsgType getResponseMsgType(ActionType actionType) { |
612 | switch (actionType) { | 684 | switch (actionType) { |
613 | case UPDATED: | 685 | case UPDATED: |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.edge.rpc.constructor; | ||
17 | + | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
19 | +import org.springframework.stereotype.Component; | ||
20 | +import org.thingsboard.server.common.data.id.TenantId; | ||
21 | +import org.thingsboard.server.common.data.id.WidgetTypeId; | ||
22 | +import org.thingsboard.server.common.data.widget.WidgetType; | ||
23 | +import org.thingsboard.server.dao.util.mapping.JacksonUtil; | ||
24 | +import org.thingsboard.server.gen.edge.UpdateMsgType; | ||
25 | +import org.thingsboard.server.gen.edge.WidgetTypeUpdateMsg; | ||
26 | + | ||
27 | +@Component | ||
28 | +@Slf4j | ||
29 | +public class WidgetTypeUpdateMsgConstructor { | ||
30 | + | ||
31 | + public WidgetTypeUpdateMsg constructWidgetTypeUpdateMsg(UpdateMsgType msgType, WidgetType widgetType) { | ||
32 | + WidgetTypeUpdateMsg.Builder builder = WidgetTypeUpdateMsg.newBuilder() | ||
33 | + .setMsgType(msgType) | ||
34 | + .setIdMSB(widgetType.getId().getId().getMostSignificantBits()) | ||
35 | + .setIdLSB(widgetType.getId().getId().getLeastSignificantBits()); | ||
36 | + if (widgetType.getBundleAlias() != null) { | ||
37 | + builder.setBundleAlias(widgetType.getBundleAlias()); | ||
38 | + } | ||
39 | + if (widgetType.getAlias() != null) { | ||
40 | + builder.setAlias(widgetType.getAlias()); | ||
41 | + } | ||
42 | + if (widgetType.getName() != null) { | ||
43 | + builder.setName(widgetType.getName()); | ||
44 | + } | ||
45 | + if (widgetType.getDescriptor() != null) { | ||
46 | + builder.setDescriptorJson(JacksonUtil.toString(widgetType.getDescriptor())); | ||
47 | + } | ||
48 | + if (widgetType.getTenantId().equals(TenantId.SYS_TENANT_ID)) { | ||
49 | + builder.setIsSystem(true); | ||
50 | + } | ||
51 | + return builder.build(); | ||
52 | + } | ||
53 | + | ||
54 | + public WidgetTypeUpdateMsg constructWidgetTypeDeleteMsg(WidgetTypeId widgetTypeId) { | ||
55 | + return WidgetTypeUpdateMsg.newBuilder() | ||
56 | + .setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE) | ||
57 | + .setIdMSB(widgetTypeId.getId().getMostSignificantBits()) | ||
58 | + .setIdLSB(widgetTypeId.getId().getLeastSignificantBits()) | ||
59 | + .build(); | ||
60 | + } | ||
61 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.edge.rpc.constructor; | ||
17 | + | ||
18 | +import com.google.protobuf.ByteString; | ||
19 | +import lombok.extern.slf4j.Slf4j; | ||
20 | +import org.springframework.stereotype.Component; | ||
21 | +import org.thingsboard.server.common.data.id.TenantId; | ||
22 | +import org.thingsboard.server.common.data.id.WidgetsBundleId; | ||
23 | +import org.thingsboard.server.common.data.widget.WidgetsBundle; | ||
24 | +import org.thingsboard.server.gen.edge.UpdateMsgType; | ||
25 | +import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; | ||
26 | + | ||
27 | +@Component | ||
28 | +@Slf4j | ||
29 | +public class WidgetsBundleUpdateMsgConstructor { | ||
30 | + | ||
31 | + public WidgetsBundleUpdateMsg constructWidgetsBundleUpdateMsg(UpdateMsgType msgType, WidgetsBundle widgetsBundle) { | ||
32 | + WidgetsBundleUpdateMsg.Builder builder = WidgetsBundleUpdateMsg.newBuilder() | ||
33 | + .setMsgType(msgType) | ||
34 | + .setIdMSB(widgetsBundle.getId().getId().getMostSignificantBits()) | ||
35 | + .setIdLSB(widgetsBundle.getId().getId().getLeastSignificantBits()) | ||
36 | + .setTitle(widgetsBundle.getTitle()) | ||
37 | + .setAlias(widgetsBundle.getAlias()); | ||
38 | + if (widgetsBundle.getImage() != null) { | ||
39 | + builder.setImage(ByteString.copyFrom(widgetsBundle.getImage())); | ||
40 | + } | ||
41 | + if (widgetsBundle.getTenantId().equals(TenantId.SYS_TENANT_ID)) { | ||
42 | + builder.setIsSystem(true); | ||
43 | + } | ||
44 | + return builder.build(); | ||
45 | + } | ||
46 | + | ||
47 | + public WidgetsBundleUpdateMsg constructWidgetsBundleDeleteMsg(WidgetsBundleId widgetsBundleId) { | ||
48 | + return WidgetsBundleUpdateMsg.newBuilder() | ||
49 | + .setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE) | ||
50 | + .setIdMSB(widgetsBundleId.getId().getMostSignificantBits()) | ||
51 | + .setIdLSB(widgetsBundleId.getId().getLeastSignificantBits()) | ||
52 | + .build(); | ||
53 | + } | ||
54 | +} |
@@ -54,6 +54,8 @@ import org.thingsboard.server.common.data.relation.EntityRelationsQuery; | @@ -54,6 +54,8 @@ import org.thingsboard.server.common.data.relation.EntityRelationsQuery; | ||
54 | import org.thingsboard.server.common.data.relation.EntitySearchDirection; | 54 | import org.thingsboard.server.common.data.relation.EntitySearchDirection; |
55 | import org.thingsboard.server.common.data.relation.RelationsSearchParameters; | 55 | import org.thingsboard.server.common.data.relation.RelationsSearchParameters; |
56 | import org.thingsboard.server.common.data.rule.RuleChain; | 56 | import org.thingsboard.server.common.data.rule.RuleChain; |
57 | +import org.thingsboard.server.common.data.widget.WidgetType; | ||
58 | +import org.thingsboard.server.common.data.widget.WidgetsBundle; | ||
57 | import org.thingsboard.server.dao.asset.AssetService; | 59 | import org.thingsboard.server.dao.asset.AssetService; |
58 | import org.thingsboard.server.dao.attributes.AttributesService; | 60 | import org.thingsboard.server.dao.attributes.AttributesService; |
59 | import org.thingsboard.server.dao.dashboard.DashboardService; | 61 | import org.thingsboard.server.dao.dashboard.DashboardService; |
@@ -63,6 +65,8 @@ import org.thingsboard.server.dao.entityview.EntityViewService; | @@ -63,6 +65,8 @@ import org.thingsboard.server.dao.entityview.EntityViewService; | ||
63 | import org.thingsboard.server.dao.relation.RelationService; | 65 | import org.thingsboard.server.dao.relation.RelationService; |
64 | import org.thingsboard.server.dao.rule.RuleChainService; | 66 | import org.thingsboard.server.dao.rule.RuleChainService; |
65 | import org.thingsboard.server.dao.user.UserService; | 67 | import org.thingsboard.server.dao.user.UserService; |
68 | +import org.thingsboard.server.dao.widget.WidgetTypeService; | ||
69 | +import org.thingsboard.server.dao.widget.WidgetsBundleService; | ||
66 | import org.thingsboard.server.gen.edge.AttributesRequestMsg; | 70 | import org.thingsboard.server.gen.edge.AttributesRequestMsg; |
67 | import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; | 71 | import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; |
68 | import org.thingsboard.server.gen.edge.RelationRequestMsg; | 72 | import org.thingsboard.server.gen.edge.RelationRequestMsg; |
@@ -110,6 +114,12 @@ public class DefaultSyncEdgeService implements SyncEdgeService { | @@ -110,6 +114,12 @@ public class DefaultSyncEdgeService implements SyncEdgeService { | ||
110 | private UserService userService; | 114 | private UserService userService; |
111 | 115 | ||
112 | @Autowired | 116 | @Autowired |
117 | + private WidgetsBundleService widgetsBundleService; | ||
118 | + | ||
119 | + @Autowired | ||
120 | + private WidgetTypeService widgetTypeService; | ||
121 | + | ||
122 | + @Autowired | ||
113 | private DbCallbackExecutorService dbCallbackExecutorService; | 123 | private DbCallbackExecutorService dbCallbackExecutorService; |
114 | 124 | ||
115 | @Override | 125 | @Override |
@@ -121,6 +131,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService { | @@ -121,6 +131,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService { | ||
121 | syncAssets(edge); | 131 | syncAssets(edge); |
122 | syncEntityViews(edge); | 132 | syncEntityViews(edge); |
123 | syncDashboards(edge); | 133 | syncDashboards(edge); |
134 | + syncWidgetsBundleAndWidgetTypes(edge); | ||
124 | } catch (Exception e) { | 135 | } catch (Exception e) { |
125 | log.error("Exception during sync process", e); | 136 | log.error("Exception during sync process", e); |
126 | } | 137 | } |
@@ -261,6 +272,24 @@ public class DefaultSyncEdgeService implements SyncEdgeService { | @@ -261,6 +272,24 @@ public class DefaultSyncEdgeService implements SyncEdgeService { | ||
261 | } | 272 | } |
262 | } | 273 | } |
263 | 274 | ||
275 | + private void syncWidgetsBundleAndWidgetTypes(Edge edge) { | ||
276 | + List<WidgetsBundle> widgetsBundlesToPush = new ArrayList<>(); | ||
277 | + List<WidgetType> widgetTypesToPush = new ArrayList<>(); | ||
278 | + widgetsBundlesToPush.addAll(widgetsBundleService.findAllTenantWidgetsBundlesByTenantId(edge.getTenantId())); | ||
279 | + widgetsBundlesToPush.addAll(widgetsBundleService.findSystemWidgetsBundles(edge.getTenantId())); | ||
280 | + try { | ||
281 | + for (WidgetsBundle widgetsBundle: widgetsBundlesToPush) { | ||
282 | + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.WIDGETS_BUNDLE, ActionType.ADDED, widgetsBundle.getId(), null); | ||
283 | + widgetTypesToPush.addAll(widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(widgetsBundle.getTenantId(), widgetsBundle.getAlias())); | ||
284 | + } | ||
285 | + for (WidgetType widgetType: widgetTypesToPush) { | ||
286 | + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.WIDGET_TYPE, ActionType.ADDED, widgetType.getId(), null); | ||
287 | + } | ||
288 | + } catch (Exception e) { | ||
289 | + log.error("Exception during loading widgets bundle(s) and widget type(s) on sync!", e); | ||
290 | + } | ||
291 | + } | ||
292 | + | ||
264 | private void pushUsersToEdge(TextPageData<User> pageData, Edge edge) { | 293 | private void pushUsersToEdge(TextPageData<User> pageData, Edge edge) { |
265 | if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { | 294 | if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { |
266 | log.trace("[{}] [{}] user(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); | 295 | log.trace("[{}] [{}] user(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); |
@@ -16,9 +16,6 @@ | @@ -16,9 +16,6 @@ | ||
16 | package org.thingsboard.server.common.data; | 16 | package org.thingsboard.server.common.data; |
17 | 17 | ||
18 | import org.thingsboard.server.common.data.edge.EdgeEventType; | 18 | import org.thingsboard.server.common.data.edge.EdgeEventType; |
19 | -import org.thingsboard.server.common.data.id.EdgeId; | ||
20 | - | ||
21 | -import java.util.Set; | ||
22 | 19 | ||
23 | public final class EdgeUtils { | 20 | public final class EdgeUtils { |
24 | 21 | ||
@@ -43,6 +40,10 @@ public final class EdgeUtils { | @@ -43,6 +40,10 @@ public final class EdgeUtils { | ||
43 | return EdgeEventType.TENANT; | 40 | return EdgeEventType.TENANT; |
44 | case CUSTOMER: | 41 | case CUSTOMER: |
45 | return EdgeEventType.CUSTOMER; | 42 | return EdgeEventType.CUSTOMER; |
43 | + case WIDGETS_BUNDLE: | ||
44 | + return EdgeEventType.WIDGETS_BUNDLE; | ||
45 | + case WIDGET_TYPE: | ||
46 | + return EdgeEventType.WIDGET_TYPE; | ||
46 | default: | 47 | default: |
47 | return null; | 48 | return null; |
48 | } | 49 | } |
@@ -87,6 +87,10 @@ public class EntityIdFactory { | @@ -87,6 +87,10 @@ public class EntityIdFactory { | ||
87 | return new RuleChainId(uuid); | 87 | return new RuleChainId(uuid); |
88 | case ENTITY_VIEW: | 88 | case ENTITY_VIEW: |
89 | return new EntityViewId(uuid); | 89 | return new EntityViewId(uuid); |
90 | + case WIDGETS_BUNDLE: | ||
91 | + return new WidgetsBundleId(uuid); | ||
92 | + case WIDGET_TYPE: | ||
93 | + return new WidgetTypeId(uuid); | ||
90 | case EDGE: | 94 | case EDGE: |
91 | return new EdgeId(uuid); | 95 | return new EdgeId(uuid); |
92 | } | 96 | } |
@@ -59,6 +59,8 @@ message EntityUpdateMsg { | @@ -59,6 +59,8 @@ message EntityUpdateMsg { | ||
59 | UserCredentialsUpdateMsg userCredentialsUpdateMsg = 10; | 59 | UserCredentialsUpdateMsg userCredentialsUpdateMsg = 10; |
60 | CustomerUpdateMsg customerUpdateMsg = 11; | 60 | CustomerUpdateMsg customerUpdateMsg = 11; |
61 | RelationUpdateMsg relationUpdateMsg = 12; | 61 | RelationUpdateMsg relationUpdateMsg = 12; |
62 | + WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = 13; | ||
63 | + WidgetTypeUpdateMsg widgetTypeUpdateMsg = 14; | ||
62 | } | 64 | } |
63 | 65 | ||
64 | enum RequestMsgType { | 66 | enum RequestMsgType { |
@@ -266,6 +268,27 @@ message UserUpdateMsg { | @@ -266,6 +268,27 @@ message UserUpdateMsg { | ||
266 | string additionalInfo = 8; | 268 | string additionalInfo = 8; |
267 | } | 269 | } |
268 | 270 | ||
271 | +message WidgetsBundleUpdateMsg { | ||
272 | + UpdateMsgType msgType = 1; | ||
273 | + int64 idMSB = 2; | ||
274 | + int64 idLSB = 3; | ||
275 | + string title = 4; | ||
276 | + string alias = 5; | ||
277 | + bytes image = 6; | ||
278 | + bool isSystem = 7; | ||
279 | +} | ||
280 | + | ||
281 | +message WidgetTypeUpdateMsg { | ||
282 | + UpdateMsgType msgType = 1; | ||
283 | + int64 idMSB = 2; | ||
284 | + int64 idLSB = 3; | ||
285 | + string bundleAlias = 4; | ||
286 | + string alias = 5; | ||
287 | + string name = 6; | ||
288 | + string descriptorJson = 7; | ||
289 | + bool isSystem = 8; | ||
290 | +} | ||
291 | + | ||
269 | message UserCredentialsUpdateMsg { | 292 | message UserCredentialsUpdateMsg { |
270 | int64 userIdMSB = 1; | 293 | int64 userIdMSB = 1; |
271 | int64 userIdLSB = 2; | 294 | int64 userIdLSB = 2; |