Commit 5af7eb822140f526aeaea8f1580288ec4ccc2496

Authored by Bohdan Smetaniuk
1 parent d34c54b3

WidgetsBundles fetch feature

@@ -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(savedWidgetsBundle.getTenantId(), savedWidgetsBundle.getId(), 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,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { @@ -157,6 +157,7 @@ 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:
160 processEntity(tenantId, edgeNotificationMsg); 161 processEntity(tenantId, edgeNotificationMsg);
161 break; 162 break;
162 case ALARM: 163 case ALARM:
@@ -185,20 +186,29 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { @@ -185,20 +186,29 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
185 // case ADDED: 186 // case ADDED:
186 case UPDATED: 187 case UPDATED:
187 case CREDENTIALS_UPDATED: 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 break; 212 break;
203 case DELETED: 213 case DELETED:
204 TextPageData<Edge> edgesByTenantId = edgeService.findEdgesByTenantId(tenantId, new TextPageLink(Integer.MAX_VALUE)); 214 TextPageData<Edge> edgesByTenantId = edgeService.findEdgesByTenantId(tenantId, new TextPageLink(Integer.MAX_VALUE));
@@ -33,19 +33,12 @@ import org.thingsboard.server.dao.entityview.EntityViewService; @@ -33,19 +33,12 @@ 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.WidgetsBundleService;
36 import org.thingsboard.server.queue.discovery.PartitionService; 37 import org.thingsboard.server.queue.discovery.PartitionService;
37 import org.thingsboard.server.queue.provider.TbQueueProducerProvider; 38 import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
38 import org.thingsboard.server.queue.util.TbCoreComponent; 39 import org.thingsboard.server.queue.util.TbCoreComponent;
39 import org.thingsboard.server.service.edge.rpc.EdgeEventStorageSettings; 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 import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService; 42 import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService;
50 import org.thingsboard.server.service.executors.DbCallbackExecutorService; 43 import org.thingsboard.server.service.executors.DbCallbackExecutorService;
51 import org.thingsboard.server.service.queue.TbClusterService; 44 import org.thingsboard.server.service.queue.TbClusterService;
@@ -121,6 +114,10 @@ public class EdgeContextComponent { @@ -121,6 +114,10 @@ public class EdgeContextComponent {
121 114
122 @Lazy 115 @Lazy
123 @Autowired 116 @Autowired
  117 + private WidgetsBundleService widgetsBundleService;
  118 +
  119 + @Lazy
  120 + @Autowired
124 private DeviceStateService deviceStateService; 121 private DeviceStateService deviceStateService;
125 122
126 @Lazy 123 @Lazy
@@ -165,6 +162,10 @@ public class EdgeContextComponent { @@ -165,6 +162,10 @@ public class EdgeContextComponent {
165 162
166 @Lazy 163 @Lazy
167 @Autowired 164 @Autowired
  165 + private WidgetsBundleUpdateMsgConstructor widgetsBundleUpdateMsgConstructor;
  166 +
  167 + @Lazy
  168 + @Autowired
168 private EntityDataMsgConstructor entityDataMsgConstructor; 169 private EntityDataMsgConstructor entityDataMsgConstructor;
169 170
170 @Lazy 171 @Lazy
@@ -54,6 +54,7 @@ import org.thingsboard.server.common.data.id.EntityViewId; @@ -54,6 +54,7 @@ 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.WidgetsBundleId;
57 import org.thingsboard.server.common.data.kv.AttributeKvEntry; 58 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
58 import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; 59 import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
59 import org.thingsboard.server.common.data.kv.LongDataEntry; 60 import org.thingsboard.server.common.data.kv.LongDataEntry;
@@ -66,6 +67,7 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; @@ -66,6 +67,7 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData;
66 import org.thingsboard.server.common.data.security.DeviceCredentials; 67 import org.thingsboard.server.common.data.security.DeviceCredentials;
67 import org.thingsboard.server.common.data.security.DeviceCredentialsType; 68 import org.thingsboard.server.common.data.security.DeviceCredentialsType;
68 import org.thingsboard.server.common.data.security.UserCredentials; 69 import org.thingsboard.server.common.data.security.UserCredentials;
  70 +import org.thingsboard.server.common.data.widget.WidgetsBundle;
69 import org.thingsboard.server.common.msg.TbMsg; 71 import org.thingsboard.server.common.msg.TbMsg;
70 import org.thingsboard.server.common.msg.TbMsgMetaData; 72 import org.thingsboard.server.common.msg.TbMsgMetaData;
71 import org.thingsboard.server.common.msg.queue.ServiceType; 73 import org.thingsboard.server.common.msg.queue.ServiceType;
@@ -99,6 +101,7 @@ import org.thingsboard.server.gen.edge.UplinkMsg; @@ -99,6 +101,7 @@ import org.thingsboard.server.gen.edge.UplinkMsg;
99 import org.thingsboard.server.gen.edge.UplinkResponseMsg; 101 import org.thingsboard.server.gen.edge.UplinkResponseMsg;
100 import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; 102 import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg;
101 import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; 103 import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg;
  104 +import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg;
102 import org.thingsboard.server.gen.transport.TransportProtos; 105 import org.thingsboard.server.gen.transport.TransportProtos;
103 import org.thingsboard.server.queue.TbQueueCallback; 106 import org.thingsboard.server.queue.TbQueueCallback;
104 import org.thingsboard.server.queue.TbQueueMsgMetadata; 107 import org.thingsboard.server.queue.TbQueueMsgMetadata;
@@ -335,6 +338,9 @@ public final class EdgeGrpcSession implements Closeable { @@ -335,6 +338,9 @@ public final class EdgeGrpcSession implements Closeable {
335 case RELATION: 338 case RELATION:
336 processRelation(edgeEvent, msgType); 339 processRelation(edgeEvent, msgType);
337 break; 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,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 private UpdateMsgType getResponseMsgType(ActionType actionType) { 627 private UpdateMsgType getResponseMsgType(ActionType actionType) {
592 switch (actionType) { 628 switch (actionType) {
593 case UPDATED: 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,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
@@ -39,6 +36,8 @@ public final class EdgeUtils { @@ -39,6 +36,8 @@ public final class EdgeUtils {
39 return EdgeEventType.USER; 36 return EdgeEventType.USER;
40 case ALARM: 37 case ALARM:
41 return EdgeEventType.ALARM; 38 return EdgeEventType.ALARM;
  39 + case WIDGETS_BUNDLE:
  40 + return EdgeEventType.WIDGETS_BUNDLE;
42 default: 41 default:
43 return null; 42 return null;
44 } 43 }
@@ -26,5 +26,6 @@ public enum EdgeEventType { @@ -26,5 +26,6 @@ public enum EdgeEventType {
26 EDGE, 26 EDGE,
27 USER, 27 USER,
28 CUSTOMER, 28 CUSTOMER,
29 - RELATION 29 + RELATION,
  30 + WIDGETS_BUNDLE
30 } 31 }
@@ -87,6 +87,8 @@ public class EntityIdFactory { @@ -87,6 +87,8 @@ 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);
90 case EDGE: 92 case EDGE:
91 return new EdgeId(uuid); 93 return new EdgeId(uuid);
92 } 94 }
@@ -59,6 +59,7 @@ message EntityUpdateMsg { @@ -59,6 +59,7 @@ 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;
62 } 63 }
63 64
64 enum RequestMsgType { 65 enum RequestMsgType {
@@ -266,6 +267,15 @@ message UserUpdateMsg { @@ -266,6 +267,15 @@ message UserUpdateMsg {
266 string additionalInfo = 8; 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 message UserCredentialsUpdateMsg { 279 message UserCredentialsUpdateMsg {
270 int64 userIdMSB = 1; 280 int64 userIdMSB = 1;
271 int64 userIdLSB = 2; 281 int64 userIdLSB = 2;