WidgetsBundles fetch feature

This commit is contained in:
Bohdan Smetaniuk 2020-07-30 18:58:04 +03:00
parent d34c54b31c
commit 5af7eb8221
9 changed files with 143 additions and 26 deletions

View File

@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.id.WidgetsBundleId;
@ -68,7 +69,11 @@ public class WidgetsBundleController extends BaseController {
} }
checkEntity(widgetsBundle.getId(), widgetsBundle, Resource.WIDGETS_BUNDLE); checkEntity(widgetsBundle.getId(), widgetsBundle, Resource.WIDGETS_BUNDLE);
return checkNotNull(widgetsBundleService.saveWidgetsBundle(widgetsBundle)); WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
sendNotificationMsgToEdgeService(savedWidgetsBundle.getTenantId(), savedWidgetsBundle.getId(), ActionType.UPDATED);
return checkNotNull(savedWidgetsBundle);
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -83,6 +88,9 @@ public class WidgetsBundleController extends BaseController {
WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId));
checkWidgetsBundleId(widgetsBundleId, Operation.DELETE); checkWidgetsBundleId(widgetsBundleId, Operation.DELETE);
widgetsBundleService.deleteWidgetsBundle(getTenantId(), widgetsBundleId); widgetsBundleService.deleteWidgetsBundle(getTenantId(), widgetsBundleId);
sendNotificationMsgToEdgeService(getTenantId(), widgetsBundleId, ActionType.DELETED);
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }

View File

@ -157,6 +157,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
case ENTITY_VIEW: case ENTITY_VIEW:
case DASHBOARD: case DASHBOARD:
case RULE_CHAIN: case RULE_CHAIN:
case WIDGETS_BUNDLE:
processEntity(tenantId, edgeNotificationMsg); processEntity(tenantId, edgeNotificationMsg);
break; break;
case ALARM: case ALARM:
@ -185,20 +186,29 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
// case ADDED: // case ADDED:
case UPDATED: case UPDATED:
case CREDENTIALS_UPDATED: case CREDENTIALS_UPDATED:
ListenableFuture<List<EdgeId>> edgeIdsFuture = findRelatedEdgeIdsByEntityId(tenantId, entityId); if (edgeEventType.equals(EdgeEventType.WIDGETS_BUNDLE)) {
Futures.transform(edgeIdsFuture, edgeIds -> { TextPageData<Edge> edgesByTenantId = edgeService.findEdgesByTenantId(tenantId, new TextPageLink(Integer.MAX_VALUE));
if (edgeIds != null && !edgeIds.isEmpty()) { if (edgesByTenantId != null && edgesByTenantId.getData() != null && !edgesByTenantId.getData().isEmpty()) {
for (EdgeId edgeId : edgeIds) { for (Edge edge : edgesByTenantId.getData()) {
try { saveEdgeEvent(tenantId, edge.getId(), edgeEventType, edgeEventActionType, entityId, null);
saveEdgeEvent(tenantId, edgeId, edgeEventType, edgeEventActionType, entityId, null);
} catch (Exception e) {
log.error("[{}] Failed to push event to edge, edgeId [{}], edgeEventType [{}], edgeEventActionType [{}], entityId [{}]",
tenantId, edgeId, edgeEventType, edgeEventActionType, entityId, e);
}
} }
} }
return null; } else {
}, dbCallbackExecutorService); ListenableFuture<List<EdgeId>> edgeIdsFuture = findRelatedEdgeIdsByEntityId(tenantId, entityId);
Futures.transform(edgeIdsFuture, edgeIds -> {
if (edgeIds != null && !edgeIds.isEmpty()) {
for (EdgeId edgeId : edgeIds) {
try {
saveEdgeEvent(tenantId, edgeId, edgeEventType, edgeEventActionType, entityId, null);
} catch (Exception e) {
log.error("[{}] Failed to push event to edge, edgeId [{}], edgeEventType [{}], edgeEventActionType [{}], entityId [{}]",
tenantId, edgeId, edgeEventType, edgeEventActionType, entityId, e);
}
}
}
return null;
}, dbCallbackExecutorService);
}
break; break;
case DELETED: case DELETED:
TextPageData<Edge> edgesByTenantId = edgeService.findEdgesByTenantId(tenantId, new TextPageLink(Integer.MAX_VALUE)); TextPageData<Edge> edgesByTenantId = edgeService.findEdgesByTenantId(tenantId, new TextPageLink(Integer.MAX_VALUE));

