Commit e7906375a6fac21eeb41b94085acc4b4df0116aa

Authored by VoBa
Committed by GitHub
2 parents 869a492c 4e167d85

Merge pull request #30 from BohdanSmetanyuk/feature/widgets_bundle_fetch

WidgetsBundle fetch + WidgetTypes fetch
@@ -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 }
@@ -28,4 +28,7 @@ public enum EdgeEventType { @@ -28,4 +28,7 @@ public enum EdgeEventType {
28 CUSTOMER, 28 CUSTOMER,
29 RELATION, 29 RELATION,
30 TENANT 30 TENANT
  31 + RELATION,
  32 + WIDGETS_BUNDLE,
  33 + WIDGET_TYPE
31 } 34 }
@@ -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;