Showing
9 changed files
with
143 additions
and
26 deletions
... | ... | @@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestParam; |
25 | 25 | import org.springframework.web.bind.annotation.ResponseBody; |
26 | 26 | import org.springframework.web.bind.annotation.ResponseStatus; |
27 | 27 | import org.springframework.web.bind.annotation.RestController; |
28 | +import org.thingsboard.server.common.data.audit.ActionType; | |
28 | 29 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
29 | 30 | import org.thingsboard.server.common.data.id.TenantId; |
30 | 31 | import org.thingsboard.server.common.data.id.WidgetsBundleId; |
... | ... | @@ -68,7 +69,11 @@ public class WidgetsBundleController extends BaseController { |
68 | 69 | } |
69 | 70 | |
70 | 71 | checkEntity(widgetsBundle.getId(), widgetsBundle, Resource.WIDGETS_BUNDLE); |
71 | - return checkNotNull(widgetsBundleService.saveWidgetsBundle(widgetsBundle)); | |
72 | + WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); | |
73 | + | |
74 | + sendNotificationMsgToEdgeService(savedWidgetsBundle.getTenantId(), savedWidgetsBundle.getId(), ActionType.UPDATED); | |
75 | + | |
76 | + return checkNotNull(savedWidgetsBundle); | |
72 | 77 | } catch (Exception e) { |
73 | 78 | throw handleException(e); |
74 | 79 | } |
... | ... | @@ -83,6 +88,9 @@ public class WidgetsBundleController extends BaseController { |
83 | 88 | WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); |
84 | 89 | checkWidgetsBundleId(widgetsBundleId, Operation.DELETE); |
85 | 90 | widgetsBundleService.deleteWidgetsBundle(getTenantId(), widgetsBundleId); |
91 | + | |
92 | + sendNotificationMsgToEdgeService(getTenantId(), widgetsBundleId, ActionType.DELETED); | |
93 | + | |
86 | 94 | } catch (Exception e) { |
87 | 95 | throw handleException(e); |
88 | 96 | } | ... | ... |
... | ... | @@ -157,6 +157,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { |
157 | 157 | case ENTITY_VIEW: |
158 | 158 | case DASHBOARD: |
159 | 159 | case RULE_CHAIN: |
160 | + case WIDGETS_BUNDLE: | |
160 | 161 | processEntity(tenantId, edgeNotificationMsg); |
161 | 162 | break; |
162 | 163 | case ALARM: |
... | ... | @@ -185,20 +186,29 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { |
185 | 186 | // case ADDED: |
186 | 187 | case UPDATED: |
187 | 188 | 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 | - } | |
189 | + if (edgeEventType.equals(EdgeEventType.WIDGETS_BUNDLE)) { | |
190 | + TextPageData<Edge> edgesByTenantId = edgeService.findEdgesByTenantId(tenantId, new TextPageLink(Integer.MAX_VALUE)); | |
191 | + if (edgesByTenantId != null && edgesByTenantId.getData() != null && !edgesByTenantId.getData().isEmpty()) { | |
192 | + for (Edge edge : edgesByTenantId.getData()) { | |
193 | + saveEdgeEvent(tenantId, edge.getId(), edgeEventType, edgeEventActionType, entityId, null); | |
198 | 194 | } |
199 | 195 | } |
200 | - return null; | |
201 | - }, dbCallbackExecutorService); | |
196 | + } else { | |
197 | + ListenableFuture<List<EdgeId>> edgeIdsFuture = findRelatedEdgeIdsByEntityId(tenantId, entityId); | |
198 | + Futures.transform(edgeIdsFuture, edgeIds -> { | |
199 | + if (edgeIds != null && !edgeIds.isEmpty()) { | |
200 | + for (EdgeId edgeId : edgeIds) { | |
201 | + try { | |
202 | + saveEdgeEvent(tenantId, edgeId, edgeEventType, edgeEventActionType, entityId, null); | |
203 | + } catch (Exception e) { | |
204 | + log.error("[{}] Failed to push event to edge, edgeId [{}], edgeEventType [{}], edgeEventActionType [{}], entityId [{}]", | |
205 | + tenantId, edgeId, edgeEventType, edgeEventActionType, entityId, e); | |
206 | + } | |
207 | + } | |
208 | + } | |
209 | + return null; | |
210 | + }, dbCallbackExecutorService); | |
211 | + } | |
202 | 212 | break; |
203 | 213 | case DELETED: |
204 | 214 | TextPageData<Edge> edgesByTenantId = edgeService.findEdgesByTenantId(tenantId, new TextPageLink(Integer.MAX_VALUE)); | ... | ... |
... | ... | @@ -33,19 +33,12 @@ import org.thingsboard.server.dao.entityview.EntityViewService; |
33 | 33 | import org.thingsboard.server.dao.relation.RelationService; |
34 | 34 | import org.thingsboard.server.dao.rule.RuleChainService; |
35 | 35 | import org.thingsboard.server.dao.user.UserService; |
36 | +import org.thingsboard.server.dao.widget.WidgetsBundleService; | |
36 | 37 | import org.thingsboard.server.queue.discovery.PartitionService; |
37 | 38 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; |
38 | 39 | import org.thingsboard.server.queue.util.TbCoreComponent; |
39 | 40 | import org.thingsboard.server.service.edge.rpc.EdgeEventStorageSettings; |
40 | -import org.thingsboard.server.service.edge.rpc.constructor.AlarmUpdateMsgConstructor; | |
41 | -import org.thingsboard.server.service.edge.rpc.constructor.AssetUpdateMsgConstructor; | |
42 | -import org.thingsboard.server.service.edge.rpc.constructor.DashboardUpdateMsgConstructor; | |
43 | -import org.thingsboard.server.service.edge.rpc.constructor.DeviceUpdateMsgConstructor; | |
44 | -import org.thingsboard.server.service.edge.rpc.constructor.EntityDataMsgConstructor; | |
45 | -import org.thingsboard.server.service.edge.rpc.constructor.EntityViewUpdateMsgConstructor; | |
46 | -import org.thingsboard.server.service.edge.rpc.constructor.RelationUpdateMsgConstructor; | |
47 | -import org.thingsboard.server.service.edge.rpc.constructor.RuleChainUpdateMsgConstructor; | |
48 | -import org.thingsboard.server.service.edge.rpc.constructor.UserUpdateMsgConstructor; | |
41 | +import org.thingsboard.server.service.edge.rpc.constructor.*; | |
49 | 42 | import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService; |
50 | 43 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; |
51 | 44 | import org.thingsboard.server.service.queue.TbClusterService; |
... | ... | @@ -121,6 +114,10 @@ public class EdgeContextComponent { |
121 | 114 | |
122 | 115 | @Lazy |
123 | 116 | @Autowired |
117 | + private WidgetsBundleService widgetsBundleService; | |
118 | + | |
119 | + @Lazy | |
120 | + @Autowired | |
124 | 121 | private DeviceStateService deviceStateService; |
125 | 122 | |
126 | 123 | @Lazy |
... | ... | @@ -165,6 +162,10 @@ public class EdgeContextComponent { |
165 | 162 | |
166 | 163 | @Lazy |
167 | 164 | @Autowired |
165 | + private WidgetsBundleUpdateMsgConstructor widgetsBundleUpdateMsgConstructor; | |
166 | + | |
167 | + @Lazy | |
168 | + @Autowired | |
168 | 169 | private EntityDataMsgConstructor entityDataMsgConstructor; |
169 | 170 | |
170 | 171 | @Lazy | ... | ... |
... | ... | @@ -54,6 +54,7 @@ import org.thingsboard.server.common.data.id.EntityViewId; |
54 | 54 | import org.thingsboard.server.common.data.id.RuleChainId; |
55 | 55 | import org.thingsboard.server.common.data.id.TenantId; |
56 | 56 | import org.thingsboard.server.common.data.id.UserId; |
57 | +import org.thingsboard.server.common.data.id.WidgetsBundleId; | |
57 | 58 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
58 | 59 | import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
59 | 60 | import org.thingsboard.server.common.data.kv.LongDataEntry; |
... | ... | @@ -66,6 +67,7 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; |
66 | 67 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
67 | 68 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; |
68 | 69 | import org.thingsboard.server.common.data.security.UserCredentials; |
70 | +import org.thingsboard.server.common.data.widget.WidgetsBundle; | |
69 | 71 | import org.thingsboard.server.common.msg.TbMsg; |
70 | 72 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
71 | 73 | import org.thingsboard.server.common.msg.queue.ServiceType; |
... | ... | @@ -99,6 +101,7 @@ import org.thingsboard.server.gen.edge.UplinkMsg; |
99 | 101 | import org.thingsboard.server.gen.edge.UplinkResponseMsg; |
100 | 102 | import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; |
101 | 103 | import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; |
104 | +import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; | |
102 | 105 | import org.thingsboard.server.gen.transport.TransportProtos; |
103 | 106 | import org.thingsboard.server.queue.TbQueueCallback; |
104 | 107 | import org.thingsboard.server.queue.TbQueueMsgMetadata; |
... | ... | @@ -335,6 +338,9 @@ public final class EdgeGrpcSession implements Closeable { |
335 | 338 | case RELATION: |
336 | 339 | processRelation(edgeEvent, msgType); |
337 | 340 | break; |
341 | + case WIDGETS_BUNDLE: | |
342 | + processWidgetsBundle(edgeEvent, msgType, edgeEventAction); | |
343 | + break; | |
338 | 344 | } |
339 | 345 | } |
340 | 346 | |
... | ... | @@ -588,6 +594,36 @@ public final class EdgeGrpcSession implements Closeable { |
588 | 594 | } |
589 | 595 | } |
590 | 596 | |
597 | + private void processWidgetsBundle(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) { | |
598 | + WidgetsBundleId widgetsBundleId = new WidgetsBundleId(edgeEvent.getEntityId()); | |
599 | + EntityUpdateMsg entityUpdateMsg = null; | |
600 | + switch (edgeActionType) { | |
601 | + case ADDED: | |
602 | + case UPDATED: | |
603 | + WidgetsBundle widgetsBundle = ctx.getWidgetsBundleService().findWidgetsBundleById(edgeEvent.getTenantId(), widgetsBundleId); | |
604 | + if (widgetsBundle != null) { | |
605 | + WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = | |
606 | + ctx.getWidgetsBundleUpdateMsgConstructor().constructWidgetsBundleUpdateMsg(msgType, widgetsBundle); | |
607 | + entityUpdateMsg = EntityUpdateMsg.newBuilder() | |
608 | + .setWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg) | |
609 | + .build(); | |
610 | + } | |
611 | + break; | |
612 | + case DELETED: | |
613 | + WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = | |
614 | + ctx.getWidgetsBundleUpdateMsgConstructor().constructWidgetsBundleDeleteMsg(widgetsBundleId); | |
615 | + entityUpdateMsg = EntityUpdateMsg.newBuilder() | |
616 | + .setWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg) | |
617 | + .build(); | |
618 | + break; | |
619 | + } | |
620 | + if (entityUpdateMsg != null) { | |
621 | + outputStream.onNext(ResponseMsg.newBuilder() | |
622 | + .setEntityUpdateMsg(entityUpdateMsg) | |
623 | + .build()); | |
624 | + } | |
625 | + } | |
626 | + | |
591 | 627 | private UpdateMsgType getResponseMsgType(ActionType actionType) { |
592 | 628 | switch (actionType) { |
593 | 629 | 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 com.google.protobuf.ByteString; | |
19 | +import lombok.extern.slf4j.Slf4j; | |
20 | +import org.springframework.stereotype.Component; | |
21 | +import org.thingsboard.server.common.data.id.WidgetsBundleId; | |
22 | +import org.thingsboard.server.common.data.widget.WidgetsBundle; | |
23 | +import org.thingsboard.server.gen.edge.UpdateMsgType; | |
24 | +import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; | |
25 | + | |
26 | +@Component | |
27 | +@Slf4j | |
28 | +public class WidgetsBundleUpdateMsgConstructor { | |
29 | + | |
30 | + public WidgetsBundleUpdateMsg constructWidgetsBundleUpdateMsg(UpdateMsgType msgType, WidgetsBundle widgetsBundle) { | |
31 | + WidgetsBundleUpdateMsg.Builder builder = WidgetsBundleUpdateMsg.newBuilder() | |
32 | + .setMsgType(msgType) | |
33 | + .setIdMSB(widgetsBundle.getId().getId().getMostSignificantBits()) | |
34 | + .setIdLSB(widgetsBundle.getId().getId().getLeastSignificantBits()) | |
35 | + .setTitle(widgetsBundle.getTitle()) | |
36 | + .setAlias(widgetsBundle.getAlias()); | |
37 | + if (widgetsBundle.getImage() != null) { | |
38 | + builder.setImage(ByteString.copyFrom(widgetsBundle.getImage())); | |
39 | + } | |
40 | + return builder.build(); | |
41 | + } | |
42 | + | |
43 | + public WidgetsBundleUpdateMsg constructWidgetsBundleDeleteMsg(WidgetsBundleId widgetsBundleId) { | |
44 | + return WidgetsBundleUpdateMsg.newBuilder() | |
45 | + .setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE) | |
46 | + .setIdMSB(widgetsBundleId.getId().getMostSignificantBits()) | |
47 | + .setIdLSB(widgetsBundleId.getId().getLeastSignificantBits()) | |
48 | + .build(); | |
49 | + } | |
50 | +} | ... | ... |
... | ... | @@ -16,9 +16,6 @@ |
16 | 16 | package org.thingsboard.server.common.data; |
17 | 17 | |
18 | 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 | 20 | public final class EdgeUtils { |
24 | 21 | |
... | ... | @@ -39,6 +36,8 @@ public final class EdgeUtils { |
39 | 36 | return EdgeEventType.USER; |
40 | 37 | case ALARM: |
41 | 38 | return EdgeEventType.ALARM; |
39 | + case WIDGETS_BUNDLE: | |
40 | + return EdgeEventType.WIDGETS_BUNDLE; | |
42 | 41 | default: |
43 | 42 | return null; |
44 | 43 | } | ... | ... |
... | ... | @@ -59,6 +59,7 @@ message EntityUpdateMsg { |
59 | 59 | UserCredentialsUpdateMsg userCredentialsUpdateMsg = 10; |
60 | 60 | CustomerUpdateMsg customerUpdateMsg = 11; |
61 | 61 | RelationUpdateMsg relationUpdateMsg = 12; |
62 | + WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = 13; | |
62 | 63 | } |
63 | 64 | |
64 | 65 | enum RequestMsgType { |
... | ... | @@ -266,6 +267,15 @@ message UserUpdateMsg { |
266 | 267 | string additionalInfo = 8; |
267 | 268 | } |
268 | 269 | |
270 | +message WidgetsBundleUpdateMsg { | |
271 | + UpdateMsgType msgType = 1; | |
272 | + int64 idMSB = 2; | |
273 | + int64 idLSB = 3; | |
274 | + string title = 4; | |
275 | + string alias = 5; | |
276 | + bytes image = 6; | |
277 | +} | |
278 | + | |
269 | 279 | message UserCredentialsUpdateMsg { |
270 | 280 | int64 userIdMSB = 1; |
271 | 281 | int64 userIdLSB = 2; | ... | ... |