View File

@ -33,19 +33,12 @@ import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.dao.widget.WidgetsBundleService;
import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.EdgeEventStorageSettings; import org.thingsboard.server.service.edge.rpc.EdgeEventStorageSettings;
import org.thingsboard.server.service.edge.rpc.constructor.AlarmUpdateMsgConstructor; import org.thingsboard.server.service.edge.rpc.constructor.*;
import org.thingsboard.server.service.edge.rpc.constructor.AssetUpdateMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.DashboardUpdateMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.DeviceUpdateMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.EntityDataMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.EntityViewUpdateMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.RelationUpdateMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.RuleChainUpdateMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.UserUpdateMsgConstructor;
import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService; import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.queue.TbClusterService; import org.thingsboard.server.service.queue.TbClusterService;
@ -119,6 +112,10 @@ public class EdgeContextComponent {
@Autowired @Autowired
private ActorService actorService; private ActorService actorService;
@Lazy
@Autowired
private WidgetsBundleService widgetsBundleService;
@Lazy @Lazy
@Autowired @Autowired
private DeviceStateService deviceStateService; private DeviceStateService deviceStateService;
@ -163,6 +160,10 @@ public class EdgeContextComponent {
@Autowired @Autowired
private RelationUpdateMsgConstructor relationUpdateMsgConstructor; private RelationUpdateMsgConstructor relationUpdateMsgConstructor;
@Lazy
@Autowired
private WidgetsBundleUpdateMsgConstructor widgetsBundleUpdateMsgConstructor;
@Lazy @Lazy
@Autowired @Autowired
private EntityDataMsgConstructor entityDataMsgConstructor; private EntityDataMsgConstructor entityDataMsgConstructor;

View File

@ -54,6 +54,7 @@ import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.id.WidgetsBundleId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.kv.LongDataEntry;
@ -66,6 +67,7 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.ServiceType;
@ -99,6 +101,7 @@ import org.thingsboard.server.gen.edge.UplinkMsg;
import org.thingsboard.server.gen.edge.UplinkResponseMsg; import org.thingsboard.server.gen.edge.UplinkResponseMsg;
import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg;
import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg;
import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg;
import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.TbQueueCallback; import org.thingsboard.server.queue.TbQueueCallback;
import org.thingsboard.server.queue.TbQueueMsgMetadata; import org.thingsboard.server.queue.TbQueueMsgMetadata;
@ -335,6 +338,9 @@ public final class EdgeGrpcSession implements Closeable {
case RELATION: case RELATION:
processRelation(edgeEvent, msgType); processRelation(edgeEvent, msgType);
break; break;
case WIDGETS_BUNDLE:
processWidgetsBundle(edgeEvent, msgType, edgeEventAction);
break;
} }
} }
@ -588,6 +594,36 @@ public final class EdgeGrpcSession implements Closeable {
} }
} }
private void processWidgetsBundle(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) {
WidgetsBundleId widgetsBundleId = new WidgetsBundleId(edgeEvent.getEntityId());
EntityUpdateMsg entityUpdateMsg = null;
switch (edgeActionType) {
case ADDED:
case UPDATED:
WidgetsBundle widgetsBundle = ctx.getWidgetsBundleService().findWidgetsBundleById(edgeEvent.getTenantId(), widgetsBundleId);
if (widgetsBundle != null) {
WidgetsBundleUpdateMsg widgetsBundleUpdateMsg =
ctx.getWidgetsBundleUpdateMsgConstructor().constructWidgetsBundleUpdateMsg(msgType, widgetsBundle);
entityUpdateMsg = EntityUpdateMsg.newBuilder()
.setWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg)
.build();
}
break;
case DELETED:
WidgetsBundleUpdateMsg widgetsBundleUpdateMsg =
ctx.getWidgetsBundleUpdateMsgConstructor().constructWidgetsBundleDeleteMsg(widgetsBundleId);
entityUpdateMsg = EntityUpdateMsg.newBuilder()
.setWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg)
.build();
break;
}
if (entityUpdateMsg != null) {
outputStream.onNext(ResponseMsg.newBuilder()
.setEntityUpdateMsg(entityUpdateMsg)
.build());
}
}
private UpdateMsgType getResponseMsgType(ActionType actionType) { private UpdateMsgType getResponseMsgType(ActionType actionType) {
switch (actionType) { switch (actionType) {
case UPDATED: case UPDATED:

View File

@ -0,0 +1,50 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.constructor;
import com.google.protobuf.ByteString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.id.WidgetsBundleId;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.gen.edge.UpdateMsgType;
import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg;
@Component
@Slf4j
public class WidgetsBundleUpdateMsgConstructor {
public WidgetsBundleUpdateMsg constructWidgetsBundleUpdateMsg(UpdateMsgType msgType, WidgetsBundle widgetsBundle) {
WidgetsBundleUpdateMsg.Builder builder = WidgetsBundleUpdateMsg.newBuilder()
.setMsgType(msgType)
.setIdMSB(widgetsBundle.getId().getId().getMostSignificantBits())
.setIdLSB(widgetsBundle.getId().getId().getLeastSignificantBits())
.setTitle(widgetsBundle.getTitle())
.setAlias(widgetsBundle.getAlias());
if (widgetsBundle.getImage() != null) {
builder.setImage(ByteString.copyFrom(widgetsBundle.getImage()));
}
return builder.build();
}
public WidgetsBundleUpdateMsg constructWidgetsBundleDeleteMsg(WidgetsBundleId widgetsBundleId) {
return WidgetsBundleUpdateMsg.newBuilder()
.setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE)
.setIdMSB(widgetsBundleId.getId().getMostSignificantBits())
.setIdLSB(widgetsBundleId.getId().getLeastSignificantBits())
.build();
}
}

View File

@ -16,9 +16,6 @@
package org.thingsboard.server.common.data; package org.thingsboard.server.common.data;
import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.EdgeId;
import java.util.Set;
public final class EdgeUtils { public final class EdgeUtils {
@ -39,6 +36,8 @@ public final class EdgeUtils {
return EdgeEventType.USER; return EdgeEventType.USER;
case ALARM: case ALARM:
return EdgeEventType.ALARM; return EdgeEventType.ALARM;
case WIDGETS_BUNDLE:
return EdgeEventType.WIDGETS_BUNDLE;
default: default:
return null; return null;
} }

View File

@ -26,5 +26,6 @@ public enum EdgeEventType {
EDGE, EDGE,
USER, USER,
CUSTOMER, CUSTOMER,
RELATION RELATION,
WIDGETS_BUNDLE
} }

View File

@ -87,6 +87,8 @@ public class EntityIdFactory {
return new RuleChainId(uuid); return new RuleChainId(uuid);
case ENTITY_VIEW: case ENTITY_VIEW:
return new EntityViewId(uuid); return new EntityViewId(uuid);
case WIDGETS_BUNDLE:
return new WidgetsBundleId(uuid);
case EDGE: case EDGE:
return new EdgeId(uuid); return new EdgeId(uuid);
} }

View File

@ -59,6 +59,7 @@ message EntityUpdateMsg {
UserCredentialsUpdateMsg userCredentialsUpdateMsg = 10; UserCredentialsUpdateMsg userCredentialsUpdateMsg = 10;
CustomerUpdateMsg customerUpdateMsg = 11; CustomerUpdateMsg customerUpdateMsg = 11;
RelationUpdateMsg relationUpdateMsg = 12; RelationUpdateMsg relationUpdateMsg = 12;
WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = 13;
} }
enum RequestMsgType { enum RequestMsgType {
@ -266,6 +267,15 @@ message UserUpdateMsg {
string additionalInfo = 8; string additionalInfo = 8;
} }
message WidgetsBundleUpdateMsg {
UpdateMsgType msgType = 1;
int64 idMSB = 2;
int64 idLSB = 3;
string title = 4;
string alias = 5;
bytes image = 6;
}
message UserCredentialsUpdateMsg { message UserCredentialsUpdateMsg {
int64 userIdMSB = 1; int64 userIdMSB = 1;
int64 userIdLSB = 2; int64 userIdLSB = 2;