From a76d3a2b70287eec95dcb76b0da20941a3d7357c Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 12 May 2021 18:14:51 +0300 Subject: [PATCH 01/52] Cover cases when entities added during edge disconnect. Refactoring --- .../server/actors/tenant/TenantActor.java | 6 +- .../server/controller/BaseController.java | 14 +- .../server/controller/EdgeController.java | 5 +- .../edge/DefaultEdgeNotificationService.java | 2 +- .../service/edge/EdgeContextComponent.java | 4 +- .../service/edge/rpc/EdgeEventUtils.java | 48 ++ .../service/edge/rpc/EdgeGrpcService.java | 31 +- .../service/edge/rpc/EdgeGrpcSession.java | 298 +++++++---- .../service/edge/rpc/EdgeRpcService.java | 9 +- .../fetch/AdminSettingsEdgeEventFetcher.java | 109 ++++ .../rpc/fetch/AssetsEdgeEventFetcher.java | 58 ++ .../rpc/fetch/BaseUsersEdgeEventFetcher.java | 58 ++ .../BaseWidgetsBundlesEdgeEventFetcher.java | 55 ++ .../fetch/CustomerUsersEdgeEventFetcher.java | 36 ++ .../rpc/fetch/DashboardsEdgeEventFetcher.java | 58 ++ .../fetch/DeviceProfilesEdgeEventFetcher.java | 58 ++ .../edge/rpc/fetch/EdgeEventFetcher.java | 31 ++ .../rpc/fetch/GeneralEdgeEventFetcher.java | 50 ++ .../rpc/fetch/RuleChainsEdgeEventFetcher.java | 58 ++ .../SystemWidgetsBundlesEdgeEventFetcher.java | 36 ++ .../TenantAdminUsersEdgeEventFetcher.java | 34 ++ .../TenantWidgetsBundlesEdgeEventFetcher.java | 36 ++ .../DefaultEdgeRequestsService.java} | 503 ++++++------------ .../EdgeRequestsService.java} | 15 +- application/src/main/resources/logback.xml | 1 + .../thingsboard/server/edge/BaseEdgeTest.java | 9 +- .../server/edge/imitator/EdgeImitator.java | 2 +- .../thingsboard/edge/rpc/EdgeGrpcClient.java | 7 +- .../thingsboard/edge/rpc/EdgeRpcClient.java | 2 +- common/edge-api/src/main/proto/edge.proto | 66 ++- .../server/dao/edge/EdgeServiceImpl.java | 1 + 31 files changed, 1195 insertions(+), 505 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeEventUtils.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemWidgetsBundlesEdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantAdminUsersEdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java rename application/src/main/java/org/thingsboard/server/service/edge/rpc/{init/DefaultSyncEdgeService.java => sync/DefaultEdgeRequestsService.java} (52%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/{init/SyncEdgeService.java => sync/EdgeRequestsService.java} (71%) diff --git a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java index 68afbdaf99..1a74e368f5 100644 --- a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java @@ -245,11 +245,11 @@ public class TenantActor extends RuleChainManagerActor { EdgeId edgeId = new EdgeId(msg.getEntityId().getId()); EdgeRpcService edgeRpcService = systemContext.getEdgeRpcService(); if (msg.getEvent() == ComponentLifecycleEvent.DELETED) { - edgeRpcService.deleteEdge(edgeId); + edgeRpcService.deleteEdge(tenantId, edgeId); } else { Edge edge = systemContext.getEdgeService().findEdgeById(tenantId, edgeId); if (msg.getEvent() == ComponentLifecycleEvent.UPDATED) { - edgeRpcService.updateEdge(edge); + edgeRpcService.updateEdge(tenantId, edge); } } } else if (isRuleEngineForCurrentTenant) { @@ -277,7 +277,7 @@ public class TenantActor extends RuleChainManagerActor { private void onToEdgeSessionMsg(EdgeEventUpdateMsg msg) { log.trace("[{}] onToEdgeSessionMsg [{}]", msg.getTenantId(), msg); - systemContext.getEdgeRpcService().onEdgeEvent(msg.getEdgeId()); + systemContext.getEdgeRpcService().onEdgeEvent(tenantId, msg.getEdgeId()); } public static class ActorCreator extends ContextBasedCreator { diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 505416f4d6..9f6379cf6c 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -43,8 +43,8 @@ import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.FirmwareInfo; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasTenantId; -import org.thingsboard.server.common.data.TbResourceInfo; import org.thingsboard.server.common.data.TbResource; +import org.thingsboard.server.common.data.TbResourceInfo; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.TenantInfo; import org.thingsboard.server.common.data.TenantProfile; @@ -71,9 +71,9 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.FirmwareId; -import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; +import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.id.UserId; @@ -128,10 +128,9 @@ import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.component.ComponentDiscoveryService; -import org.thingsboard.server.service.firmware.FirmwareStateService; import org.thingsboard.server.service.edge.EdgeNotificationService; -import org.thingsboard.server.service.edge.rpc.EdgeGrpcService; -import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService; +import org.thingsboard.server.service.edge.rpc.EdgeRpcService; +import org.thingsboard.server.service.firmware.FirmwareStateService; import org.thingsboard.server.service.lwm2m.LwM2MServerSecurityInfoRepository; import org.thingsboard.server.service.profile.TbDeviceProfileCache; import org.thingsboard.server.service.queue.TbClusterService; @@ -276,10 +275,7 @@ public abstract class BaseController { protected EdgeNotificationService edgeNotificationService; @Autowired(required = false) - protected SyncEdgeService syncEdgeService; - - @Autowired(required = false) - protected EdgeGrpcService edgeGrpcService; + protected EdgeRpcService edgeGrpcService; @Value("${server.log_controller_error_stack_trace}") @Getter diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java index 9c196c6bd2..c71f1a7a74 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java @@ -49,7 +49,6 @@ import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.queue.util.TbCoreComponent; -import org.thingsboard.server.service.edge.rpc.EdgeGrpcSession; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; @@ -536,9 +535,7 @@ public class EdgeController extends BaseController { edgeId = checkNotNull(edgeId); SecurityUser user = getCurrentUser(); TenantId tenantId = user.getTenantId(); - EdgeGrpcSession session = edgeGrpcService.getEdgeGrpcSessionById(tenantId, edgeId); - Edge edge = session.getEdge(); - syncEdgeService.sync(tenantId, edge); + edgeGrpcService.startSyncProcess(tenantId, edgeId); } else { throw new ThingsboardException("Edges support disabled", ThingsboardErrorCode.GENERAL); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java index 66e64c14f1..5d85ddf16f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java @@ -326,7 +326,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { case ASSIGNED_TO_CUSTOMER: case UNASSIGNED_FROM_CUSTOMER: edgeIdsFuture = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId); - Futures.addCallback(edgeIdsFuture, new FutureCallback>() { + Futures.addCallback(edgeIdsFuture, new FutureCallback<>() { @Override public void onSuccess(@Nullable List edgeIds) { if (edgeIds != null && !edgeIds.isEmpty()) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java b/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java index eb3852f7ac..62940f2931 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java @@ -54,7 +54,7 @@ import org.thingsboard.server.service.edge.rpc.constructor.RuleChainMsgConstruct import org.thingsboard.server.service.edge.rpc.constructor.UserMsgConstructor; import org.thingsboard.server.service.edge.rpc.constructor.WidgetTypeMsgConstructor; import org.thingsboard.server.service.edge.rpc.constructor.WidgetsBundleMsgConstructor; -import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService; +import org.thingsboard.server.service.edge.rpc.sync.EdgeRequestsService; import org.thingsboard.server.service.edge.rpc.processor.AlarmProcessor; import org.thingsboard.server.service.edge.rpc.processor.DeviceProcessor; import org.thingsboard.server.service.edge.rpc.processor.RelationProcessor; @@ -149,7 +149,7 @@ public class EdgeContextComponent { @Lazy @Autowired - private SyncEdgeService syncEdgeService; + private EdgeRequestsService edgeRequestsService; @Lazy @Autowired diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeEventUtils.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeEventUtils.java new file mode 100644 index 0000000000..f09184504e --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeEventUtils.java @@ -0,0 +1,48 @@ +/** + * Copyright © 2016-2021 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; + +import com.fasterxml.jackson.databind.JsonNode; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; + +public final class EdgeEventUtils { + + private EdgeEventUtils() { + } + + public static EdgeEvent constructEdgeEvent(TenantId tenantId, + EdgeId edgeId, + EdgeEventType type, + EdgeEventActionType action, + EntityId entityId, + JsonNode body) { + EdgeEvent edgeEvent = new EdgeEvent(); + edgeEvent.setTenantId(tenantId); + edgeEvent.setEdgeId(edgeId); + edgeEvent.setType(type); + edgeEvent.setAction(action); + if (entityId != null) { + edgeEvent.setEntityId(entityId.getId()); + } + edgeEvent.setBody(body); + return edgeEvent; + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 70033f10e1..59b22864bd 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -53,6 +53,7 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -95,6 +96,8 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i private ScheduledExecutorService scheduler; + private ExecutorService syncExecutorService; + @PostConstruct public void init() { log.info("Initializing Edge RPC service!"); @@ -120,6 +123,8 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i throw new RuntimeException("Failed to start Edge RPC server!"); } this.scheduler = Executors.newScheduledThreadPool(schedulerPoolSize, ThingsBoardThreadFactory.forName("edge-scheduler")); + this.syncExecutorService = Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors(), ThingsBoardThreadFactory.forName("edge-sync")); log.info("Edge RPC service initialized!"); } @@ -139,29 +144,32 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i if (scheduler != null) { scheduler.shutdownNow(); } + if (syncExecutorService != null) { + syncExecutorService.shutdownNow(); + } } @Override public StreamObserver handleMsgs(StreamObserver outputStream) { - return new EdgeGrpcSession(ctx, outputStream, this::onEdgeConnect, this::onEdgeDisconnect, mapper).getInputStream(); + return new EdgeGrpcSession(ctx, outputStream, this::onEdgeConnect, this::onEdgeDisconnect, mapper, syncExecutorService).getInputStream(); } @Override - public void updateEdge(Edge edge) { + public void updateEdge(TenantId tenantId, Edge edge) { EdgeGrpcSession session = sessions.get(edge.getId()); if (session != null && session.isConnected()) { - log.debug("[{}] Updating configuration for edge [{}] [{}]", edge.getTenantId(), edge.getName(), edge.getId()); + log.debug("[{}] Updating configuration for edge [{}] [{}]", tenantId, edge.getName(), edge.getId()); session.onConfigurationUpdate(edge); } else { - log.debug("[{}] Session doesn't exist for edge [{}] [{}]", edge.getTenantId(), edge.getName(), edge.getId()); + log.debug("[{}] Session doesn't exist for edge [{}] [{}]", tenantId, edge.getName(), edge.getId()); } } @Override - public void deleteEdge(EdgeId edgeId) { + public void deleteEdge(TenantId tenantId, EdgeId edgeId) { EdgeGrpcSession session = sessions.get(edgeId); if (session != null && session.isConnected()) { - log.info("Closing and removing session for edge [{}]", edgeId); + log.info("[{}] Closing and removing session for edge [{}]", tenantId, edgeId); session.close(); sessions.remove(edgeId); sessionNewEvents.remove(edgeId); @@ -170,10 +178,10 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i } @Override - public void onEdgeEvent(EdgeId edgeId) { - log.trace("[{}] onEdgeEvent", edgeId.getId()); + public void onEdgeEvent(TenantId tenantId, EdgeId edgeId) { + log.trace("[{}] onEdgeEvent [{}]", tenantId, edgeId.getId()); if (!sessionNewEvents.get(edgeId)) { - log.trace("[{}] set session new events flag to true", edgeId.getId()); + log.trace("[{}] set session new events flag to true [{}]", tenantId, edgeId.getId()); sessionNewEvents.put(edgeId, true); } } @@ -188,10 +196,11 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i scheduleEdgeEventsCheck(edgeGrpcSession); } - public EdgeGrpcSession getEdgeGrpcSessionById(TenantId tenantId, EdgeId edgeId) { + @Override + public void startSyncProcess(TenantId tenantId, EdgeId edgeId) { EdgeGrpcSession session = sessions.get(edgeId); if (session != null && session.isConnected()) { - return session; + session.startSyncProcess(); } else { log.error("[{}] Edge is not connected [{}]", tenantId, edgeId); throw new RuntimeException("Edge is not connected"); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index fb01926e2a..da0b1a7736 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -16,9 +16,7 @@ package org.thingsboard.server.service.edge.rpc; import com.datastax.oss.driver.api.core.uuid.Uuids; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -28,6 +26,7 @@ import io.grpc.stub.StreamObserver; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.Nullable; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Dashboard; @@ -61,8 +60,7 @@ import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.page.PageData; -import org.thingsboard.server.common.data.page.SortOrder; -import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainMetaData; @@ -71,7 +69,6 @@ import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.common.transport.util.JsonUtils; -import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.gen.edge.AdminSettingsUpdateMsg; import org.thingsboard.server.gen.edge.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.AssetUpdateMsg; @@ -83,6 +80,7 @@ import org.thingsboard.server.gen.edge.CustomerUpdateMsg; import org.thingsboard.server.gen.edge.DashboardUpdateMsg; import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.DeviceProfileDevicesRequestMsg; import org.thingsboard.server.gen.edge.DeviceProfileUpdateMsg; import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; import org.thingsboard.server.gen.edge.DeviceUpdateMsg; @@ -92,6 +90,7 @@ import org.thingsboard.server.gen.edge.EdgeConfiguration; import org.thingsboard.server.gen.edge.EdgeUpdateMsg; import org.thingsboard.server.gen.edge.EntityDataProto; import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; +import org.thingsboard.server.gen.edge.EntityViewsRequestMsg; import org.thingsboard.server.gen.edge.RelationRequestMsg; import org.thingsboard.server.gen.edge.RelationUpdateMsg; import org.thingsboard.server.gen.edge.RequestMsg; @@ -100,14 +99,26 @@ import org.thingsboard.server.gen.edge.ResponseMsg; import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg; import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg; import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; +import org.thingsboard.server.gen.edge.SyncCompletedMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; import org.thingsboard.server.gen.edge.UplinkMsg; import org.thingsboard.server.gen.edge.UplinkResponseMsg; import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.WidgetBundleTypesRequestMsg; import org.thingsboard.server.gen.edge.WidgetTypeUpdateMsg; import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; import org.thingsboard.server.service.edge.EdgeContextComponent; +import org.thingsboard.server.service.edge.rpc.fetch.AssetsEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.CustomerUsersEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.DashboardsEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.DeviceProfilesEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.EdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.GeneralEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.RuleChainsEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.SystemWidgetsBundlesEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.TenantAdminUsersEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.TenantWidgetsBundlesEdgeEventFetcher; import java.io.Closeable; import java.util.ArrayList; @@ -117,6 +128,7 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import java.util.function.BiConsumer; @@ -140,22 +152,26 @@ public final class EdgeGrpcSession implements Closeable { private StreamObserver inputStream; private StreamObserver outputStream; private boolean connected; + private boolean syncCompleted; + + private ExecutorService syncExecutorService; private CountDownLatch latch; EdgeGrpcSession(EdgeContextComponent ctx, StreamObserver outputStream, BiConsumer sessionOpenListener, - Consumer sessionCloseListener, ObjectMapper mapper) { + Consumer sessionCloseListener, ObjectMapper mapper, ExecutorService syncExecutorService) { this.sessionId = UUID.randomUUID(); this.ctx = ctx; this.outputStream = outputStream; this.sessionOpenListener = sessionOpenListener; this.sessionCloseListener = sessionCloseListener; this.mapper = mapper; + this.syncExecutorService = syncExecutorService; initInputStream(); } private void initInputStream() { - this.inputStream = new StreamObserver() { + this.inputStream = new StreamObserver<>() { @Override public void onNext(RequestMsg requestMsg) { if (!connected && requestMsg.getMsgType().equals(RequestMsgType.CONNECT_RPC_MESSAGE)) { @@ -170,7 +186,10 @@ public final class EdgeGrpcSession implements Closeable { } } if (connected && requestMsg.getMsgType().equals(RequestMsgType.SYNC_REQUEST_RPC_MESSAGE)) { - ctx.getSyncEdgeService().sync(edge.getTenantId(), edge); + if (requestMsg.getSyncRequestMsg().getSyncRequired()) { + startSyncProcess(); + } + syncCompleted = true; } if (connected) { if (requestMsg.getMsgType().equals(RequestMsgType.UPLINK_RPC_MESSAGE) && requestMsg.hasUplinkMsg()) { @@ -198,18 +217,55 @@ public final class EdgeGrpcSession implements Closeable { if (edge != null) { try { sessionCloseListener.accept(edge.getId()); - } catch (Exception ignored) {} + } catch (Exception ignored) { + } } try { outputStream.onCompleted(); - } catch (Exception ignored) {} + } catch (Exception ignored) { + } } }; } + public void startSyncProcess() { + log.trace("[{}][{}] Staring edge sync process", edge.getTenantId(), edge.getId()); + syncExecutorService.submit(() -> { + try { + startProcessingEdgeEvents(new TenantWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService())); + startProcessingEdgeEvents(new SystemWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService())); + startProcessingEdgeEvents(new DeviceProfilesEdgeEventFetcher(ctx.getDeviceProfileService())); + startProcessingEdgeEvents(new RuleChainsEdgeEventFetcher(ctx.getRuleChainService())); + + startProcessingEdgeEvents(new TenantAdminUsersEdgeEventFetcher(ctx.getUserService())); + if (edge.getCustomerId() != null && !EntityId.NULL_UUID.equals(edge.getCustomerId().getId())) { + EdgeEvent customerEdgeEvent = EdgeEventUtils.constructEdgeEvent(edge.getTenantId(), edge.getId(), + EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, edge.getCustomerId(), null); + DownlinkMsg customerDownlinkMsg = convertToDownlinkMsg(customerEdgeEvent); + sendSingleDownlinkMsg(customerDownlinkMsg); + + startProcessingEdgeEvents(new CustomerUsersEdgeEventFetcher(ctx.getUserService(), edge.getCustomerId())); + } + + // TODO: voba - implement this functionality + // syncAdminSettings(edge); + + startProcessingEdgeEvents(new AssetsEdgeEventFetcher(ctx.getAssetService())); + startProcessingEdgeEvents(new DashboardsEdgeEventFetcher(ctx.getDashboardService())); + + DownlinkMsg syncCompleteDownlinkMsg = DownlinkMsg.newBuilder() + .setSyncCompletedMsg(SyncCompletedMsg.newBuilder().build()) + .build(); + sendSingleDownlinkMsg(syncCompleteDownlinkMsg); + } catch (Exception e) { + log.error("[{}][{}] Exception during sync process", edge.getTenantId(), edge.getId(), e); + } + }); + } + private void onUplinkMsg(UplinkMsg uplinkMsg) { ListenableFuture> future = processUplinkMsg(uplinkMsg); - Futures.addCallback(future, new FutureCallback>() { + Futures.addCallback(future, new FutureCallback<>() { @Override public void onSuccess(@Nullable List result) { UplinkResponseMsg uplinkResponseMsg = UplinkResponseMsg.newBuilder().setSuccess(true).build(); @@ -271,101 +327,136 @@ public final class EdgeGrpcSession implements Closeable { void processEdgeEvents() throws ExecutionException, InterruptedException { log.trace("[{}] processHandleMessages started", this.sessionId); - if (isConnected()) { + if (isConnected() && isSyncCompleted()) { Long queueStartTs = getQueueStartTs().get(); - TimePageLink pageLink = new TimePageLink( + GeneralEdgeEventFetcher fetcher = new GeneralEdgeEventFetcher( ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount(), - 0, - null, - new SortOrder("createdTime", SortOrder.Direction.ASC), queueStartTs, - null); - PageData pageData; - UUID ifOffset = null; - boolean success = true; - do { - pageData = ctx.getEdgeEventService().findEdgeEvents(edge.getTenantId(), edge.getId(), pageLink, true); - if (isConnected() && !pageData.getData().isEmpty()) { - log.trace("[{}] [{}] event(s) are going to be processed.", this.sessionId, pageData.getData().size()); - List downlinkMsgsPack = convertToDownlinkMsgsPack(pageData.getData()); - log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, downlinkMsgsPack.size()); - - latch = new CountDownLatch(downlinkMsgsPack.size()); - for (DownlinkMsg downlinkMsg : downlinkMsgsPack) { - sendDownlinkMsg(ResponseMsg.newBuilder() - .setDownlinkMsg(downlinkMsg) - .build()); - } + ctx.getEdgeEventService()); + UUID ifOffset = startProcessingEdgeEvents(fetcher); + if (ifOffset != null) { + Long newStartTs = Uuids.unixTimestamp(ifOffset); + updateQueueStartTs(newStartTs); + } + } + log.trace("[{}] processHandleMessages finished", this.sessionId); + } - ifOffset = pageData.getData().get(pageData.getData().size() - 1).getUuidId(); + private UUID startProcessingEdgeEvents(EdgeEventFetcher fetcher) throws InterruptedException { + PageLink pageLink = fetcher.getPageLink(); + PageData pageData; + UUID ifOffset = null; + boolean success = true; + do { + pageData = fetcher.fetchEdgeEvents(edge.getTenantId(), edge.getId(), pageLink); + if (isConnected() && !pageData.getData().isEmpty()) { + log.trace("[{}] [{}] event(s) are going to be processed.", this.sessionId, pageData.getData().size()); - success = latch.await(10, TimeUnit.SECONDS); - if (!success) { - log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, downlinkMsgsPack); - } + success = processEdgeEventsPack(pageData.getData()); + + ifOffset = pageData.getData().get(pageData.getData().size() - 1).getUuidId(); + } + if (isConnected() && (!success || pageData.hasNext())) { + try { + Thread.sleep(ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches()); + } catch (InterruptedException e) { + log.error("[{}] Error during sleep between batches", this.sessionId, e); } - if (isConnected() && (!success || pageData.hasNext())) { - try { - Thread.sleep(ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches()); - } catch (InterruptedException e) { - log.error("[{}] Error during sleep between batches", this.sessionId, e); - } - if (success) { - pageLink = pageLink.nextPageLink(); - } + if (success) { + pageLink = pageLink.nextPageLink(); } - } while (isConnected() && (!success || pageData.hasNext())); + } + } while (isConnected() && (!success || pageData.hasNext())); + return ifOffset; + } - if (ifOffset != null) { - Long newStartTs = Uuids.unixTimestamp(ifOffset); - updateQueueStartTs(newStartTs); + private boolean processEdgeEventsPack(List edgeEvents) throws InterruptedException { + List downlinkMsgsPack = convertToDownlinkMsgsPack(edgeEvents); + + log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, downlinkMsgsPack.size()); + + latch = new CountDownLatch(downlinkMsgsPack.size()); + for (DownlinkMsg downlinkMsg : downlinkMsgsPack) { + sendDownlinkMsg(ResponseMsg.newBuilder() + .setDownlinkMsg(downlinkMsg) + .build()); + } + + boolean success = latch.await(10, TimeUnit.SECONDS); + if (!success) { + log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, downlinkMsgsPack); + } + return success; + } + + private void sendSingleDownlinkMsg(DownlinkMsg downlinkMsg) throws InterruptedException { + boolean success; + do { + latch = new CountDownLatch(1); + sendDownlinkMsg(ResponseMsg.newBuilder() + .setDownlinkMsg(downlinkMsg) + .build()); + success = latch.await(10, TimeUnit.SECONDS); + if (!success) { + log.warn("[{}] Failed to deliver single downlink msg!", this.sessionId); + } + if (isConnected() && !success) { + try { + Thread.sleep(ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches()); + } catch (InterruptedException e) { + log.error("[{}] Error during sleep between next send of single downlink msg", this.sessionId, e); + } } + } while (isConnected() && !success); + } + + private DownlinkMsg convertToDownlinkMsg(EdgeEvent edgeEvent) { + log.trace("[{}] converting edge event to downlink msg [{}]", this.sessionId, edgeEvent); + DownlinkMsg downlinkMsg = null; + try { + switch (edgeEvent.getAction()) { + case UPDATED: + case ADDED: + case DELETED: + case ASSIGNED_TO_EDGE: + case UNASSIGNED_FROM_EDGE: + case ALARM_ACK: + case ALARM_CLEAR: + case CREDENTIALS_UPDATED: + case RELATION_ADD_OR_UPDATE: + case RELATION_DELETED: + case ASSIGNED_TO_CUSTOMER: + case UNASSIGNED_FROM_CUSTOMER: + downlinkMsg = processEntityMessage(edgeEvent, edgeEvent.getAction()); + break; + case ATTRIBUTES_UPDATED: + case POST_ATTRIBUTES: + case ATTRIBUTES_DELETED: + case TIMESERIES_UPDATED: + downlinkMsg = processTelemetryMessage(edgeEvent); + break; + case CREDENTIALS_REQUEST: + downlinkMsg = processCredentialsRequestMessage(edgeEvent); + break; + case ENTITY_MERGE_REQUEST: + downlinkMsg = processEntityMergeRequestMessage(edgeEvent); + break; + case RPC_CALL: + downlinkMsg = processRpcCallMsg(edgeEvent); + break; + } + } catch (Exception e) { + log.error("Exception during converting edge event to downlink msg", e); } - log.trace("[{}] processHandleMessages finished", this.sessionId); + return downlinkMsg; } private List convertToDownlinkMsgsPack(List edgeEvents) { List result = new ArrayList<>(); for (EdgeEvent edgeEvent : edgeEvents) { - log.trace("[{}] Processing edge event [{}]", this.sessionId, edgeEvent); - try { - DownlinkMsg downlinkMsg = null; - switch (edgeEvent.getAction()) { - case UPDATED: - case ADDED: - case DELETED: - case ASSIGNED_TO_EDGE: - case UNASSIGNED_FROM_EDGE: - case ALARM_ACK: - case ALARM_CLEAR: - case CREDENTIALS_UPDATED: - case RELATION_ADD_OR_UPDATE: - case RELATION_DELETED: - case ASSIGNED_TO_CUSTOMER: - case UNASSIGNED_FROM_CUSTOMER: - downlinkMsg = processEntityMessage(edgeEvent, edgeEvent.getAction()); - break; - case ATTRIBUTES_UPDATED: - case POST_ATTRIBUTES: - case ATTRIBUTES_DELETED: - case TIMESERIES_UPDATED: - downlinkMsg = processTelemetryMessage(edgeEvent); - break; - case CREDENTIALS_REQUEST: - downlinkMsg = processCredentialsRequestMessage(edgeEvent); - break; - case ENTITY_MERGE_REQUEST: - downlinkMsg = processEntityMergeRequestMessage(edgeEvent); - break; - case RPC_CALL: - downlinkMsg = processRpcCallMsg(edgeEvent); - break; - } - if (downlinkMsg != null) { - result.add(downlinkMsg); - } - } catch (Exception e) { - log.error("Exception during processing records from queue", e); + DownlinkMsg downlinkMsg = convertToDownlinkMsg(edgeEvent); + if (downlinkMsg != null) { + result.add(downlinkMsg); } } return result; @@ -945,27 +1036,27 @@ public final class EdgeGrpcSession implements Closeable { } if (uplinkMsg.getRuleChainMetadataRequestMsgCount() > 0) { for (RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg : uplinkMsg.getRuleChainMetadataRequestMsgList()) { - result.add(ctx.getSyncEdgeService().processRuleChainMetadataRequestMsg(edge.getTenantId(), edge, ruleChainMetadataRequestMsg)); + result.add(ctx.getEdgeRequestsService().processRuleChainMetadataRequestMsg(edge.getTenantId(), edge, ruleChainMetadataRequestMsg)); } } if (uplinkMsg.getAttributesRequestMsgCount() > 0) { for (AttributesRequestMsg attributesRequestMsg : uplinkMsg.getAttributesRequestMsgList()) { - result.add(ctx.getSyncEdgeService().processAttributesRequestMsg(edge.getTenantId(), edge, attributesRequestMsg)); + result.add(ctx.getEdgeRequestsService().processAttributesRequestMsg(edge.getTenantId(), edge, attributesRequestMsg)); } } if (uplinkMsg.getRelationRequestMsgCount() > 0) { for (RelationRequestMsg relationRequestMsg : uplinkMsg.getRelationRequestMsgList()) { - result.add(ctx.getSyncEdgeService().processRelationRequestMsg(edge.getTenantId(), edge, relationRequestMsg)); + result.add(ctx.getEdgeRequestsService().processRelationRequestMsg(edge.getTenantId(), edge, relationRequestMsg)); } } if (uplinkMsg.getUserCredentialsRequestMsgCount() > 0) { for (UserCredentialsRequestMsg userCredentialsRequestMsg : uplinkMsg.getUserCredentialsRequestMsgList()) { - result.add(ctx.getSyncEdgeService().processUserCredentialsRequestMsg(edge.getTenantId(), edge, userCredentialsRequestMsg)); + result.add(ctx.getEdgeRequestsService().processUserCredentialsRequestMsg(edge.getTenantId(), edge, userCredentialsRequestMsg)); } } if (uplinkMsg.getDeviceCredentialsRequestMsgCount() > 0) { for (DeviceCredentialsRequestMsg deviceCredentialsRequestMsg : uplinkMsg.getDeviceCredentialsRequestMsgList()) { - result.add(ctx.getSyncEdgeService().processDeviceCredentialsRequestMsg(edge.getTenantId(), edge, deviceCredentialsRequestMsg)); + result.add(ctx.getEdgeRequestsService().processDeviceCredentialsRequestMsg(edge.getTenantId(), edge, deviceCredentialsRequestMsg)); } } if (uplinkMsg.getDeviceRpcCallMsgCount() > 0) { @@ -973,6 +1064,21 @@ public final class EdgeGrpcSession implements Closeable { result.add(ctx.getDeviceProcessor().processDeviceRpcCallResponseMsg(edge.getTenantId(), deviceRpcCallMsg)); } } + if (uplinkMsg.getDeviceProfileDevicesRequestMsgCount() > 0) { + for (DeviceProfileDevicesRequestMsg deviceProfileDevicesRequestMsg : uplinkMsg.getDeviceProfileDevicesRequestMsgList()) { + result.add(ctx.getEdgeRequestsService().processDeviceProfileDevicesRequestMsg(edge.getTenantId(), edge, deviceProfileDevicesRequestMsg)); + } + } + if (uplinkMsg.getWidgetBundleTypesRequestMsgCount() > 0) { + for (WidgetBundleTypesRequestMsg widgetBundleTypesRequestMsg : uplinkMsg.getWidgetBundleTypesRequestMsgList()) { + result.add(ctx.getEdgeRequestsService().processWidgetBundleTypesRequestMsg(edge.getTenantId(), edge, widgetBundleTypesRequestMsg)); + } + } + if (uplinkMsg.getEntityViewsRequestMsgCount() > 0) { + for (EntityViewsRequestMsg entityViewRequestMsg : uplinkMsg.getEntityViewsRequestMsgList()) { + result.add(ctx.getEdgeRequestsService().processEntityViewsRequestMsg(edge.getTenantId(), edge, entityViewRequestMsg)); + } + } } catch (Exception e) { log.error("[{}] Can't process uplink msg [{}]", this.sessionId, uplinkMsg, e); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeRpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeRpcService.java index ddea009849..fdd2adadd7 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeRpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeRpcService.java @@ -17,12 +17,15 @@ package org.thingsboard.server.service.edge.rpc; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; public interface EdgeRpcService { - void updateEdge(Edge edge); + void updateEdge(TenantId tenantId, Edge edge); - void deleteEdge(EdgeId edgeId); + void deleteEdge(TenantId tenantId, EdgeId edgeId); - void onEdgeEvent(EdgeId edgeId); + void onEdgeEvent(TenantId tenantId, EdgeId edgeId); + + void startSyncProcess(TenantId tenantId, EdgeId edgeId); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java new file mode 100644 index 0000000000..b232333d5d --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java @@ -0,0 +1,109 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; + +@AllArgsConstructor +@Slf4j +public class AdminSettingsEdgeEventFetcher implements EdgeEventFetcher { + + @Override + public PageLink getPageLink() { + return new PageLink(DEFAULT_LIMIT); + } + + @Override + public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { + return null; + } + + +// +// private void syncAdminSettings(TenantId tenantId, Edge edge) { +// log.trace("[{}] syncAdminSettings [{}]", tenantId, edge.getName()); +// try { +// AdminSettings systemMailSettings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"); +// saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailSettings)); +// AdminSettings tenantMailSettings = convertToTenantAdminSettings(systemMailSettings.getKey(), (ObjectNode) systemMailSettings.getJsonValue()); +// saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailSettings)); +// AdminSettings systemMailTemplates = loadMailTemplates(); +// saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailTemplates)); +// AdminSettings tenantMailTemplates = convertToTenantAdminSettings(systemMailTemplates.getKey(), (ObjectNode) systemMailTemplates.getJsonValue()); +// saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailTemplates)); +// } catch (Exception e) { +// log.error("Can't load admin settings", e); +// } +// } +// +// private AdminSettings loadMailTemplates() throws Exception { +// Map mailTemplates = new HashMap<>(); +// Pattern startPattern = Pattern.compile("
"); +// Pattern endPattern = Pattern.compile("
"); +// File[] files = new DefaultResourceLoader().getResource("classpath:/templates/").getFile().listFiles(); +// for (File file : files) { +// Map mailTemplate = new HashMap<>(); +// String name = validateName(file.getName()); +// String stringTemplate = FileUtils.readFileToString(file, StandardCharsets.UTF_8); +// Matcher start = startPattern.matcher(stringTemplate); +// Matcher end = endPattern.matcher(stringTemplate); +// if (start.find() && end.find()) { +// String body = StringUtils.substringBetween(stringTemplate, start.group(), end.group()).replaceAll("\t", ""); +// String subject = StringUtils.substringBetween(body, "

", "

"); +// mailTemplate.put("subject", subject); +// mailTemplate.put("body", body); +// mailTemplates.put(name, mailTemplate); +// } else { +// log.error("Can't load mail template from file {}", file.getName()); +// } +// } +// AdminSettings adminSettings = new AdminSettings(); +// adminSettings.setId(new AdminSettingsId(Uuids.timeBased())); +// adminSettings.setKey("mailTemplates"); +// adminSettings.setJsonValue(mapper.convertValue(mailTemplates, JsonNode.class)); +// return adminSettings; +// } +// +// private String validateName(String name) throws Exception { +// StringBuilder nameBuilder = new StringBuilder(); +// name = name.replace(".vm", ""); +// String[] nameParts = name.split("\\."); +// if (nameParts.length >= 1) { +// nameBuilder.append(nameParts[0]); +// for (int i = 1; i < nameParts.length; i++) { +// String word = WordUtils.capitalize(nameParts[i]); +// nameBuilder.append(word); +// } +// return nameBuilder.toString(); +// } else { +// throw new Exception("Error during filename validation"); +// } +// } +// +// private AdminSettings convertToTenantAdminSettings(String key, ObjectNode jsonValue) { +// AdminSettings tenantMailSettings = new AdminSettings(); +// jsonValue.put("useSystemMailSettings", true); +// tenantMailSettings.setJsonValue(jsonValue); +// tenantMailSettings.setKey(key); +// return tenantMailSettings; +// } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java new file mode 100644 index 0000000000..e2eb2e8d61 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java @@ -0,0 +1,58 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.dao.asset.AssetService; +import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; + +import java.util.ArrayList; +import java.util.List; + +@AllArgsConstructor +@Slf4j +public class AssetsEdgeEventFetcher implements EdgeEventFetcher { + + private final AssetService assetService; + + @Override + public PageLink getPageLink() { + return new PageLink(DEFAULT_LIMIT); + } + + @Override + public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); + PageData pageData = assetService.findAssetsByTenantIdAndEdgeId(tenantId, edgeId, pageLink); + List result = new ArrayList<>(); + if (!pageData.getData().isEmpty()) { + for (Asset asset : pageData.getData()) { + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.ASSET, + EdgeEventActionType.ADDED, asset.getId(), null)); + } + } + return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java new file mode 100644 index 0000000000..883f451636 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java @@ -0,0 +1,58 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.dao.user.UserService; +import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public abstract class BaseUsersEdgeEventFetcher implements EdgeEventFetcher { + + @Override + public PageLink getPageLink() { + return new PageLink(DEFAULT_LIMIT); + } + + @Override + public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); + PageData pageData = findUsers(tenantId, pageLink); + List result = new ArrayList<>(); + if (!pageData.getData().isEmpty()) { + for (User user : pageData.getData()) { + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.USER, + EdgeEventActionType.ADDED, user.getId(), null)); + } + } + return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + } + + protected abstract PageData findUsers(TenantId tenantId, PageLink pageLink); +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java new file mode 100644 index 0000000000..53c6e579d3 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java @@ -0,0 +1,55 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public abstract class BaseWidgetsBundlesEdgeEventFetcher implements EdgeEventFetcher { + + @Override + public PageLink getPageLink() { + return new PageLink(DEFAULT_LIMIT); + } + + @Override + public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); + PageData pageData = findWidgetsBundles(tenantId, pageLink); + List result = new ArrayList<>(); + if (!pageData.getData().isEmpty()) { + for (WidgetsBundle widgetsBundle : pageData.getData()) { + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.WIDGETS_BUNDLE, + EdgeEventActionType.ADDED, widgetsBundle.getId(), null)); + } + } + return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + } + + protected abstract PageData findWidgetsBundles(TenantId tenantId, PageLink pageLink); +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java new file mode 100644 index 0000000000..6775b85844 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java @@ -0,0 +1,36 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.AllArgsConstructor; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.dao.user.UserService; + +@AllArgsConstructor +public class CustomerUsersEdgeEventFetcher extends BaseUsersEdgeEventFetcher { + + private final UserService userService; + private final CustomerId customerId; + + @Override + protected PageData findUsers(TenantId tenantId, PageLink pageLink) { + return userService.findCustomerUsers(tenantId, customerId, pageLink); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java new file mode 100644 index 0000000000..515a356850 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java @@ -0,0 +1,58 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.DashboardInfo; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.dao.dashboard.DashboardService; +import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; + +import java.util.ArrayList; +import java.util.List; + +@AllArgsConstructor +@Slf4j +public class DashboardsEdgeEventFetcher implements EdgeEventFetcher { + + private final DashboardService dashboardService; + + @Override + public PageLink getPageLink() { + return new PageLink(DEFAULT_LIMIT); + } + + @Override + public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); + PageData pageData = dashboardService.findDashboardsByTenantIdAndEdgeId(tenantId, edgeId, pageLink); + List result = new ArrayList<>(); + if (!pageData.getData().isEmpty()) { + for (DashboardInfo dashboardInfo : pageData.getData()) { + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.DASHBOARD, + EdgeEventActionType.ADDED, dashboardInfo.getId(), null)); + } + } + return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java new file mode 100644 index 0000000000..fb0af06b75 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java @@ -0,0 +1,58 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.dao.device.DeviceProfileService; +import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; + +import java.util.ArrayList; +import java.util.List; + +@AllArgsConstructor +@Slf4j +public class DeviceProfilesEdgeEventFetcher implements EdgeEventFetcher { + + private final DeviceProfileService deviceProfileService; + + @Override + public PageLink getPageLink() { + return new PageLink(DEFAULT_LIMIT); + } + + @Override + public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); + PageData pageData = deviceProfileService.findDeviceProfiles(tenantId, pageLink); + List result = new ArrayList<>(); + if (!pageData.getData().isEmpty()) { + for (DeviceProfile deviceProfile : pageData.getData()) { + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.DEVICE_PROFILE, + EdgeEventActionType.ADDED, deviceProfile.getId(), null)); + } + } + return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java new file mode 100644 index 0000000000..e283b2c043 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java @@ -0,0 +1,31 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; + +public interface EdgeEventFetcher { + + final int DEFAULT_LIMIT = 100; + + PageLink getPageLink(); + + PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink); +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java new file mode 100644 index 0000000000..a87a4ebd68 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java @@ -0,0 +1,50 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.AllArgsConstructor; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.page.SortOrder; +import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.dao.edge.EdgeEventService; + +@AllArgsConstructor +public class GeneralEdgeEventFetcher implements EdgeEventFetcher { + + private final int maxReadRecordsCount; + private final Long queueStartTs; + private final EdgeEventService edgeEventService; + + @Override + public PageLink getPageLink() { + return new TimePageLink( + maxReadRecordsCount, + 0, + null, + new SortOrder("createdTime", SortOrder.Direction.ASC), + queueStartTs, + null); + } + + @Override + public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { + return edgeEventService.findEdgeEvents(tenantId, edgeId, (TimePageLink) pageLink, true); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java new file mode 100644 index 0000000000..2aca092856 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java @@ -0,0 +1,58 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.dao.rule.RuleChainService; +import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@AllArgsConstructor +public class RuleChainsEdgeEventFetcher implements EdgeEventFetcher { + + private final RuleChainService ruleChainService; + + @Override + public PageLink getPageLink() { + return new PageLink(DEFAULT_LIMIT); + } + + @Override + public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); + PageData pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edgeId, pageLink); + List result = new ArrayList<>(); + if (!pageData.getData().isEmpty()) { + for (RuleChain ruleChain : pageData.getData()) { + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.RULE_CHAIN, + EdgeEventActionType.ADDED, ruleChain.getId(), null)); + } + } + return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemWidgetsBundlesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemWidgetsBundlesEdgeEventFetcher.java new file mode 100644 index 0000000000..e32e003d4e --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemWidgetsBundlesEdgeEventFetcher.java @@ -0,0 +1,36 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.dao.widget.WidgetsBundleService; + +@Slf4j +@AllArgsConstructor +public class SystemWidgetsBundlesEdgeEventFetcher extends BaseWidgetsBundlesEdgeEventFetcher { + + private final WidgetsBundleService widgetsBundleService; + + @Override + protected PageData findWidgetsBundles(TenantId tenantId, PageLink pageLink) { + return widgetsBundleService.findSystemWidgetsBundlesByPageLink(tenantId, pageLink); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantAdminUsersEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantAdminUsersEdgeEventFetcher.java new file mode 100644 index 0000000000..018104ed31 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantAdminUsersEdgeEventFetcher.java @@ -0,0 +1,34 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.AllArgsConstructor; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.dao.user.UserService; + +@AllArgsConstructor +public class TenantAdminUsersEdgeEventFetcher extends BaseUsersEdgeEventFetcher { + + private final UserService userService; + + @Override + protected PageData findUsers(TenantId tenantId, PageLink pageLink) { + return userService.findTenantAdmins(tenantId, pageLink); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java new file mode 100644 index 0000000000..6dee9853de --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java @@ -0,0 +1,36 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.dao.widget.WidgetsBundleService; + +@Slf4j +@AllArgsConstructor +public class TenantWidgetsBundlesEdgeEventFetcher extends BaseWidgetsBundlesEdgeEventFetcher implements EdgeEventFetcher { + + private final WidgetsBundleService widgetsBundleService; + + @Override + protected PageData findWidgetsBundles(TenantId tenantId, PageLink pageLink) { + return widgetsBundleService.findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, pageLink); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/init/DefaultSyncEdgeService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java similarity index 52% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/init/DefaultSyncEdgeService.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java index 0b9afa4ccf..bccc6cedd0 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/init/DefaultSyncEdgeService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.service.edge.rpc.init; +package org.thingsboard.server.service.edge.rpc.sync; -import com.datastax.oss.driver.api.core.uuid.Uuids; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -24,34 +23,27 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.text.WordUtils; import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.DefaultResourceLoader; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.AdminSettings; -import org.thingsboard.server.common.data.DashboardInfo; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; -import org.thingsboard.server.common.data.User; -import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; -import org.thingsboard.server.common.data.id.AdminSettingsId; import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; 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.DataType; import org.thingsboard.server.common.data.page.PageData; @@ -59,44 +51,39 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelationsQuery; import org.thingsboard.server.common.data.relation.EntitySearchDirection; +import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.relation.RelationsSearchParameters; -import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetsBundle; -import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.attributes.AttributesService; -import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.relation.RelationService; -import org.thingsboard.server.dao.rule.RuleChainService; -import org.thingsboard.server.dao.settings.AdminSettingsService; -import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.widget.WidgetTypeService; import org.thingsboard.server.dao.widget.WidgetsBundleService; import org.thingsboard.server.gen.edge.AttributesRequestMsg; import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.DeviceProfileDevicesRequestMsg; +import org.thingsboard.server.gen.edge.EntityViewsRequestMsg; import org.thingsboard.server.gen.edge.RelationRequestMsg; import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg; import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.WidgetBundleTypesRequestMsg; +import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.queue.TbClusterService; -import java.io.File; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; @Service @Slf4j -public class DefaultSyncEdgeService implements SyncEdgeService { +public class DefaultEdgeRequestsService implements EdgeRequestsService { private static final ObjectMapper mapper = new ObjectMapper(); @@ -108,29 +95,17 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @Autowired private AttributesService attributesService; - @Autowired - private RuleChainService ruleChainService; - @Autowired private RelationService relationService; @Autowired private DeviceService deviceService; - @Autowired - private DeviceProfileService deviceProfileService; - - @Autowired - private AssetService assetService; - @Autowired private EntityViewService entityViewService; @Autowired - private DashboardService dashboardService; - - @Autowired - private UserService userService; + private DeviceProfileService deviceProfileService; @Autowired private WidgetsBundleService widgetsBundleService; @@ -138,309 +113,12 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @Autowired private WidgetTypeService widgetTypeService; - @Autowired - private AdminSettingsService adminSettingsService; - @Autowired private DbCallbackExecutorService dbCallbackExecutorService; @Autowired private TbClusterService tbClusterService; - @Override - public void sync(TenantId tenantId, Edge edge) { - log.trace("[{}][{}] Staring edge sync process", tenantId, edge.getId()); - try { - syncWidgetsBundles(tenantId, edge); - // TODO: voba - implement this functionality - // syncAdminSettings(edge); - syncDeviceProfiles(tenantId, edge); - syncRuleChains(tenantId, edge); - syncUsers(tenantId, edge); - syncAssets(tenantId, edge); - syncEntityViews(tenantId, edge); - syncDashboards(tenantId, edge); - syncWidgetsTypes(tenantId, edge); - syncDevices(tenantId, edge); - } catch (Exception e) { - log.error("[{}][{}] Exception during sync process", tenantId, edge.getId(), e); - } - } - - private void syncRuleChains(TenantId tenantId, Edge edge) { - log.trace("[{}] syncRuleChains [{}]", tenantId, edge.getName()); - try { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - log.trace("[{}] [{}] rule chains(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); - for (RuleChain ruleChain : pageData.getData()) { - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, EdgeEventActionType.ADDED, ruleChain.getId(), null); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - } catch (Exception e) { - log.error("Exception during loading edge rule chain(s) on sync!", e); - } - } - - private void syncDevices(TenantId tenantId, Edge edge) { - log.trace("[{}] syncDevices [{}]", tenantId, edge.getName()); - try { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = deviceService.findDevicesByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); - for (Device device : pageData.getData()) { - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ADDED, device.getId(), null); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - } catch (Exception e) { - log.error("Exception during loading edge device(s) on sync!", e); - } - } - - private void syncDeviceProfiles(TenantId tenantId, Edge edge) { - log.trace("[{}] syncDeviceProfiles [{}]", tenantId, edge.getName()); - try { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = deviceProfileService.findDeviceProfiles(tenantId, pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - log.trace("[{}] [{}] user(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); - for (DeviceProfile deviceProfile : pageData.getData()) { - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE_PROFILE, EdgeEventActionType.ADDED, deviceProfile.getId(), null); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - } catch (Exception e) { - log.error("Exception during loading device profile(s) on sync!", e); - } - } - - private void syncAssets(TenantId tenantId, Edge edge) { - log.trace("[{}] syncAssets [{}]", tenantId, edge.getName()); - try { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = assetService.findAssetsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - log.trace("[{}] [{}] asset(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); - for (Asset asset : pageData.getData()) { - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ASSET, EdgeEventActionType.ADDED, asset.getId(), null); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - } catch (Exception e) { - log.error("Exception during loading edge asset(s) on sync!", e); - } - } - - private void syncEntityViews(TenantId tenantId, Edge edge) { - log.trace("[{}] syncEntityViews [{}]", tenantId, edge.getName()); - try { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = entityViewService.findEntityViewsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - log.trace("[{}] [{}] entity view(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); - for (EntityView entityView : pageData.getData()) { - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ENTITY_VIEW, EdgeEventActionType.ADDED, entityView.getId(), null); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - } catch (Exception e) { - log.error("Exception during loading edge entity view(s) on sync!", e); - } - } - - private void syncDashboards(TenantId tenantId, Edge edge) { - log.trace("[{}] syncDashboards [{}]", tenantId, edge.getName()); - try { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = dashboardService.findDashboardsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - log.trace("[{}] [{}] dashboard(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); - for (DashboardInfo dashboardInfo : pageData.getData()) { - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DASHBOARD, EdgeEventActionType.ADDED, dashboardInfo.getId(), null); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - } catch (Exception e) { - log.error("Exception during loading edge dashboard(s) on sync!", e); - } - } - - private void syncUsers(TenantId tenantId, Edge edge) { - log.trace("[{}] syncUsers [{}]", tenantId, edge.getName()); - try { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = userService.findTenantAdmins(tenantId, pageLink); - pushUsersToEdge(tenantId, pageData, edge); - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } while (pageData.hasNext()); - syncCustomerUsers(tenantId, edge); - } catch (Exception e) { - log.error("Exception during loading edge user(s) on sync!", e); - } - } - - private void syncCustomerUsers(TenantId tenantId, Edge edge) { - if (edge.getCustomerId() != null && !EntityId.NULL_UUID.equals(edge.getCustomerId().getId())) { - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, edge.getCustomerId(), null); - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = userService.findCustomerUsers(tenantId, edge.getCustomerId(), pageLink); - pushUsersToEdge(tenantId, pageData, edge); - if (pageData != null && pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } while (pageData != null && pageData.hasNext()); - } - } - - private void pushUsersToEdge(TenantId tenantId, PageData pageData, Edge edge) { - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - log.trace("[{}] [{}] user(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); - for (User user : pageData.getData()) { - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER, EdgeEventActionType.ADDED, user.getId(), null); - } - } - } - - private void syncWidgetsBundles(TenantId tenantId, Edge edge) { - log.trace("[{}] syncWidgetsBundles [{}]", tenantId, edge.getName()); - List widgetsBundlesToPush = new ArrayList<>(); - widgetsBundlesToPush.addAll(widgetsBundleService.findAllTenantWidgetsBundlesByTenantId(tenantId)); - widgetsBundlesToPush.addAll(widgetsBundleService.findSystemWidgetsBundles(tenantId)); - try { - for (WidgetsBundle widgetsBundle : widgetsBundlesToPush) { - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGETS_BUNDLE, EdgeEventActionType.ADDED, widgetsBundle.getId(), null); - } - } catch (Exception e) { - log.error("Exception during loading widgets bundle(s) on sync!", e); - } - } - - private void syncWidgetsTypes(TenantId tenantId, Edge edge) { - log.trace("[{}] syncWidgetsTypes [{}]", tenantId, edge.getName()); - List widgetsBundlesToPush = new ArrayList<>(); - widgetsBundlesToPush.addAll(widgetsBundleService.findAllTenantWidgetsBundlesByTenantId(tenantId)); - widgetsBundlesToPush.addAll(widgetsBundleService.findSystemWidgetsBundles(tenantId)); - try { - for (WidgetsBundle widgetsBundle : widgetsBundlesToPush) { - List widgetTypesToPush = - widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(widgetsBundle.getTenantId(), widgetsBundle.getAlias()); - for (WidgetType widgetType : widgetTypesToPush) { - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGET_TYPE, EdgeEventActionType.ADDED, widgetType.getId(), null); - } - } - } catch (Exception e) { - log.error("Exception during loading widgets type(s) on sync!", e); - } - } - - private void syncAdminSettings(TenantId tenantId, Edge edge) { - log.trace("[{}] syncAdminSettings [{}]", tenantId, edge.getName()); - try { - AdminSettings systemMailSettings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"); - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailSettings)); - AdminSettings tenantMailSettings = convertToTenantAdminSettings(systemMailSettings.getKey(), (ObjectNode) systemMailSettings.getJsonValue()); - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailSettings)); - AdminSettings systemMailTemplates = loadMailTemplates(); - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailTemplates)); - AdminSettings tenantMailTemplates = convertToTenantAdminSettings(systemMailTemplates.getKey(), (ObjectNode) systemMailTemplates.getJsonValue()); - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailTemplates)); - } catch (Exception e) { - log.error("Can't load admin settings", e); - } - } - - private AdminSettings loadMailTemplates() throws Exception { - Map mailTemplates = new HashMap<>(); - Pattern startPattern = Pattern.compile("
"); - Pattern endPattern = Pattern.compile("
"); - File[] files = new DefaultResourceLoader().getResource("classpath:/templates/").getFile().listFiles(); - for (File file : files) { - Map mailTemplate = new HashMap<>(); - String name = validateName(file.getName()); - String stringTemplate = FileUtils.readFileToString(file, StandardCharsets.UTF_8); - Matcher start = startPattern.matcher(stringTemplate); - Matcher end = endPattern.matcher(stringTemplate); - if (start.find() && end.find()) { - String body = StringUtils.substringBetween(stringTemplate, start.group(), end.group()).replaceAll("\t", ""); - String subject = StringUtils.substringBetween(body, "

", "

"); - mailTemplate.put("subject", subject); - mailTemplate.put("body", body); - mailTemplates.put(name, mailTemplate); - } else { - log.error("Can't load mail template from file {}", file.getName()); - } - } - AdminSettings adminSettings = new AdminSettings(); - adminSettings.setId(new AdminSettingsId(Uuids.timeBased())); - adminSettings.setKey("mailTemplates"); - adminSettings.setJsonValue(mapper.convertValue(mailTemplates, JsonNode.class)); - return adminSettings; - } - - private String validateName(String name) throws Exception { - StringBuilder nameBuilder = new StringBuilder(); - name = name.replace(".vm", ""); - String[] nameParts = name.split("\\."); - if (nameParts.length >= 1) { - nameBuilder.append(nameParts[0]); - for (int i = 1; i < nameParts.length; i++) { - String word = WordUtils.capitalize(nameParts[i]); - nameBuilder.append(word); - } - return nameBuilder.toString(); - } else { - throw new Exception("Error during filename validation"); - } - } - - private AdminSettings convertToTenantAdminSettings(String key, ObjectNode jsonValue) { - AdminSettings tenantMailSettings = new AdminSettings(); - jsonValue.put("useSystemMailSettings", true); - tenantMailSettings.setJsonValue(jsonValue); - tenantMailSettings.setKey(key); - return tenantMailSettings; - } - @Override public ListenableFuture processRuleChainMetadataRequestMsg(TenantId tenantId, Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) { log.trace("[{}] processRuleChainMetadataRequestMsg [{}][{}]", tenantId, edge.getName(), ruleChainMetadataRequestMsg); @@ -448,7 +126,8 @@ public class DefaultSyncEdgeService implements SyncEdgeService { if (ruleChainMetadataRequestMsg.getRuleChainIdMSB() != 0 && ruleChainMetadataRequestMsg.getRuleChainIdLSB() != 0) { RuleChainId ruleChainId = new RuleChainId(new UUID(ruleChainMetadataRequestMsg.getRuleChainIdMSB(), ruleChainMetadataRequestMsg.getRuleChainIdLSB())); - ListenableFuture future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN_METADATA, EdgeEventActionType.ADDED, ruleChainId, null); + ListenableFuture future = saveEdgeEvent(tenantId, edge.getId(), + EdgeEventType.RULE_CHAIN_METADATA, EdgeEventActionType.ADDED, ruleChainId, null); Futures.addCallback(future, new FutureCallback() { @Override public void onSuccess(@Nullable EdgeEvent result) { @@ -584,7 +263,8 @@ public class DefaultSyncEdgeService implements SyncEdgeService { return futureToSet; } - private ListenableFuture> findRelationByQuery(TenantId tenantId, Edge edge, EntityId entityId, EntitySearchDirection direction) { + private ListenableFuture> findRelationByQuery(TenantId tenantId, Edge edge, + EntityId entityId, EntitySearchDirection direction) { EntityRelationsQuery query = new EntityRelationsQuery(); query.setParameters(new RelationsSearchParameters(entityId, direction, -1, false)); return relationService.findByQuery(tenantId, query); @@ -596,7 +276,8 @@ public class DefaultSyncEdgeService implements SyncEdgeService { SettableFuture futureToSet = SettableFuture.create(); if (deviceCredentialsRequestMsg.getDeviceIdMSB() != 0 && deviceCredentialsRequestMsg.getDeviceIdLSB() != 0) { DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsRequestMsg.getDeviceIdMSB(), deviceCredentialsRequestMsg.getDeviceIdLSB())); - ListenableFuture future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_UPDATED, deviceId, null); + ListenableFuture future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, + EdgeEventActionType.CREDENTIALS_UPDATED, deviceId, null); Futures.addCallback(future, new FutureCallback() { @Override public void onSuccess(@Nullable EdgeEvent result) { @@ -619,8 +300,9 @@ public class DefaultSyncEdgeService implements SyncEdgeService { SettableFuture futureToSet = SettableFuture.create(); if (userCredentialsRequestMsg.getUserIdMSB() != 0 && userCredentialsRequestMsg.getUserIdLSB() != 0) { UserId userId = new UserId(new UUID(userCredentialsRequestMsg.getUserIdMSB(), userCredentialsRequestMsg.getUserIdLSB())); - ListenableFuture future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER, EdgeEventActionType.CREDENTIALS_UPDATED, userId, null); - Futures.addCallback(future, new FutureCallback() { + ListenableFuture future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER, + EdgeEventActionType.CREDENTIALS_UPDATED, userId, null); + Futures.addCallback(future, new FutureCallback<>() { @Override public void onSuccess(@Nullable EdgeEvent result) { futureToSet.set(null); @@ -636,6 +318,139 @@ public class DefaultSyncEdgeService implements SyncEdgeService { return futureToSet; } + @Override + public ListenableFuture processDeviceProfileDevicesRequestMsg(TenantId tenantId, Edge edge, DeviceProfileDevicesRequestMsg deviceProfileDevicesRequestMsg) { + log.trace("[{}] processDeviceProfileDevicesRequestMsg [{}][{}]", tenantId, edge.getName(), deviceProfileDevicesRequestMsg); + SettableFuture futureToSet = SettableFuture.create(); + if (deviceProfileDevicesRequestMsg.getDeviceProfileIdMSB() != 0 && deviceProfileDevicesRequestMsg.getDeviceProfileIdLSB() != 0) { + DeviceProfileId deviceProfileId = new DeviceProfileId(new UUID(deviceProfileDevicesRequestMsg.getDeviceProfileIdMSB(), deviceProfileDevicesRequestMsg.getDeviceProfileIdLSB())); + DeviceProfile deviceProfileById = deviceProfileService.findDeviceProfileById(tenantId, deviceProfileId); + List> futures; + if (deviceProfileById != null) { + futures = syncDevices(tenantId, edge, deviceProfileById.getName()); + } else { + futures = new ArrayList<>(); + } + Futures.addCallback(Futures.allAsList(futures), new FutureCallback<>() { + @Override + public void onSuccess(@Nullable List result) { + futureToSet.set(null); + } + + @Override + public void onFailure(Throwable t) { + log.error("Can't sync devices by device profile [{}]", deviceProfileDevicesRequestMsg, t); + futureToSet.setException(t); + } + }, dbCallbackExecutorService); + } + return futureToSet; + } + + private List> syncDevices(TenantId tenantId, Edge edge, String deviceType) { + List> futures = new ArrayList<>(); + log.trace("[{}] syncDevices [{}][{}]", tenantId, edge.getName(), deviceType); + try { + PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageData pageData; + do { + pageData = deviceService.findDevicesByTenantIdAndEdgeIdAndType(tenantId, edge.getId(), deviceType, pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); + for (Device device : pageData.getData()) { + futures.add(saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ADDED, device.getId(), null)); + } + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } + } while (pageData != null && pageData.hasNext()); + } catch (Exception e) { + log.error("Exception during loading edge device(s) on sync!", e); + } + return futures; + } + + @Override + public ListenableFuture processWidgetBundleTypesRequestMsg(TenantId tenantId, Edge edge, + WidgetBundleTypesRequestMsg widgetBundleTypesRequestMsg) { + log.trace("[{}] processWidgetBundleTypesRequestMsg [{}][{}]", tenantId, edge.getName(), widgetBundleTypesRequestMsg); + SettableFuture futureToSet = SettableFuture.create(); + if (widgetBundleTypesRequestMsg.getWidgetBundleIdMSB() != 0 && widgetBundleTypesRequestMsg.getWidgetBundleIdLSB() != 0) { + WidgetsBundleId widgetsBundleId = new WidgetsBundleId(new UUID(widgetBundleTypesRequestMsg.getWidgetBundleIdMSB(), widgetBundleTypesRequestMsg.getWidgetBundleIdLSB())); + WidgetsBundle widgetsBundleById = widgetsBundleService.findWidgetsBundleById(tenantId, widgetsBundleId); + List> futures = new ArrayList<>(); + if (widgetsBundleById != null) { + List widgetTypesToPush = + widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(widgetsBundleById.getTenantId(), widgetsBundleById.getAlias()); + + for (WidgetType widgetType : widgetTypesToPush) { + futures.add(saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGET_TYPE, EdgeEventActionType.ADDED, widgetType.getId(), null)); + } + } + Futures.addCallback(Futures.allAsList(futures), new FutureCallback<>() { + @Override + public void onSuccess(@Nullable List result) { + futureToSet.set(null); + } + + @Override + public void onFailure(Throwable t) { + log.error("Can't sync widget types by widget bundle [{}]", widgetBundleTypesRequestMsg, t); + futureToSet.setException(t); + } + }, dbCallbackExecutorService); + } + return futureToSet; + } + + @Override + public ListenableFuture processEntityViewsRequestMsg(TenantId tenantId, Edge edge, EntityViewsRequestMsg entityViewsRequestMsg) { + log.trace("[{}] processEntityViewsRequestMsg [{}][{}]", tenantId, edge.getName(), entityViewsRequestMsg); + EntityId entityId = EntityIdFactory.getByTypeAndUuid( + EntityType.valueOf(entityViewsRequestMsg.getEntityType()), + new UUID(entityViewsRequestMsg.getEntityIdMSB(), entityViewsRequestMsg.getEntityIdLSB())); + SettableFuture futureToSet = SettableFuture.create(); + Futures.addCallback(entityViewService.findEntityViewsByTenantIdAndEntityIdAsync(tenantId, entityId), new FutureCallback<>() { + @Override + public void onSuccess(@Nullable List entityViews) { + try { + if (entityViews != null && !entityViews.isEmpty()) { + for (EntityView entityView : entityViews) { + Futures.addCallback(relationService.checkRelation(tenantId, edge.getId(), entityView.getId(), + EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE), new FutureCallback<>() { + @Override + public void onSuccess(@Nullable Boolean result) { + if (Boolean.TRUE.equals(result)) { + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ENTITY_VIEW, + EdgeEventActionType.ADDED, entityView.getId(), null); + } + } + + @Override + public void onFailure(Throwable t) { + log.error("Exception during loading relation [{}] to edge on sync!", t, t); + futureToSet.setException(t); + } + }, dbCallbackExecutorService); + } + } + futureToSet.set(null); + } catch (Exception e) { + log.error("Exception during loading relation(s) to edge on sync!", e); + futureToSet.setException(e); + } + } + + @Override + public void onFailure(Throwable t) { + log.error("[{}] Can't find entity views by entity id [{}]", tenantId, entityId, t); + futureToSet.setException(t); + } + }, dbCallbackExecutorService); + return futureToSet; + } + private ListenableFuture saveEdgeEvent(TenantId tenantId, EdgeId edgeId, EdgeEventType type, @@ -645,17 +460,10 @@ public class DefaultSyncEdgeService implements SyncEdgeService { log.trace("Pushing edge event to edge queue. tenantId [{}], edgeId [{}], type [{}], action[{}], entityId [{}], body [{}]", tenantId, edgeId, type, action, entityId, body); - EdgeEvent edgeEvent = new EdgeEvent(); - edgeEvent.setTenantId(tenantId); - edgeEvent.setEdgeId(edgeId); - edgeEvent.setType(type); - edgeEvent.setAction(action); - if (entityId != null) { - edgeEvent.setEntityId(entityId.getId()); - } - edgeEvent.setBody(body); + EdgeEvent edgeEvent = EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, type, action, entityId, body); + ListenableFuture future = edgeEventService.saveAsync(edgeEvent); - Futures.addCallback(future, new FutureCallback() { + Futures.addCallback(future, new FutureCallback<>() { @Override public void onSuccess(@Nullable EdgeEvent result) { tbClusterService.onEdgeEventUpdate(tenantId, edgeId); @@ -668,4 +476,5 @@ public class DefaultSyncEdgeService implements SyncEdgeService { }, dbCallbackExecutorService); return future; } + } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/init/SyncEdgeService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/EdgeRequestsService.java similarity index 71% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/init/SyncEdgeService.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/EdgeRequestsService.java index e95809d019..6e8caf6383 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/init/SyncEdgeService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/EdgeRequestsService.java @@ -13,20 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.service.edge.rpc.init; +package org.thingsboard.server.service.edge.rpc.sync; import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.gen.edge.AttributesRequestMsg; import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.DeviceProfileDevicesRequestMsg; +import org.thingsboard.server.gen.edge.EntityViewsRequestMsg; import org.thingsboard.server.gen.edge.RelationRequestMsg; import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg; import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.WidgetBundleTypesRequestMsg; -public interface SyncEdgeService { - - void sync(TenantId tenantId, Edge edge); +public interface EdgeRequestsService { ListenableFuture processRuleChainMetadataRequestMsg(TenantId tenantId, Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg); @@ -37,4 +38,10 @@ public interface SyncEdgeService { ListenableFuture processDeviceCredentialsRequestMsg(TenantId tenantId, Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg); ListenableFuture processUserCredentialsRequestMsg(TenantId tenantId, Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg); + + ListenableFuture processDeviceProfileDevicesRequestMsg(TenantId tenantId, Edge edge, DeviceProfileDevicesRequestMsg deviceProfileDevicesRequestMsg); + + ListenableFuture processWidgetBundleTypesRequestMsg(TenantId tenantId, Edge edge, WidgetBundleTypesRequestMsg widgetBundleTypesRequestMsg); + + ListenableFuture processEntityViewsRequestMsg(TenantId tenantId, Edge edge, EntityViewsRequestMsg entityViewsRequestMsg); } diff --git a/application/src/main/resources/logback.xml b/application/src/main/resources/logback.xml index b2f19748b6..f34d90876c 100644 --- a/application/src/main/resources/logback.xml +++ b/application/src/main/resources/logback.xml @@ -27,6 +27,7 @@ + diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java index 92548bb621..120b6007cf 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -191,7 +191,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { @Test public void test() throws Exception { testReceivedInitialData(); - int expectedDownlinkSize = 10; + int expectedDownlinkSize = 9; Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testDevices(); @@ -308,7 +308,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { private void testReceivedInitialData() throws Exception { log.info("Checking received data"); - Assert.assertTrue(edgeImitator.waitForMessages()); + boolean condition = edgeImitator.waitForMessages(); + Assert.assertTrue(condition); EdgeConfiguration configuration = edgeImitator.getConfiguration(); Assert.assertNotNull(configuration); @@ -1523,6 +1524,10 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { private void installation() throws Exception { edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); + Device savedDeviceDefault = saveDevice("Edge Device Default", "Default"); + doPost("/api/edge/" + edge.getId().getId().toString() + + "/device/" + savedDeviceDefault.getId().getId().toString(), Device.class); + DeviceProfile deviceProfile = this.createDeviceProfile(CUSTOM_DEVICE_PROFILE_NAME, null); extendDeviceProfileData(deviceProfile); doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index 6b4234f151..3717f16d06 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -109,7 +109,7 @@ public class EdgeImitator { this::onDownlink, this::onClose); - edgeRpcClient.sendSyncRequestMsg(); + edgeRpcClient.sendSyncRequestMsg(false); } public void disconnect() throws InterruptedException { diff --git a/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java b/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java index c5099069ee..aeb4c38ee4 100644 --- a/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java +++ b/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java @@ -34,6 +34,7 @@ import org.thingsboard.server.gen.edge.EdgeRpcServiceGrpc; import org.thingsboard.server.gen.edge.RequestMsg; import org.thingsboard.server.gen.edge.RequestMsgType; import org.thingsboard.server.gen.edge.ResponseMsg; +import org.thingsboard.server.gen.edge.SyncRequestMsg; import org.thingsboard.server.gen.edge.UplinkMsg; import org.thingsboard.server.gen.edge.UplinkResponseMsg; @@ -102,7 +103,7 @@ public class EdgeGrpcClient implements EdgeRpcClient { Consumer onEdgeUpdate, Consumer onDownlink, Consumer onError) { - return new StreamObserver() { + return new StreamObserver<>() { @Override public void onNext(ResponseMsg responseMsg) { if (responseMsg.hasConnectResponseMsg()) { @@ -195,11 +196,13 @@ public class EdgeGrpcClient implements EdgeRpcClient { } @Override - public void sendSyncRequestMsg() { + public void sendSyncRequestMsg(boolean syncRequired) { try { uplinkMsgLock.lock(); + SyncRequestMsg syncRequestMsg = SyncRequestMsg.newBuilder().setSyncRequired(syncRequired).build(); this.inputStream.onNext(RequestMsg.newBuilder() .setMsgType(RequestMsgType.SYNC_REQUEST_RPC_MESSAGE) + .setSyncRequestMsg(syncRequestMsg) .build()); } finally { uplinkMsgLock.unlock(); diff --git a/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeRpcClient.java b/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeRpcClient.java index b3928819a1..83ff20828b 100644 --- a/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeRpcClient.java +++ b/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeRpcClient.java @@ -34,7 +34,7 @@ public interface EdgeRpcClient { void disconnect(boolean onError) throws InterruptedException; - void sendSyncRequestMsg(); + void sendSyncRequestMsg(boolean syncRequired); void sendUplinkMsg(UplinkMsg uplinkMsg); diff --git a/common/edge-api/src/main/proto/edge.proto b/common/edge-api/src/main/proto/edge.proto index 9b50b628fd..a630e64066 100644 --- a/common/edge-api/src/main/proto/edge.proto +++ b/common/edge-api/src/main/proto/edge.proto @@ -38,6 +38,7 @@ message RequestMsg { ConnectRequestMsg connectRequestMsg = 2; UplinkMsg uplinkMsg = 3; DownlinkResponseMsg downlinkResponseMsg = 4; + SyncRequestMsg syncRequestMsg = 5; } message ResponseMsg { @@ -74,6 +75,13 @@ message ConnectResponseMsg { EdgeConfiguration configuration = 3; } +message SyncRequestMsg { + bool syncRequired = 1; +} + +message SyncCompletedMsg { +} + message EdgeConfiguration { int64 edgeIdMSB = 1; int64 edgeIdLSB = 2; @@ -358,6 +366,22 @@ message DeviceCredentialsRequestMsg { int64 deviceIdLSB = 2; } +message DeviceProfileDevicesRequestMsg { + int64 deviceProfileIdMSB = 1; + int64 deviceProfileIdLSB = 2; +} + +message WidgetBundleTypesRequestMsg { + int64 widgetBundleIdMSB = 1; + int64 widgetBundleIdLSB = 2; +} + +message EntityViewsRequestMsg { + int64 entityIdMSB = 1; + int64 entityIdLSB = 2; + string entityType = 3; +} + message DeviceRpcCallMsg { int64 deviceIdMSB = 1; int64 deviceIdLSB = 2; @@ -402,6 +426,9 @@ message UplinkMsg { repeated UserCredentialsRequestMsg userCredentialsRequestMsg = 10; repeated DeviceCredentialsRequestMsg deviceCredentialsRequestMsg = 11; repeated DeviceRpcCallMsg deviceRpcCallMsg = 12; + repeated DeviceProfileDevicesRequestMsg deviceProfileDevicesRequestMsg = 13; + repeated WidgetBundleTypesRequestMsg widgetBundleTypesRequestMsg = 14; + repeated EntityViewsRequestMsg entityViewsRequestMsg = 15; } message UplinkResponseMsg { @@ -416,24 +443,25 @@ message DownlinkResponseMsg { message DownlinkMsg { int32 downlinkMsgId = 1; - repeated EntityDataProto entityData = 2; - repeated DeviceCredentialsRequestMsg deviceCredentialsRequestMsg = 3; - repeated DeviceUpdateMsg deviceUpdateMsg = 4; - repeated DeviceProfileUpdateMsg deviceProfileUpdateMsg = 5; - repeated DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg = 6; - repeated RuleChainUpdateMsg ruleChainUpdateMsg = 7; - repeated RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = 8; - repeated DashboardUpdateMsg dashboardUpdateMsg = 9; - repeated AssetUpdateMsg assetUpdateMsg = 10; - repeated EntityViewUpdateMsg entityViewUpdateMsg = 11; - repeated AlarmUpdateMsg alarmUpdateMsg = 12; - repeated UserUpdateMsg userUpdateMsg = 13; - repeated UserCredentialsUpdateMsg userCredentialsUpdateMsg = 14; - repeated CustomerUpdateMsg customerUpdateMsg = 15; - repeated RelationUpdateMsg relationUpdateMsg = 16; - repeated WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = 17; - repeated WidgetTypeUpdateMsg widgetTypeUpdateMsg = 18; - repeated AdminSettingsUpdateMsg adminSettingsUpdateMsg = 19; - repeated DeviceRpcCallMsg deviceRpcCallMsg = 20; + SyncCompletedMsg syncCompletedMsg = 2; + repeated EntityDataProto entityData = 3; + repeated DeviceCredentialsRequestMsg deviceCredentialsRequestMsg = 4; + repeated DeviceUpdateMsg deviceUpdateMsg = 5; + repeated DeviceProfileUpdateMsg deviceProfileUpdateMsg = 6; + repeated DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg = 7; + repeated RuleChainUpdateMsg ruleChainUpdateMsg = 8; + repeated RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = 9; + repeated DashboardUpdateMsg dashboardUpdateMsg = 10; + repeated AssetUpdateMsg assetUpdateMsg = 11; + repeated EntityViewUpdateMsg entityViewUpdateMsg = 12; + repeated AlarmUpdateMsg alarmUpdateMsg = 13; + repeated UserUpdateMsg userUpdateMsg = 14; + repeated UserCredentialsUpdateMsg userCredentialsUpdateMsg = 15; + repeated CustomerUpdateMsg customerUpdateMsg = 16; + repeated RelationUpdateMsg relationUpdateMsg = 17; + repeated WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = 18; + repeated WidgetTypeUpdateMsg widgetTypeUpdateMsg = 19; + repeated AdminSettingsUpdateMsg adminSettingsUpdateMsg = 20; + repeated DeviceRpcCallMsg deviceRpcCallMsg = 21; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index 2ff7d94f43..d9e70bb68b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -558,6 +558,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic if (userById.getCustomerId() == null || userById.getCustomerId().isNullUid()) { pageData = findEdgesByTenantId(tenantId, pageLink); } else { +// pageData = findEdgesByTenantIdAndCustomerId(tenantId, userById.getCustomerId(), pageLink); pageData = findEdgesByTenantIdAndCustomerId(tenantId, new CustomerId(entityId.getId()), pageLink); } if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { From 690bdcc85fecb72486e634fe316e4b0e90ccd825 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 12 May 2021 19:49:53 +0300 Subject: [PATCH 02/52] Fixed new user added and not assigned to edge. Added new user test and entity view request test --- .../service/edge/rpc/EdgeGrpcService.java | 2 +- .../thingsboard/server/edge/BaseEdgeTest.java | 104 ++++++++++++------ .../server/edge/imitator/EdgeImitator.java | 46 ++++---- .../server/dao/edge/EdgeServiceImpl.java | 3 +- 4 files changed, 92 insertions(+), 63 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 59b22864bd..9cc93dd28f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -189,7 +189,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i private void onEdgeConnect(EdgeId edgeId, EdgeGrpcSession edgeGrpcSession) { log.info("[{}] edge [{}] connected successfully.", edgeGrpcSession.getSessionId(), edgeId); sessions.put(edgeId, edgeGrpcSession); - sessionNewEvents.put(edgeId, false); + sessionNewEvents.put(edgeId, true); save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, true); save(edgeId, DefaultDeviceStateService.LAST_CONNECT_TIME, System.currentTimeMillis()); cancelScheduleEdgeEventsCheck(edgeId); diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java index 120b6007cf..3953b6c642 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -100,6 +100,7 @@ import org.thingsboard.server.gen.edge.DeviceUpdateMsg; import org.thingsboard.server.gen.edge.EdgeConfiguration; import org.thingsboard.server.gen.edge.EntityDataProto; import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; +import org.thingsboard.server.gen.edge.EntityViewsRequestMsg; import org.thingsboard.server.gen.edge.RelationRequestMsg; import org.thingsboard.server.gen.edge.RelationUpdateMsg; import org.thingsboard.server.gen.edge.RpcResponseMsg; @@ -110,6 +111,7 @@ import org.thingsboard.server.gen.edge.UpdateMsgType; import org.thingsboard.server.gen.edge.UplinkMsg; import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.UserUpdateMsg; import org.thingsboard.server.gen.edge.WidgetTypeUpdateMsg; import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; import org.thingsboard.server.gen.transport.TransportProtos; @@ -172,7 +174,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { edgeImitator = new EdgeImitator("localhost", 7070, edge.getRoutingKey(), edge.getSecret()); // TODO: voba - should be less, but events from SyncEdgeService stack with events from controller. will be fixed in next releases // so ideally sync process should check current edge queue and add only missing entities to the edge queue - edgeImitator.expectMessageAmount(10); + edgeImitator.expectMessageAmount(9); edgeImitator.connect(); } @@ -219,11 +221,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testEntityView(); - expectedDownlinkSize = expectedDownlinkSize + 2; + expectedDownlinkSize = expectedDownlinkSize + 3; Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); - testCustomer(); - expectedDownlinkSize = expectedDownlinkSize + 2; + testCustomerAndNewUser(); + expectedDownlinkSize = expectedDownlinkSize + 3; Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testWidgetsBundleAndWidgetType(); @@ -316,9 +318,6 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { testAutoGeneratedCodeByProtobuf(configuration); - UserId userId = edgeImitator.getUserId(); - Assert.assertNotNull(userId); - Optional deviceUpdateMsgOpt = edgeImitator.findMessageByType(DeviceUpdateMsg.class); Assert.assertTrue(deviceUpdateMsgOpt.isPresent()); DeviceUpdateMsg deviceUpdateMsg = deviceUpdateMsgOpt.get(); @@ -362,7 +361,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Optional ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); UUID ruleChainUUID = new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB()); RuleChain ruleChain = doGet("/api/ruleChain/" + ruleChainUUID.toString(), RuleChain.class); Assert.assertNotNull(ruleChain); @@ -798,31 +797,41 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { doPost("/api/edge/" + edge.getId().getId().toString() + "/entityView/" + savedEntityView.getId().getId().toString(), EntityView.class); Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); - EntityViewUpdateMsg entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, entityViewUpdateMsg.getMsgType()); - Assert.assertEquals(entityViewUpdateMsg.getType(), savedEntityView.getType()); - Assert.assertEquals(entityViewUpdateMsg.getName(), savedEntityView.getName()); - Assert.assertEquals(entityViewUpdateMsg.getIdMSB(), savedEntityView.getUuidId().getMostSignificantBits()); - Assert.assertEquals(entityViewUpdateMsg.getIdLSB(), savedEntityView.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(entityViewUpdateMsg.getEntityIdMSB(), device.getUuidId().getMostSignificantBits()); - Assert.assertEquals(entityViewUpdateMsg.getEntityIdLSB(), device.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(entityViewUpdateMsg.getEntityType().name(), device.getId().getEntityType().name()); + verifyEntityViewUpdateMsg(savedEntityView, device); + // 2 + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + EntityViewsRequestMsg.Builder entityViewsRequestBuilder = EntityViewsRequestMsg.newBuilder(); + entityViewsRequestBuilder.setEntityIdMSB(device.getUuidId().getMostSignificantBits()); + entityViewsRequestBuilder.setEntityIdLSB(device.getUuidId().getLeastSignificantBits()); + entityViewsRequestBuilder.setEntityType(device.getId().getEntityType().name()); + testAutoGeneratedCodeByProtobuf(entityViewsRequestBuilder); + uplinkMsgBuilder.addEntityViewsRequestMsg(entityViewsRequestBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + verifyEntityViewUpdateMsg(savedEntityView, device); + + + // 3 edgeImitator.expectMessageAmount(1); doDelete("/api/edge/" + edge.getId().getId().toString() + "/entityView/" + savedEntityView.getId().getId().toString(), EntityView.class); Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); - entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; + EntityViewUpdateMsg entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, entityViewUpdateMsg.getMsgType()); Assert.assertEquals(entityViewUpdateMsg.getIdMSB(), savedEntityView.getUuidId().getMostSignificantBits()); Assert.assertEquals(entityViewUpdateMsg.getIdLSB(), savedEntityView.getUuidId().getLeastSignificantBits()); - // 3 + edgeImitator.expectMessageAmount(1); doDelete("/api/entityView/" + savedEntityView.getId().getId().toString()) .andExpect(status().isOk()); @@ -831,7 +840,21 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { log.info("EntityView tested successfully"); } - private void testCustomer() throws Exception { + private void verifyEntityViewUpdateMsg(EntityView entityView, Device device) { + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); + EntityViewUpdateMsg entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, entityViewUpdateMsg.getMsgType()); + Assert.assertEquals(entityViewUpdateMsg.getType(), entityView.getType()); + Assert.assertEquals(entityViewUpdateMsg.getName(), entityView.getName()); + Assert.assertEquals(entityViewUpdateMsg.getIdMSB(), entityView.getUuidId().getMostSignificantBits()); + Assert.assertEquals(entityViewUpdateMsg.getIdLSB(), entityView.getUuidId().getLeastSignificantBits()); + Assert.assertEquals(entityViewUpdateMsg.getEntityIdMSB(), device.getUuidId().getMostSignificantBits()); + Assert.assertEquals(entityViewUpdateMsg.getEntityIdLSB(), device.getUuidId().getLeastSignificantBits()); + Assert.assertEquals(entityViewUpdateMsg.getEntityType().name(), device.getId().getEntityType().name()); + } + + private void testCustomerAndNewUser() throws Exception { log.info("Testing Customer"); // 1 @@ -853,6 +876,26 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { // 2 edgeImitator.expectMessageAmount(1); + User customerUser = new User(); + customerUser.setAuthority(Authority.CUSTOMER_USER); + customerUser.setTenantId(savedTenant.getId()); + customerUser.setCustomerId(savedCustomer.getId()); + customerUser.setEmail("customerUser@thingsboard.org"); + customerUser.setFirstName("John"); + customerUser.setLastName("Edwards"); + User savedUser = doPost("/api/user", customerUser, User.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof UserUpdateMsg); + UserUpdateMsg userUpdateMsg = (UserUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, userUpdateMsg.getMsgType()); + Assert.assertEquals(userUpdateMsg.getIdMSB(), savedUser.getUuidId().getMostSignificantBits()); + Assert.assertEquals(userUpdateMsg.getIdLSB(), savedUser.getUuidId().getLeastSignificantBits()); + Assert.assertEquals(userUpdateMsg.getEmail(), savedUser.getEmail()); + testAutoGeneratedCodeByProtobuf(userUpdateMsg); + + // 3 + edgeImitator.expectMessageAmount(1); doDelete("/api/customer/edge/" + edge.getId().getId().toString(), Edge.class); Assert.assertTrue(edgeImitator.waitForMessages()); latestMessage = edgeImitator.getLatestMessage(); @@ -862,7 +905,6 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(customerUpdateMsg.getIdMSB(), savedCustomer.getUuidId().getMostSignificantBits()); Assert.assertEquals(customerUpdateMsg.getIdLSB(), savedCustomer.getUuidId().getLeastSignificantBits()); - // 3 edgeImitator.expectMessageAmount(1); doDelete("/api/customer/" + savedCustomer.getId().getId().toString()) .andExpect(status().isOk()); @@ -1352,12 +1394,10 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { } private void sendUserCredentialsRequest() throws Exception { - UserId userId = edgeImitator.getUserId(); - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); UserCredentialsRequestMsg.Builder userCredentialsRequestMsgBuilder = UserCredentialsRequestMsg.newBuilder(); - userCredentialsRequestMsgBuilder.setUserIdMSB(userId.getId().getMostSignificantBits()); - userCredentialsRequestMsgBuilder.setUserIdLSB(userId.getId().getLeastSignificantBits()); + userCredentialsRequestMsgBuilder.setUserIdMSB(tenantAdmin.getId().getId().getMostSignificantBits()); + userCredentialsRequestMsgBuilder.setUserIdLSB(tenantAdmin.getId().getId().getLeastSignificantBits()); testAutoGeneratedCodeByProtobuf(userCredentialsRequestMsgBuilder); uplinkMsgBuilder.addUserCredentialsRequestMsg(userCredentialsRequestMsgBuilder.build()); @@ -1372,8 +1412,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { AbstractMessage latestMessage = edgeImitator.getLatestMessage(); Assert.assertTrue(latestMessage instanceof UserCredentialsUpdateMsg); UserCredentialsUpdateMsg userCredentialsUpdateMsg = (UserCredentialsUpdateMsg) latestMessage; - Assert.assertEquals(userCredentialsUpdateMsg.getUserIdMSB(), userId.getId().getMostSignificantBits()); - Assert.assertEquals(userCredentialsUpdateMsg.getUserIdLSB(), userId.getId().getLeastSignificantBits()); + Assert.assertEquals(userCredentialsUpdateMsg.getUserIdMSB(), tenantAdmin.getId().getId().getMostSignificantBits()); + Assert.assertEquals(userCredentialsUpdateMsg.getUserIdLSB(), tenantAdmin.getId().getId().getLeastSignificantBits()); testAutoGeneratedCodeByProtobuf(userCredentialsUpdateMsg); } @@ -1524,10 +1564,6 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { private void installation() throws Exception { edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); - Device savedDeviceDefault = saveDevice("Edge Device Default", "Default"); - doPost("/api/edge/" + edge.getId().getId().toString() - + "/device/" + savedDeviceDefault.getId().getId().toString(), Device.class); - DeviceProfile deviceProfile = this.createDeviceProfile(CUSTOM_DEVICE_PROFILE_NAME, null); extendDeviceProfileData(deviceProfile); doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index 3717f16d06..7625647144 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -54,7 +54,6 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; @@ -109,7 +108,7 @@ public class EdgeImitator { this::onDownlink, this::onClose); - edgeRpcClient.sendSyncRequestMsg(false); + edgeRpcClient.sendSyncRequestMsg(true); } public void disconnect() throws InterruptedException { @@ -129,13 +128,9 @@ public class EdgeImitator { this.configuration = edgeConfiguration; } - private void onUserUpdate(UserUpdateMsg userUpdateMsg) { - this.userId = new UserId(new UUID(userUpdateMsg.getIdMSB(), userUpdateMsg.getIdLSB())); - } - private void onDownlink(DownlinkMsg downlinkMsg) { ListenableFuture> future = processDownlinkMsg(downlinkMsg); - Futures.addCallback(future, new FutureCallback>() { + Futures.addCallback(future, new FutureCallback<>() { @Override public void onSuccess(@Nullable List result) { DownlinkResponseMsg downlinkResponseMsg = DownlinkResponseMsg.newBuilder().setSuccess(true).build(); @@ -157,7 +152,7 @@ public class EdgeImitator { private ListenableFuture> processDownlinkMsg(DownlinkMsg downlinkMsg) { List> result = new ArrayList<>(); if (downlinkMsg.getDeviceUpdateMsgCount() > 0) { - for (DeviceUpdateMsg deviceUpdateMsg: downlinkMsg.getDeviceUpdateMsgList()) { + for (DeviceUpdateMsg deviceUpdateMsg : downlinkMsg.getDeviceUpdateMsgList()) { result.add(saveDownlinkMsg(deviceUpdateMsg)); } } @@ -167,83 +162,82 @@ public class EdgeImitator { } } if (downlinkMsg.getDeviceCredentialsUpdateMsgCount() > 0) { - for (DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg: downlinkMsg.getDeviceCredentialsUpdateMsgList()) { + for (DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg : downlinkMsg.getDeviceCredentialsUpdateMsgList()) { result.add(saveDownlinkMsg(deviceCredentialsUpdateMsg)); } } if (downlinkMsg.getAssetUpdateMsgCount() > 0) { - for (AssetUpdateMsg assetUpdateMsg: downlinkMsg.getAssetUpdateMsgList()) { + for (AssetUpdateMsg assetUpdateMsg : downlinkMsg.getAssetUpdateMsgList()) { result.add(saveDownlinkMsg(assetUpdateMsg)); } } if (downlinkMsg.getRuleChainUpdateMsgCount() > 0) { - for (RuleChainUpdateMsg ruleChainUpdateMsg: downlinkMsg.getRuleChainUpdateMsgList()) { + for (RuleChainUpdateMsg ruleChainUpdateMsg : downlinkMsg.getRuleChainUpdateMsgList()) { result.add(saveDownlinkMsg(ruleChainUpdateMsg)); } } if (downlinkMsg.getRuleChainMetadataUpdateMsgCount() > 0) { - for (RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg: downlinkMsg.getRuleChainMetadataUpdateMsgList()) { + for (RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg : downlinkMsg.getRuleChainMetadataUpdateMsgList()) { result.add(saveDownlinkMsg(ruleChainMetadataUpdateMsg)); } } if (downlinkMsg.getDashboardUpdateMsgCount() > 0) { - for (DashboardUpdateMsg dashboardUpdateMsg: downlinkMsg.getDashboardUpdateMsgList()) { + for (DashboardUpdateMsg dashboardUpdateMsg : downlinkMsg.getDashboardUpdateMsgList()) { result.add(saveDownlinkMsg(dashboardUpdateMsg)); } } if (downlinkMsg.getRelationUpdateMsgCount() > 0) { - for (RelationUpdateMsg relationUpdateMsg: downlinkMsg.getRelationUpdateMsgList()) { + for (RelationUpdateMsg relationUpdateMsg : downlinkMsg.getRelationUpdateMsgList()) { result.add(saveDownlinkMsg(relationUpdateMsg)); } } if (downlinkMsg.getAlarmUpdateMsgCount() > 0) { - for (AlarmUpdateMsg alarmUpdateMsg: downlinkMsg.getAlarmUpdateMsgList()) { + for (AlarmUpdateMsg alarmUpdateMsg : downlinkMsg.getAlarmUpdateMsgList()) { result.add(saveDownlinkMsg(alarmUpdateMsg)); } } if (downlinkMsg.getEntityDataCount() > 0) { - for (EntityDataProto entityData: downlinkMsg.getEntityDataList()) { + for (EntityDataProto entityData : downlinkMsg.getEntityDataList()) { result.add(saveDownlinkMsg(entityData)); } } if (downlinkMsg.getEntityViewUpdateMsgCount() > 0) { - for (EntityViewUpdateMsg entityViewUpdateMsg: downlinkMsg.getEntityViewUpdateMsgList()) { + for (EntityViewUpdateMsg entityViewUpdateMsg : downlinkMsg.getEntityViewUpdateMsgList()) { result.add(saveDownlinkMsg(entityViewUpdateMsg)); } } if (downlinkMsg.getCustomerUpdateMsgCount() > 0) { - for (CustomerUpdateMsg customerUpdateMsg: downlinkMsg.getCustomerUpdateMsgList()) { + for (CustomerUpdateMsg customerUpdateMsg : downlinkMsg.getCustomerUpdateMsgList()) { result.add(saveDownlinkMsg(customerUpdateMsg)); } } if (downlinkMsg.getWidgetsBundleUpdateMsgCount() > 0) { - for (WidgetsBundleUpdateMsg widgetsBundleUpdateMsg: downlinkMsg.getWidgetsBundleUpdateMsgList()) { + for (WidgetsBundleUpdateMsg widgetsBundleUpdateMsg : downlinkMsg.getWidgetsBundleUpdateMsgList()) { result.add(saveDownlinkMsg(widgetsBundleUpdateMsg)); } } if (downlinkMsg.getWidgetTypeUpdateMsgCount() > 0) { - for (WidgetTypeUpdateMsg widgetTypeUpdateMsg: downlinkMsg.getWidgetTypeUpdateMsgList()) { + for (WidgetTypeUpdateMsg widgetTypeUpdateMsg : downlinkMsg.getWidgetTypeUpdateMsgList()) { result.add(saveDownlinkMsg(widgetTypeUpdateMsg)); } } if (downlinkMsg.getUserUpdateMsgCount() > 0) { - for (UserUpdateMsg userUpdateMsg: downlinkMsg.getUserUpdateMsgList()) { - onUserUpdate(userUpdateMsg); + for (UserUpdateMsg userUpdateMsg : downlinkMsg.getUserUpdateMsgList()) { result.add(saveDownlinkMsg(userUpdateMsg)); } } if (downlinkMsg.getUserCredentialsUpdateMsgCount() > 0) { - for (UserCredentialsUpdateMsg userCredentialsUpdateMsg: downlinkMsg.getUserCredentialsUpdateMsgList()) { + for (UserCredentialsUpdateMsg userCredentialsUpdateMsg : downlinkMsg.getUserCredentialsUpdateMsgList()) { result.add(saveDownlinkMsg(userCredentialsUpdateMsg)); } } if (downlinkMsg.getDeviceRpcCallMsgCount() > 0) { - for (DeviceRpcCallMsg deviceRpcCallMsg: downlinkMsg.getDeviceRpcCallMsgList()) { + for (DeviceRpcCallMsg deviceRpcCallMsg : downlinkMsg.getDeviceRpcCallMsgList()) { result.add(saveDownlinkMsg(deviceRpcCallMsg)); } } if (downlinkMsg.getDeviceCredentialsRequestMsgCount() > 0) { - for (DeviceCredentialsRequestMsg deviceCredentialsRequestMsg: downlinkMsg.getDeviceCredentialsRequestMsgList()) { + for (DeviceCredentialsRequestMsg deviceCredentialsRequestMsg : downlinkMsg.getDeviceCredentialsRequestMsgList()) { result.add(saveDownlinkMsg(deviceCredentialsRequestMsg)); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index d9e70bb68b..be01e636c9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -558,8 +558,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic if (userById.getCustomerId() == null || userById.getCustomerId().isNullUid()) { pageData = findEdgesByTenantId(tenantId, pageLink); } else { -// pageData = findEdgesByTenantIdAndCustomerId(tenantId, userById.getCustomerId(), pageLink); - pageData = findEdgesByTenantIdAndCustomerId(tenantId, new CustomerId(entityId.getId()), pageLink); + pageData = findEdgesByTenantIdAndCustomerId(tenantId, userById.getCustomerId(), pageLink); } if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { result.addAll(pageData.getData()); From d3152874fc207ffa4e5435e6aa9555a776efc7e0 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 12 May 2021 20:13:40 +0300 Subject: [PATCH 03/52] Introduced base pageable edge event fetcher --- .../service/edge/rpc/EdgeGrpcSession.java | 3 +-- .../fetch/AdminSettingsEdgeEventFetcher.java | 7 +---- .../rpc/fetch/AssetsEdgeEventFetcher.java | 7 +---- .../fetch/BasePageableEdgeEventFetcher.java | 26 +++++++++++++++++++ .../rpc/fetch/BaseUsersEdgeEventFetcher.java | 10 +------ .../BaseWidgetsBundlesEdgeEventFetcher.java | 7 +---- .../rpc/fetch/DashboardsEdgeEventFetcher.java | 7 +---- .../fetch/DeviceProfilesEdgeEventFetcher.java | 7 +---- .../edge/rpc/fetch/EdgeEventFetcher.java | 4 +-- .../rpc/fetch/GeneralEdgeEventFetcher.java | 5 ++-- .../rpc/fetch/RuleChainsEdgeEventFetcher.java | 7 +---- .../server/edge/imitator/EdgeImitator.java | 2 +- 12 files changed, 38 insertions(+), 54 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index da0b1a7736..71f47e7a69 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -330,7 +330,6 @@ public final class EdgeGrpcSession implements Closeable { if (isConnected() && isSyncCompleted()) { Long queueStartTs = getQueueStartTs().get(); GeneralEdgeEventFetcher fetcher = new GeneralEdgeEventFetcher( - ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount(), queueStartTs, ctx.getEdgeEventService()); UUID ifOffset = startProcessingEdgeEvents(fetcher); @@ -343,7 +342,7 @@ public final class EdgeGrpcSession implements Closeable { } private UUID startProcessingEdgeEvents(EdgeEventFetcher fetcher) throws InterruptedException { - PageLink pageLink = fetcher.getPageLink(); + PageLink pageLink = fetcher.getPageLink(ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount()); PageData pageData; UUID ifOffset = null; boolean success = true; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java index b232333d5d..be5344acd4 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java @@ -25,12 +25,7 @@ import org.thingsboard.server.common.data.page.PageLink; @AllArgsConstructor @Slf4j -public class AdminSettingsEdgeEventFetcher implements EdgeEventFetcher { - - @Override - public PageLink getPageLink() { - return new PageLink(DEFAULT_LIMIT); - } +public class AdminSettingsEdgeEventFetcher extends BasePageableEdgeEventFetcher { @Override public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java index e2eb2e8d61..30bbcd0aa1 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java @@ -33,15 +33,10 @@ import java.util.List; @AllArgsConstructor @Slf4j -public class AssetsEdgeEventFetcher implements EdgeEventFetcher { +public class AssetsEdgeEventFetcher extends BasePageableEdgeEventFetcher { private final AssetService assetService; - @Override - public PageLink getPageLink() { - return new PageLink(DEFAULT_LIMIT); - } - @Override public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java new file mode 100644 index 0000000000..3c2f7f82fd --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java @@ -0,0 +1,26 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import org.thingsboard.server.common.data.page.PageLink; + +public abstract class BasePageableEdgeEventFetcher implements EdgeEventFetcher { + + @Override + public PageLink getPageLink(int pageSize) { + return new PageLink(pageSize); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java index 883f451636..dbb98864d3 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.edge.rpc.fetch; -import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.edge.EdgeEvent; @@ -25,20 +24,13 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.common.data.widget.WidgetsBundle; -import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; import java.util.ArrayList; import java.util.List; @Slf4j -public abstract class BaseUsersEdgeEventFetcher implements EdgeEventFetcher { - - @Override - public PageLink getPageLink() { - return new PageLink(DEFAULT_LIMIT); - } +public abstract class BaseUsersEdgeEventFetcher extends BasePageableEdgeEventFetcher { @Override public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java index 53c6e579d3..0d02b6dd34 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java @@ -30,12 +30,7 @@ import java.util.ArrayList; import java.util.List; @Slf4j -public abstract class BaseWidgetsBundlesEdgeEventFetcher implements EdgeEventFetcher { - - @Override - public PageLink getPageLink() { - return new PageLink(DEFAULT_LIMIT); - } +public abstract class BaseWidgetsBundlesEdgeEventFetcher extends BasePageableEdgeEventFetcher { @Override public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java index 515a356850..751c6690c1 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java @@ -33,15 +33,10 @@ import java.util.List; @AllArgsConstructor @Slf4j -public class DashboardsEdgeEventFetcher implements EdgeEventFetcher { +public class DashboardsEdgeEventFetcher extends BasePageableEdgeEventFetcher { private final DashboardService dashboardService; - @Override - public PageLink getPageLink() { - return new PageLink(DEFAULT_LIMIT); - } - @Override public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java index fb0af06b75..011761cf11 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java @@ -33,15 +33,10 @@ import java.util.List; @AllArgsConstructor @Slf4j -public class DeviceProfilesEdgeEventFetcher implements EdgeEventFetcher { +public class DeviceProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher { private final DeviceProfileService deviceProfileService; - @Override - public PageLink getPageLink() { - return new PageLink(DEFAULT_LIMIT); - } - @Override public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java index e283b2c043..d36b072c3d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java @@ -23,9 +23,7 @@ import org.thingsboard.server.common.data.page.PageLink; public interface EdgeEventFetcher { - final int DEFAULT_LIMIT = 100; - - PageLink getPageLink(); + PageLink getPageLink(int pageSize); PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java index a87a4ebd68..39d0b482ed 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java @@ -28,14 +28,13 @@ import org.thingsboard.server.dao.edge.EdgeEventService; @AllArgsConstructor public class GeneralEdgeEventFetcher implements EdgeEventFetcher { - private final int maxReadRecordsCount; private final Long queueStartTs; private final EdgeEventService edgeEventService; @Override - public PageLink getPageLink() { + public PageLink getPageLink(int pageSize) { return new TimePageLink( - maxReadRecordsCount, + pageSize, 0, null, new SortOrder("createdTime", SortOrder.Direction.ASC), diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java index 2aca092856..3da1dcc47c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java @@ -33,15 +33,10 @@ import java.util.List; @Slf4j @AllArgsConstructor -public class RuleChainsEdgeEventFetcher implements EdgeEventFetcher { +public class RuleChainsEdgeEventFetcher extends BasePageableEdgeEventFetcher { private final RuleChainService ruleChainService; - @Override - public PageLink getPageLink() { - return new PageLink(DEFAULT_LIMIT); - } - @Override public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index 7625647144..6fff7d31f6 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -5,7 +5,7 @@ * 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 + * 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, From 4b4d262eebba21fbaef90b7110a775ffa83330e8 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 13 May 2021 08:38:28 +0300 Subject: [PATCH 04/52] Fixes for edge test after latest refactoring --- .../controller/BaseEdgeControllerTest.java | 28 ++++++++--------- .../thingsboard/server/edge/BaseEdgeTest.java | 30 ------------------- .../server/edge/imitator/EdgeImitator.java | 7 +++-- 3 files changed, 17 insertions(+), 48 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java index 246749881f..f18fd6c506 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java @@ -657,7 +657,7 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest { Device device = new Device(); device.setName("Edge Device 1"); - device.setType("test"); + device.setType("default"); Device savedDevice = doPost("/api/device", device, Device.class); doPost("/api/edge/" + edge.getId().getId().toString() + "/device/" + savedDevice.getId().getId().toString(), Device.class); @@ -671,29 +671,27 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest { EdgeImitator edgeImitator = new EdgeImitator("localhost", 7070, edge.getRoutingKey(), edge.getSecret()); edgeImitator.ignoreType(UserCredentialsUpdateMsg.class); + edgeImitator.expectMessageAmount(7); edgeImitator.connect(); Assert.assertTrue(edgeImitator.waitForMessages()); Assert.assertEquals(7, edgeImitator.getDownlinkMsgs().size()); - Assert.assertTrue(edgeImitator.findMessageByType(RuleChainUpdateMsg.class).isPresent()); - Assert.assertTrue(edgeImitator.findMessageByType(DeviceProfileUpdateMsg.class).isPresent()); - Assert.assertTrue(edgeImitator.findMessageByType(DeviceUpdateMsg.class).isPresent()); - Assert.assertTrue(edgeImitator.findMessageByType(AssetUpdateMsg.class).isPresent()); - Assert.assertTrue(edgeImitator.findMessageByType(UserUpdateMsg.class).isPresent()); - - edgeImitator.getDownlinkMsgs().clear(); + Assert.assertEquals(2, edgeImitator.findAllMessagesByType(RuleChainUpdateMsg.class).size()); // one msg during sync process, another from edge creation + Assert.assertEquals(1, edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class).size()); // one msg during sync process for 'default' device profile + Assert.assertEquals(1, edgeImitator.findAllMessagesByType(DeviceUpdateMsg.class).size()); // one msg once device assigned to edge + Assert.assertEquals(2, edgeImitator.findAllMessagesByType(AssetUpdateMsg.class).size()); // two msgs - one during sync process, and one more once asset assigned to edge + Assert.assertEquals(1, edgeImitator.findAllMessagesByType(UserUpdateMsg.class).size()); // one msg during sync process for tenant admin user - edgeImitator.expectMessageAmount(7); + edgeImitator.expectMessageAmount(4); doPost("/api/edge/sync/" + edge.getId()); Assert.assertTrue(edgeImitator.waitForMessages()); - Assert.assertEquals(7, edgeImitator.getDownlinkMsgs().size()); - Assert.assertTrue(edgeImitator.findMessageByType(RuleChainUpdateMsg.class).isPresent()); - Assert.assertTrue(edgeImitator.findMessageByType(DeviceProfileUpdateMsg.class).isPresent()); - Assert.assertTrue(edgeImitator.findMessageByType(DeviceUpdateMsg.class).isPresent()); - Assert.assertTrue(edgeImitator.findMessageByType(AssetUpdateMsg.class).isPresent()); - Assert.assertTrue(edgeImitator.findMessageByType(UserUpdateMsg.class).isPresent()); + Assert.assertEquals(4, edgeImitator.getDownlinkMsgs().size()); + Assert.assertEquals(1, edgeImitator.findAllMessagesByType(RuleChainUpdateMsg.class).size()); + Assert.assertEquals(1, edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class).size()); + Assert.assertEquals(1, edgeImitator.findAllMessagesByType(AssetUpdateMsg.class).size()); + Assert.assertEquals(1, edgeImitator.findAllMessagesByType(UserUpdateMsg.class).size()); edgeImitator.allowIgnoredTypes(); try { diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java index 3953b6c642..842633d30d 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -65,7 +65,6 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.query.EntityKeyValueType; @@ -193,60 +192,32 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { @Test public void test() throws Exception { testReceivedInitialData(); - int expectedDownlinkSize = 9; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testDevices(); - expectedDownlinkSize = expectedDownlinkSize + 4; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testAssets(); - expectedDownlinkSize = expectedDownlinkSize + 4; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testRuleChains(); - expectedDownlinkSize = expectedDownlinkSize + 3; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testDashboards(); - expectedDownlinkSize = expectedDownlinkSize + 3; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testRelations(); - expectedDownlinkSize = expectedDownlinkSize + 2; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testAlarms(); - expectedDownlinkSize = expectedDownlinkSize + 3; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testEntityView(); - expectedDownlinkSize = expectedDownlinkSize + 3; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testCustomerAndNewUser(); - expectedDownlinkSize = expectedDownlinkSize + 3; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testWidgetsBundleAndWidgetType(); - expectedDownlinkSize = expectedDownlinkSize + 4; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testTimeseries(); - expectedDownlinkSize = expectedDownlinkSize + 1; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testAttributes(); - expectedDownlinkSize = expectedDownlinkSize + 3; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testSendMessagesToCloud(); - expectedDownlinkSize = expectedDownlinkSize + 9; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); testRpcCall(); - expectedDownlinkSize = expectedDownlinkSize + 1; - Assert.assertEquals(expectedDownlinkSize, edgeImitator.getDownlinkMsgs().size()); } private Device findDeviceByName(String deviceName) throws Exception { @@ -442,7 +413,6 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { log.info("Devices tested successfully"); } - private void testAssets() throws Exception { log.info("Testing assets"); diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index 6fff7d31f6..1496b0d061 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -77,9 +77,7 @@ public class EdgeImitator { @Getter private EdgeConfiguration configuration; @Getter - private UserId userId; - @Getter - private final List downlinkMsgs; + private List downlinkMsgs; public EdgeImitator(String host, int port, String routingKey, String routingSecret) throws NoSuchFieldException, IllegalAccessException { edgeRpcClient = new EdgeGrpcClient(); @@ -266,6 +264,9 @@ public class EdgeImitator { } public void expectMessageAmount(int messageAmount) { + // clear downlinks + downlinkMsgs.clear(); + messagesLatch = new CountDownLatch(messageAmount); } From 96ed8f1691405f5b59650cbd226135ad6461d86f Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 13 May 2021 10:14:19 +0300 Subject: [PATCH 05/52] debug code line fix --- .../test/java/org/thingsboard/server/edge/BaseEdgeTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java index 842633d30d..8e3e8be882 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -281,8 +281,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { private void testReceivedInitialData() throws Exception { log.info("Checking received data"); - boolean condition = edgeImitator.waitForMessages(); - Assert.assertTrue(condition); + Assert.assertTrue(edgeImitator.waitForMessages()); EdgeConfiguration configuration = edgeImitator.getConfiguration(); Assert.assertNotNull(configuration); From 71791c6847a682af2d4bf5042701cb1496df9f9c Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 13 May 2021 15:04:12 +0300 Subject: [PATCH 06/52] Refactored DAO to remove additional call to relation table - use spring query --- .../controller/RuleChainController.java | 20 +++++++++-- .../server/dao/rule/RuleChainService.java | 2 +- .../server/dao/edge/EdgeServiceImpl.java | 24 ++++++-------- .../server/dao/rule/BaseRuleChainService.java | 7 ++-- .../server/dao/rule/RuleChainDao.java | 4 +-- .../server/dao/sql/rule/JpaRuleChainDao.java | 33 ++++--------------- .../dao/sql/rule/RuleChainRepository.java | 9 ++++- .../dao/service/BaseRuleChainServiceTest.java | 8 ++--- 8 files changed, 51 insertions(+), 56 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index d5fcc2706f..6f7cf4e81d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -70,6 +70,7 @@ import org.thingsboard.server.service.script.RuleNodeJsScriptEngine; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @@ -85,6 +86,8 @@ public class RuleChainController extends BaseController { public static final String RULE_CHAIN_ID = "ruleChainId"; public static final String RULE_NODE_ID = "ruleNodeId"; + private static final int DEFAULT_LIMIT = 100; + private static final ObjectMapper objectMapper = new ObjectMapper(); @Autowired @@ -477,7 +480,7 @@ public class RuleChainController extends BaseController { return objectMapper.writeValueAsString(resultNode); } - private JsonNode convertMsgToOut(TbMsg msg) throws Exception{ + private JsonNode convertMsgToOut(TbMsg msg) throws Exception { ObjectNode msgData = objectMapper.createObjectNode(); if (!StringUtils.isEmpty(msg.getData())) { msgData.set("msg", objectMapper.readTree(msg.getData())); @@ -632,13 +635,26 @@ public class RuleChainController extends BaseController { } } + // TODO: refactor this - add new config to edge rule chain to set it as auto-assign @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/ruleChain/autoAssignToEdgeRuleChains", method = RequestMethod.GET) @ResponseBody public List getAutoAssignToEdgeRuleChains() throws ThingsboardException { try { TenantId tenantId = getCurrentUser().getTenantId(); - return checkNotNull(ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId)).get(); + List result = new ArrayList<>(); + PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageData pageData; + do { + pageData = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId, pageLink); + if (pageData.getData().size() > 0) { + result.addAll(pageData.getData()); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } + } while (pageData.hasNext()); + return checkNotNull(result); } catch (Exception e) { throw handleException(e); } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java index 5740abb354..ae994d4122 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java @@ -87,6 +87,6 @@ public interface RuleChainService { boolean unsetAutoAssignToEdgeRuleChain(TenantId tenantId, RuleChainId ruleChainId); - ListenableFuture> findAutoAssignToEdgeRuleChainsByTenantId(TenantId tenantId); + PageData findAutoAssignToEdgeRuleChainsByTenantId(TenantId tenantId, PageLink pageLink); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index be01e636c9..21ca4228a3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -19,7 +19,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.base.Function; -import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; @@ -381,22 +380,19 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @Override public void assignDefaultRuleChainsToEdge(TenantId tenantId, EdgeId edgeId) { log.trace("Executing assignDefaultRuleChainsToEdge, tenantId [{}], edgeId [{}]", tenantId, edgeId); - ListenableFuture> future = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId); - Futures.addCallback(future, new FutureCallback>() { - @Override - public void onSuccess(List ruleChains) { - if (ruleChains != null && !ruleChains.isEmpty()) { - for (RuleChain ruleChain : ruleChains) { - ruleChainService.assignRuleChainToEdge(tenantId, ruleChain.getId(), edgeId); - } + PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageData pageData; + do { + pageData = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId, pageLink); + if (pageData.getData().size() > 0) { + for (RuleChain ruleChain : pageData.getData()) { + ruleChainService.assignRuleChainToEdge(tenantId, ruleChain.getId(), edgeId); } } - - @Override - public void onFailure(Throwable t) { - log.warn("[{}] can't find default edge rule chains [{}]", tenantId.getId(), edgeId.getId(), t); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); } - }, MoreExecutors.directExecutor()); + } while (pageData.hasNext()); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index b61e18e08a..38eeab9546 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -631,13 +631,12 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC } @Override - public ListenableFuture> findAutoAssignToEdgeRuleChainsByTenantId(TenantId tenantId) { - log.trace("Executing findAutoAssignToEdgeRuleChainsByTenantId, tenantId [{}]", tenantId); + public PageData findAutoAssignToEdgeRuleChainsByTenantId(TenantId tenantId, PageLink pageLink) { + log.trace("Executing findAutoAssignToEdgeRuleChainsByTenantId, tenantId [{}], pageLink {}", tenantId, pageLink); validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - return ruleChainDao.findAutoAssignToEdgeRuleChainsByTenantId(tenantId.getId()); + return ruleChainDao.findAutoAssignToEdgeRuleChainsByTenantId(tenantId.getId(), pageLink); } - private void checkRuleNodesAndDelete(TenantId tenantId, RuleChainId ruleChainId) { try{ ruleChainDao.removeById(tenantId, ruleChainId.getId()); diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainDao.java b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainDao.java index 2aaaa934d7..98ad0b34a7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainDao.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.dao.rule; -import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.rule.RuleChain; @@ -23,7 +22,6 @@ import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.dao.Dao; import org.thingsboard.server.dao.TenantEntityDao; -import java.util.List; import java.util.UUID; /** @@ -75,5 +73,5 @@ public interface RuleChainDao extends Dao, TenantEntityDao { * @param tenantId the tenantId * @return the list of rule chain objects */ - ListenableFuture> findAutoAssignToEdgeRuleChainsByTenantId(UUID tenantId); + PageData findAutoAssignToEdgeRuleChainsByTenantId(UUID tenantId, PageLink pageLink); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java index 0dbe22571e..040e60daad 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java @@ -15,9 +15,6 @@ */ package org.thingsboard.server.dao.sql.rule; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.repository.CrudRepository; @@ -25,19 +22,13 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.common.data.relation.EntityRelation; -import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.model.sql.RuleChainEntity; -import org.thingsboard.server.dao.relation.RelationDao; import org.thingsboard.server.dao.rule.RuleChainDao; import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import java.util.Objects; import java.util.UUID; @@ -48,9 +39,6 @@ public class JpaRuleChainDao extends JpaAbstractSearchTextDao getEntityClass() { return RuleChainEntity.class; @@ -91,7 +79,6 @@ public class JpaRuleChainDao extends JpaAbstractSearchTextDao findRuleChainsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, PageLink pageLink) { log.debug("Try to find rule chains by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink); - return DaoUtil.toPageData(ruleChainRepository .findByTenantIdAndEdgeId( tenantId, @@ -101,21 +88,13 @@ public class JpaRuleChainDao extends JpaAbstractSearchTextDao> findAutoAssignToEdgeRuleChainsByTenantId(UUID tenantId) { + public PageData findAutoAssignToEdgeRuleChainsByTenantId(UUID tenantId, PageLink pageLink) { log.debug("Try to find auto assign to edge rule chains by tenantId [{}]", tenantId); - ListenableFuture> relations = - relationDao.findAllByFromAndType(new TenantId(tenantId), new TenantId(tenantId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE_AUTO_ASSIGN_RULE_CHAIN); - return Futures.transformAsync(relations, input -> { - if (input != null && !input.isEmpty()) { - List> ruleChainsFutures = new ArrayList<>(input.size()); - for (EntityRelation relation : input) { - ruleChainsFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId())); - } - return Futures.successfulAsList(ruleChainsFutures); - } else { - return Futures.immediateFuture(Collections.emptyList()); - } - }, MoreExecutors.directExecutor()); + return DaoUtil.toPageData(ruleChainRepository + .findAutoAssignByTenantId( + tenantId, + Objects.toString(pageLink.getTextSearch(), ""), + DaoUtil.toPageable(pageLink))); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleChainRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleChainRepository.java index 1251234fa1..86a147cc57 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleChainRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleChainRepository.java @@ -21,7 +21,6 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; import org.thingsboard.server.common.data.rule.RuleChainType; -import org.thingsboard.server.dao.model.sql.DashboardInfoEntity; import org.thingsboard.server.dao.model.sql.RuleChainEntity; import java.util.UUID; @@ -51,6 +50,14 @@ public interface RuleChainRepository extends PagingAndSortingRepository findAutoAssignByTenantId(@Param("tenantId") UUID tenantId, + @Param("searchText") String searchText, + Pageable pageable); + RuleChainEntity findByTenantIdAndTypeAndRootIsTrue(UUID tenantId, RuleChainType ruleChainType); Long countByTenantId(UUID tenantId); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java index 3f4b103ce2..62df8c208d 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java @@ -334,13 +334,13 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest { public void testGetDefaultEdgeRuleChains() throws Exception { RuleChainId ruleChainId = saveRuleChainAndSetAutoAssignToEdge("Default Edge Rule Chain 1"); saveRuleChainAndSetAutoAssignToEdge("Default Edge Rule Chain 2"); - List result = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId).get(); - Assert.assertEquals(2, result.size()); + PageData result = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId, new PageLink(100)); + Assert.assertEquals(2, result.getData().size()); ruleChainService.unsetAutoAssignToEdgeRuleChain(tenantId, ruleChainId); - result = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId).get(); - Assert.assertEquals(1, result.size()); + result = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId, new PageLink(100)); + Assert.assertEquals(1, result.getData().size()); } @Test From bb064cbbbd20de81c99bcc7e681db106360ab698 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 18 May 2021 11:03:52 +0300 Subject: [PATCH 07/52] Edge session send donwlink msgs refactoring --- .../service/edge/rpc/EdgeGrpcSession.java | 57 ++++++------------- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 71f47e7a69..5a3587fb1b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -242,7 +242,7 @@ public final class EdgeGrpcSession implements Closeable { EdgeEvent customerEdgeEvent = EdgeEventUtils.constructEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, edge.getCustomerId(), null); DownlinkMsg customerDownlinkMsg = convertToDownlinkMsg(customerEdgeEvent); - sendSingleDownlinkMsg(customerDownlinkMsg); + sendDownlinkMsgsPack(Collections.singletonList(customerDownlinkMsg)); startProcessingEdgeEvents(new CustomerUsersEdgeEventFetcher(ctx.getUserService(), edge.getCustomerId())); } @@ -256,7 +256,7 @@ public final class EdgeGrpcSession implements Closeable { DownlinkMsg syncCompleteDownlinkMsg = DownlinkMsg.newBuilder() .setSyncCompletedMsg(SyncCompletedMsg.newBuilder().build()) .build(); - sendSingleDownlinkMsg(syncCompleteDownlinkMsg); + sendDownlinkMsgsPack(Collections.singletonList(syncCompleteDownlinkMsg)); } catch (Exception e) { log.error("[{}][{}] Exception during sync process", edge.getTenantId(), edge.getId(), e); } @@ -345,59 +345,37 @@ public final class EdgeGrpcSession implements Closeable { PageLink pageLink = fetcher.getPageLink(ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount()); PageData pageData; UUID ifOffset = null; - boolean success = true; + boolean success; do { pageData = fetcher.fetchEdgeEvents(edge.getTenantId(), edge.getId(), pageLink); if (isConnected() && !pageData.getData().isEmpty()) { log.trace("[{}] [{}] event(s) are going to be processed.", this.sessionId, pageData.getData().size()); - - success = processEdgeEventsPack(pageData.getData()); - + List downlinkMsgsPack = convertToDownlinkMsgsPack(pageData.getData()); + success = sendDownlinkMsgsPack(downlinkMsgsPack); ifOffset = pageData.getData().get(pageData.getData().size() - 1).getUuidId(); - } - if (isConnected() && (!success || pageData.hasNext())) { - try { - Thread.sleep(ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches()); - } catch (InterruptedException e) { - log.error("[{}] Error during sleep between batches", this.sessionId, e); - } if (success) { pageLink = pageLink.nextPageLink(); } + } else { + log.trace("[{}] no event(s) found. Stop processing edge events", this.sessionId); } - } while (isConnected() && (!success || pageData.hasNext())); + } while (isConnected() && pageData.hasNext()); return ifOffset; } - private boolean processEdgeEventsPack(List edgeEvents) throws InterruptedException { - List downlinkMsgsPack = convertToDownlinkMsgsPack(edgeEvents); - - log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, downlinkMsgsPack.size()); - - latch = new CountDownLatch(downlinkMsgsPack.size()); - for (DownlinkMsg downlinkMsg : downlinkMsgsPack) { - sendDownlinkMsg(ResponseMsg.newBuilder() - .setDownlinkMsg(downlinkMsg) - .build()); - } - - boolean success = latch.await(10, TimeUnit.SECONDS); - if (!success) { - log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, downlinkMsgsPack); - } - return success; - } - - private void sendSingleDownlinkMsg(DownlinkMsg downlinkMsg) throws InterruptedException { + private boolean sendDownlinkMsgsPack(List downlinkMsgsPack) throws InterruptedException { boolean success; do { - latch = new CountDownLatch(1); - sendDownlinkMsg(ResponseMsg.newBuilder() - .setDownlinkMsg(downlinkMsg) - .build()); + log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, downlinkMsgsPack.size()); + latch = new CountDownLatch(downlinkMsgsPack.size()); + for (DownlinkMsg downlinkMsg : downlinkMsgsPack) { + sendDownlinkMsg(ResponseMsg.newBuilder() + .setDownlinkMsg(downlinkMsg) + .build()); + } success = latch.await(10, TimeUnit.SECONDS); if (!success) { - log.warn("[{}] Failed to deliver single downlink msg!", this.sessionId); + log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, downlinkMsgsPack); } if (isConnected() && !success) { try { @@ -407,6 +385,7 @@ public final class EdgeGrpcSession implements Closeable { } } } while (isConnected() && !success); + return success; } private DownlinkMsg convertToDownlinkMsg(EdgeEvent edgeEvent) { From c081f9b8d35a5f338317a94d19d796d1a6b1083d Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 18 May 2021 11:09:52 +0300 Subject: [PATCH 08/52] Use stream --- .../server/service/edge/rpc/EdgeGrpcSession.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 5a3587fb1b..68bb02fc00 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -133,6 +133,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.stream.Collectors; @Slf4j @Data @@ -430,14 +431,10 @@ public final class EdgeGrpcSession implements Closeable { } private List convertToDownlinkMsgsPack(List edgeEvents) { - List result = new ArrayList<>(); - for (EdgeEvent edgeEvent : edgeEvents) { - DownlinkMsg downlinkMsg = convertToDownlinkMsg(edgeEvent); - if (downlinkMsg != null) { - result.add(downlinkMsg); - } - } - return result; + return edgeEvents + .stream() + .map(this::convertToDownlinkMsg) + .collect(Collectors.toList()); } private DownlinkMsg processEntityMergeRequestMessage(EdgeEvent edgeEvent) { From f5bc5ce1116e5ddf3dc0cc1f32c283139798792c Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 18 May 2021 11:54:54 +0300 Subject: [PATCH 09/52] One more refactoring --- .../service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java | 5 +++++ .../rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java | 5 +++++ .../edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java | 8 +++++--- .../rpc/fetch/SystemWidgetsBundlesEdgeEventFetcher.java | 6 +++--- .../edge/rpc/fetch/TenantAdminUsersEdgeEventFetcher.java | 6 +++--- .../rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java | 7 +++---- 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java index dbb98864d3..c4c0ee3a86 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.service.edge.rpc.fetch; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.edge.EdgeEvent; @@ -24,14 +25,18 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; import java.util.ArrayList; import java.util.List; @Slf4j +@AllArgsConstructor public abstract class BaseUsersEdgeEventFetcher extends BasePageableEdgeEventFetcher { + protected final UserService userService; + @Override public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java index 0d02b6dd34..d025009db9 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.service.edge.rpc.fetch; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; @@ -24,14 +25,18 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.dao.widget.WidgetsBundleService; import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; import java.util.ArrayList; import java.util.List; @Slf4j +@AllArgsConstructor public abstract class BaseWidgetsBundlesEdgeEventFetcher extends BasePageableEdgeEventFetcher { + protected final WidgetsBundleService widgetsBundleService; + @Override public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java index 6775b85844..32c3f8fe7a 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.edge.rpc.fetch; -import lombok.AllArgsConstructor; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; @@ -23,12 +22,15 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.user.UserService; -@AllArgsConstructor public class CustomerUsersEdgeEventFetcher extends BaseUsersEdgeEventFetcher { - private final UserService userService; private final CustomerId customerId; + public CustomerUsersEdgeEventFetcher(UserService userService, CustomerId customerId) { + super(userService); + this.customerId = customerId; + } + @Override protected PageData findUsers(TenantId tenantId, PageLink pageLink) { return userService.findCustomerUsers(tenantId, customerId, pageLink); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemWidgetsBundlesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemWidgetsBundlesEdgeEventFetcher.java index e32e003d4e..f1b9c32049 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemWidgetsBundlesEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemWidgetsBundlesEdgeEventFetcher.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.edge.rpc.fetch; -import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -24,10 +23,11 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.dao.widget.WidgetsBundleService; @Slf4j -@AllArgsConstructor public class SystemWidgetsBundlesEdgeEventFetcher extends BaseWidgetsBundlesEdgeEventFetcher { - private final WidgetsBundleService widgetsBundleService; + public SystemWidgetsBundlesEdgeEventFetcher(WidgetsBundleService widgetsBundleService) { + super(widgetsBundleService); + } @Override protected PageData findWidgetsBundles(TenantId tenantId, PageLink pageLink) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantAdminUsersEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantAdminUsersEdgeEventFetcher.java index 018104ed31..8921afee59 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantAdminUsersEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantAdminUsersEdgeEventFetcher.java @@ -15,17 +15,17 @@ */ package org.thingsboard.server.service.edge.rpc.fetch; -import lombok.AllArgsConstructor; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.user.UserService; -@AllArgsConstructor public class TenantAdminUsersEdgeEventFetcher extends BaseUsersEdgeEventFetcher { - private final UserService userService; + public TenantAdminUsersEdgeEventFetcher(UserService userService) { + super(userService); + } @Override protected PageData findUsers(TenantId tenantId, PageLink pageLink) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java index 6dee9853de..a1fafd858a 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.edge.rpc.fetch; -import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -24,11 +23,11 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.dao.widget.WidgetsBundleService; @Slf4j -@AllArgsConstructor public class TenantWidgetsBundlesEdgeEventFetcher extends BaseWidgetsBundlesEdgeEventFetcher implements EdgeEventFetcher { - private final WidgetsBundleService widgetsBundleService; - + public TenantWidgetsBundlesEdgeEventFetcher(WidgetsBundleService widgetsBundleService) { + super(widgetsBundleService); + } @Override protected PageData findWidgetsBundles(TenantId tenantId, PageLink pageLink) { return widgetsBundleService.findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, pageLink); From ecc43baed2e2aa2efc69cb5f8a4549dc070a29fe Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 18 May 2021 13:49:38 +0300 Subject: [PATCH 10/52] startSyncProcess added tenant id and edge id --- .../server/service/edge/rpc/EdgeGrpcService.java | 2 +- .../server/service/edge/rpc/EdgeGrpcSession.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 9cc93dd28f..e9c93d0396 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -200,7 +200,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i public void startSyncProcess(TenantId tenantId, EdgeId edgeId) { EdgeGrpcSession session = sessions.get(edgeId); if (session != null && session.isConnected()) { - session.startSyncProcess(); + session.startSyncProcess(tenantId, edgeId); } else { log.error("[{}] Edge is not connected [{}]", tenantId, edgeId); throw new RuntimeException("Edge is not connected"); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 68bb02fc00..01fa32795f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -188,7 +188,7 @@ public final class EdgeGrpcSession implements Closeable { } if (connected && requestMsg.getMsgType().equals(RequestMsgType.SYNC_REQUEST_RPC_MESSAGE)) { if (requestMsg.getSyncRequestMsg().getSyncRequired()) { - startSyncProcess(); + startSyncProcess(edge.getTenantId(), edge.getId()); } syncCompleted = true; } @@ -229,12 +229,12 @@ public final class EdgeGrpcSession implements Closeable { }; } - public void startSyncProcess() { - log.trace("[{}][{}] Staring edge sync process", edge.getTenantId(), edge.getId()); + public void startSyncProcess(TenantId tenantId, EdgeId edgeId) { + log.trace("[{}][{}] Staring edge sync process", tenantId, edgeId); syncExecutorService.submit(() -> { try { - startProcessingEdgeEvents(new TenantWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService())); startProcessingEdgeEvents(new SystemWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService())); + startProcessingEdgeEvents(new TenantWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService())); startProcessingEdgeEvents(new DeviceProfilesEdgeEventFetcher(ctx.getDeviceProfileService())); startProcessingEdgeEvents(new RuleChainsEdgeEventFetcher(ctx.getRuleChainService())); From fb6e152f7e1ce0e053ef76895714266ea648ff4e Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 19 May 2021 14:14:26 +0300 Subject: [PATCH 11/52] Introduced processors for "to edge" msgs --- .../service/edge/EdgeContextComponent.java | 96 +-- .../service/edge/rpc/EdgeGrpcSession.java | 557 +----------------- .../rpc/processor/AdminSettingsProcessor.java | 41 ++ .../edge/rpc/processor/AlarmProcessor.java | 25 +- .../edge/rpc/processor/AssetProcessor.java | 68 +++ .../edge/rpc/processor/BaseProcessor.java | 84 ++- .../edge/rpc/processor/CustomerProcessor.java | 61 ++ .../rpc/processor/DashboardProcessor.java | 71 +++ .../edge/rpc/processor/DeviceProcessor.java | 62 +- .../rpc/processor/DeviceProfileProcessor.java | 62 ++ .../edge/rpc/processor/EntityProcessor.java | 73 +++ .../rpc/processor/EntityViewProcessor.java | 68 +++ .../edge/rpc/processor/RelationProcessor.java | 13 +- .../rpc/processor/RuleChainProcessor.java | 81 +++ .../rpc/processor/TelemetryProcessor.java | 49 +- .../edge/rpc/processor/UserProcessor.java | 71 +++ .../rpc/processor/WidgetBundleProcessor.java | 62 ++ .../rpc/processor/WidgetTypeProcessor.java | 62 ++ 18 files changed, 1000 insertions(+), 606 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsProcessor.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetProcessor.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerProcessor.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardProcessor.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileProcessor.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityProcessor.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewProcessor.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainProcessor.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserProcessor.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleProcessor.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeProcessor.java diff --git a/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java b/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java index 62940f2931..c1fbcbc69b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java @@ -54,6 +54,17 @@ import org.thingsboard.server.service.edge.rpc.constructor.RuleChainMsgConstruct import org.thingsboard.server.service.edge.rpc.constructor.UserMsgConstructor; import org.thingsboard.server.service.edge.rpc.constructor.WidgetTypeMsgConstructor; import org.thingsboard.server.service.edge.rpc.constructor.WidgetsBundleMsgConstructor; +import org.thingsboard.server.service.edge.rpc.processor.AdminSettingsProcessor; +import org.thingsboard.server.service.edge.rpc.processor.AssetProcessor; +import org.thingsboard.server.service.edge.rpc.processor.CustomerProcessor; +import org.thingsboard.server.service.edge.rpc.processor.DashboardProcessor; +import org.thingsboard.server.service.edge.rpc.processor.DeviceProfileProcessor; +import org.thingsboard.server.service.edge.rpc.processor.EntityProcessor; +import org.thingsboard.server.service.edge.rpc.processor.EntityViewProcessor; +import org.thingsboard.server.service.edge.rpc.processor.RuleChainProcessor; +import org.thingsboard.server.service.edge.rpc.processor.UserProcessor; +import org.thingsboard.server.service.edge.rpc.processor.WidgetBundleProcessor; +import org.thingsboard.server.service.edge.rpc.processor.WidgetTypeProcessor; import org.thingsboard.server.service.edge.rpc.sync.EdgeRequestsService; import org.thingsboard.server.service.edge.rpc.processor.AlarmProcessor; import org.thingsboard.server.service.edge.rpc.processor.DeviceProcessor; @@ -72,9 +83,6 @@ public class EdgeContextComponent { @Autowired private EdgeService edgeService; - @Autowired - private PartitionService partitionService; - @Lazy @Autowired private EdgeEventService edgeEventService; @@ -83,38 +91,14 @@ public class EdgeContextComponent { @Autowired private AssetService assetService; - @Lazy - @Autowired - private DeviceService deviceService; - @Lazy @Autowired private DeviceProfileService deviceProfileService; - @Lazy - @Autowired - private DeviceCredentialsService deviceCredentialsService; - - @Lazy - @Autowired - private EntityViewService entityViewService; - @Lazy @Autowired private AttributesService attributesService; - @Lazy - @Autowired - private CustomerService customerService; - - @Lazy - @Autowired - private RelationService relationService; - - @Lazy - @Autowired - private AlarmService alarmService; - @Lazy @Autowired private DashboardService dashboardService; @@ -127,101 +111,73 @@ public class EdgeContextComponent { @Autowired private UserService userService; - @Lazy - @Autowired - private ActorService actorService; - @Lazy @Autowired private WidgetsBundleService widgetsBundleService; - @Lazy - @Autowired - private WidgetTypeService widgetTypeService; - - @Lazy - @Autowired - private DeviceStateService deviceStateService; - - @Lazy - @Autowired - private TbClusterService tbClusterService; - @Lazy @Autowired private EdgeRequestsService edgeRequestsService; @Lazy @Autowired - private RuleChainMsgConstructor ruleChainMsgConstructor; - - @Lazy - @Autowired - private AlarmMsgConstructor alarmMsgConstructor; - - @Lazy - @Autowired - private DeviceMsgConstructor deviceMsgConstructor; - - @Lazy - @Autowired - private DeviceProfileMsgConstructor deviceProfileMsgConstructor; + private AlarmProcessor alarmProcessor; @Lazy @Autowired - private AssetMsgConstructor assetMsgConstructor; + private DeviceProfileProcessor deviceProfileProcessor; @Lazy @Autowired - private EntityViewMsgConstructor entityViewMsgConstructor; + private DeviceProcessor deviceProcessor; @Lazy @Autowired - private DashboardMsgConstructor dashboardMsgConstructor; + private EntityProcessor entityProcessor; @Lazy @Autowired - private CustomerMsgConstructor customerMsgConstructor; + private AssetProcessor assetProcessor; @Lazy @Autowired - private UserMsgConstructor userMsgConstructor; + private EntityViewProcessor entityViewProcessor; @Lazy @Autowired - private RelationMsgConstructor relationMsgConstructor; + private UserProcessor userProcessor; @Lazy @Autowired - private WidgetsBundleMsgConstructor widgetsBundleMsgConstructor; + private RelationProcessor relationProcessor; @Lazy @Autowired - private WidgetTypeMsgConstructor widgetTypeMsgConstructor; + private TelemetryProcessor telemetryProcessor; @Lazy @Autowired - private AdminSettingsMsgConstructor adminSettingsMsgConstructor; + private DashboardProcessor dashboardProcessor; @Lazy @Autowired - private EntityDataMsgConstructor entityDataMsgConstructor; + private RuleChainProcessor ruleChainProcessor; @Lazy @Autowired - private AlarmProcessor alarmProcessor; + private CustomerProcessor customerProcessor; @Lazy @Autowired - private DeviceProcessor deviceProcessor; + private WidgetBundleProcessor widgetBundleProcessor; @Lazy @Autowired - private RelationProcessor relationProcessor; + private WidgetTypeProcessor widgetTypeProcessor; @Lazy @Autowired - private TelemetryProcessor telemetryProcessor; + private AdminSettingsProcessor adminSettingsProcessor; @Lazy @Autowired diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 01fa32795f..e95c5952f4 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -21,67 +21,32 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; -import com.google.gson.JsonElement; import io.grpc.stub.StreamObserver; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.Nullable; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.common.data.AdminSettings; -import org.thingsboard.server.common.data.Customer; -import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.common.data.EntityView; -import org.thingsboard.server.common.data.HasCustomerId; -import org.thingsboard.server.common.data.User; -import org.thingsboard.server.common.data.alarm.Alarm; -import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; -import org.thingsboard.server.common.data.id.AlarmId; -import org.thingsboard.server.common.data.id.AssetId; -import org.thingsboard.server.common.data.id.CustomerId; -import org.thingsboard.server.common.data.id.DashboardId; -import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.EntityViewId; -import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.id.UserId; -import org.thingsboard.server.common.data.id.WidgetTypeId; -import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.common.data.relation.EntityRelation; -import org.thingsboard.server.common.data.rule.RuleChain; -import org.thingsboard.server.common.data.rule.RuleChainMetaData; -import org.thingsboard.server.common.data.security.DeviceCredentials; -import org.thingsboard.server.common.data.security.UserCredentials; -import org.thingsboard.server.common.data.widget.WidgetType; -import org.thingsboard.server.common.data.widget.WidgetsBundle; -import org.thingsboard.server.common.transport.util.JsonUtils; -import org.thingsboard.server.gen.edge.AdminSettingsUpdateMsg; import org.thingsboard.server.gen.edge.AlarmUpdateMsg; -import org.thingsboard.server.gen.edge.AssetUpdateMsg; import org.thingsboard.server.gen.edge.AttributesRequestMsg; import org.thingsboard.server.gen.edge.ConnectRequestMsg; import org.thingsboard.server.gen.edge.ConnectResponseCode; import org.thingsboard.server.gen.edge.ConnectResponseMsg; -import org.thingsboard.server.gen.edge.CustomerUpdateMsg; -import org.thingsboard.server.gen.edge.DashboardUpdateMsg; import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; import org.thingsboard.server.gen.edge.DeviceProfileDevicesRequestMsg; -import org.thingsboard.server.gen.edge.DeviceProfileUpdateMsg; import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; import org.thingsboard.server.gen.edge.DeviceUpdateMsg; import org.thingsboard.server.gen.edge.DownlinkMsg; @@ -89,7 +54,6 @@ import org.thingsboard.server.gen.edge.DownlinkResponseMsg; import org.thingsboard.server.gen.edge.EdgeConfiguration; import org.thingsboard.server.gen.edge.EdgeUpdateMsg; import org.thingsboard.server.gen.edge.EntityDataProto; -import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; import org.thingsboard.server.gen.edge.EntityViewsRequestMsg; import org.thingsboard.server.gen.edge.RelationRequestMsg; import org.thingsboard.server.gen.edge.RelationUpdateMsg; @@ -97,17 +61,12 @@ import org.thingsboard.server.gen.edge.RequestMsg; import org.thingsboard.server.gen.edge.RequestMsgType; import org.thingsboard.server.gen.edge.ResponseMsg; import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg; -import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg; -import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; import org.thingsboard.server.gen.edge.SyncCompletedMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; import org.thingsboard.server.gen.edge.UplinkMsg; import org.thingsboard.server.gen.edge.UplinkResponseMsg; import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; import org.thingsboard.server.gen.edge.WidgetBundleTypesRequestMsg; -import org.thingsboard.server.gen.edge.WidgetTypeUpdateMsg; -import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; import org.thingsboard.server.service.edge.EdgeContextComponent; import org.thingsboard.server.service.edge.rpc.fetch.AssetsEdgeEventFetcher; import org.thingsboard.server.service.edge.rpc.fetch.CustomerUsersEdgeEventFetcher; @@ -390,7 +349,7 @@ public final class EdgeGrpcSession implements Closeable { } private DownlinkMsg convertToDownlinkMsg(EdgeEvent edgeEvent) { - log.trace("[{}] converting edge event to downlink msg [{}]", this.sessionId, edgeEvent); + log.trace("[{}][{}] converting edge event to downlink msg [{}]", edge.getTenantId(), this.sessionId, edgeEvent); DownlinkMsg downlinkMsg = null; try { switch (edgeEvent.getAction()) { @@ -407,25 +366,26 @@ public final class EdgeGrpcSession implements Closeable { case ASSIGNED_TO_CUSTOMER: case UNASSIGNED_FROM_CUSTOMER: downlinkMsg = processEntityMessage(edgeEvent, edgeEvent.getAction()); + log.trace("[{}][{}] entity message processed [{}]", edgeEvent.getTenantId(), this.sessionId, downlinkMsg); break; case ATTRIBUTES_UPDATED: case POST_ATTRIBUTES: case ATTRIBUTES_DELETED: case TIMESERIES_UPDATED: - downlinkMsg = processTelemetryMessage(edgeEvent); + downlinkMsg = ctx.getTelemetryProcessor().processTelemetryMessageToEdge(edgeEvent); break; case CREDENTIALS_REQUEST: - downlinkMsg = processCredentialsRequestMessage(edgeEvent); + downlinkMsg = ctx.getEntityProcessor().processCredentialsRequestMessageToEdge(edgeEvent); break; case ENTITY_MERGE_REQUEST: - downlinkMsg = processEntityMergeRequestMessage(edgeEvent); + downlinkMsg = ctx.getEntityProcessor().processEntityMergeRequestMessageToEdge(edge, edgeEvent); break; case RPC_CALL: - downlinkMsg = processRpcCallMsg(edgeEvent); + downlinkMsg = ctx.getDeviceProcessor().processRpcCallMsgToEdge(edgeEvent); break; } } catch (Exception e) { - log.error("Exception during converting edge event to downlink msg", e); + log.error("[{}][{}] Exception during converting edge event to downlink msg", edge.getTenantId(), this.sessionId, e); } return downlinkMsg; } @@ -437,49 +397,6 @@ public final class EdgeGrpcSession implements Closeable { .collect(Collectors.toList()); } - private DownlinkMsg processEntityMergeRequestMessage(EdgeEvent edgeEvent) { - DownlinkMsg downlinkMsg = null; - if (EdgeEventType.DEVICE.equals(edgeEvent.getType())) { - DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); - Device device = ctx.getDeviceService().findDeviceById(edge.getTenantId(), deviceId); - CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device); - String conflictName = null; - if(edgeEvent.getBody() != null) { - conflictName = edgeEvent.getBody().get("conflictName").asText(); - } - DeviceUpdateMsg d = ctx.getDeviceMsgConstructor() - .constructDeviceUpdatedMsg(UpdateMsgType.ENTITY_MERGE_RPC_MESSAGE, device, customerId, conflictName); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllDeviceUpdateMsg(Collections.singletonList(d)) - .build(); - } - return downlinkMsg; - } - - private DownlinkMsg processRpcCallMsg(EdgeEvent edgeEvent) { - log.trace("Executing processRpcCall, edgeEvent [{}]", edgeEvent); - DeviceRpcCallMsg deviceRpcCallMsg = - ctx.getDeviceMsgConstructor().constructDeviceRpcCallMsg(edgeEvent.getEntityId(), edgeEvent.getBody()); - return DownlinkMsg.newBuilder() - .addAllDeviceRpcCallMsg(Collections.singletonList(deviceRpcCallMsg)) - .build(); - } - - private DownlinkMsg processCredentialsRequestMessage(EdgeEvent edgeEvent) { - DownlinkMsg downlinkMsg = null; - if (EdgeEventType.DEVICE.equals(edgeEvent.getType())) { - DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); - DeviceCredentialsRequestMsg deviceCredentialsRequestMsg = DeviceCredentialsRequestMsg.newBuilder() - .setDeviceIdMSB(deviceId.getId().getMostSignificantBits()) - .setDeviceIdLSB(deviceId.getId().getLeastSignificantBits()) - .build(); - DownlinkMsg.Builder builder = DownlinkMsg.newBuilder() - .addAllDeviceCredentialsRequestMsg(Collections.singletonList(deviceCredentialsRequestMsg)); - downlinkMsg = builder.build(); - } - return downlinkMsg; - } - private ListenableFuture getQueueStartTs() { ListenableFuture> future = ctx.getAttributesService().find(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, QUEUE_START_TS_ATTR_KEY); @@ -500,454 +417,44 @@ public final class EdgeGrpcSession implements Closeable { ctx.getAttributesService().save(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, attributes); } - private DownlinkMsg processTelemetryMessage(EdgeEvent edgeEvent) { - log.trace("[{}] Executing processTelemetryMessage, edgeEvent [{}]", this.sessionId, edgeEvent); - EntityId entityId = null; - switch (edgeEvent.getType()) { - case DEVICE: - entityId = new DeviceId(edgeEvent.getEntityId()); - break; - case ASSET: - entityId = new AssetId(edgeEvent.getEntityId()); - break; - case ENTITY_VIEW: - entityId = new EntityViewId(edgeEvent.getEntityId()); - break; - case DASHBOARD: - entityId = new DashboardId(edgeEvent.getEntityId()); - break; - case TENANT: - entityId = new TenantId(edgeEvent.getEntityId()); - break; - case CUSTOMER: - entityId = new CustomerId(edgeEvent.getEntityId()); - break; - case EDGE: - entityId = new EdgeId(edgeEvent.getEntityId()); - break; - } - DownlinkMsg downlinkMsg = null; - if (entityId != null) { - log.debug("[{}] Sending telemetry data msg, entityId [{}], body [{}]", this.sessionId, edgeEvent.getEntityId(), edgeEvent.getBody()); - try { - downlinkMsg = constructEntityDataProtoMsg(entityId, edgeEvent.getAction(), JsonUtils.parse(mapper.writeValueAsString(edgeEvent.getBody()))); - } catch (Exception e) { - log.warn("[{}] Can't send telemetry data msg, entityId [{}], body [{}]", this.sessionId, edgeEvent.getEntityId(), edgeEvent.getBody(), e); - } - } - return downlinkMsg; - } - private DownlinkMsg processEntityMessage(EdgeEvent edgeEvent, EdgeEventActionType action) { UpdateMsgType msgType = getResponseMsgType(edgeEvent.getAction()); log.trace("Executing processEntityMessage, edgeEvent [{}], action [{}], msgType [{}]", edgeEvent, action, msgType); switch (edgeEvent.getType()) { case DEVICE: - return processDevice(edgeEvent, msgType, action); + return ctx.getDeviceProcessor().processDeviceToEdge(edge, edgeEvent, msgType, action); case DEVICE_PROFILE: - return processDeviceProfile(edgeEvent, msgType, action); + return ctx.getDeviceProfileProcessor().processDeviceProfileToEdge(edgeEvent, msgType, action); case ASSET: - return processAsset(edgeEvent, msgType, action); + return ctx.getAssetProcessor().processAssetToEdge(edge, edgeEvent, msgType, action); case ENTITY_VIEW: - return processEntityView(edgeEvent, msgType, action); + return ctx.getEntityViewProcessor().processEntityViewToEdge(edge, edgeEvent, msgType, action); case DASHBOARD: - return processDashboard(edgeEvent, msgType, action); + return ctx.getDashboardProcessor().processDashboardToEdge(edge, edgeEvent, msgType, action); case CUSTOMER: - return processCustomer(edgeEvent, msgType, action); + return ctx.getCustomerProcessor().processCustomerToEdge(edgeEvent, msgType, action); case RULE_CHAIN: - return processRuleChain(edgeEvent, msgType, action); + return ctx.getRuleChainProcessor().processRuleChainToEdge(edge, edgeEvent, msgType, action); case RULE_CHAIN_METADATA: - return processRuleChainMetadata(edgeEvent, msgType); + return ctx.getRuleChainProcessor().processRuleChainMetadataToEdge(edgeEvent, msgType); case ALARM: - return processAlarm(edgeEvent, msgType); + return ctx.getAlarmProcessor().processAlarmToEdge(edge, edgeEvent, msgType); case USER: - return processUser(edgeEvent, msgType, action); + return ctx.getUserProcessor().processUserToEdge(edge, edgeEvent, msgType, action); case RELATION: - return processRelation(edgeEvent, msgType); + return ctx.getRelationProcessor().processRelationToEdge(edgeEvent, msgType); case WIDGETS_BUNDLE: - return processWidgetsBundle(edgeEvent, msgType, action); + return ctx.getWidgetBundleProcessor().processWidgetsBundleToEdge(edgeEvent, msgType, action); case WIDGET_TYPE: - return processWidgetType(edgeEvent, msgType, action); + return ctx.getWidgetTypeProcessor().processWidgetTypeToEdge(edgeEvent, msgType, action); case ADMIN_SETTINGS: - return processAdminSettings(edgeEvent); + return ctx.getAdminSettingsProcessor().processAdminSettingsToEdge(edgeEvent); default: log.warn("Unsupported edge event type [{}]", edgeEvent); return null; } } - private DownlinkMsg processDevice(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { - DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); - DownlinkMsg downlinkMsg = null; - switch (edgeEdgeEventActionType) { - case ADDED: - case UPDATED: - case ASSIGNED_TO_EDGE: - case ASSIGNED_TO_CUSTOMER: - case UNASSIGNED_FROM_CUSTOMER: - Device device = ctx.getDeviceService().findDeviceById(edgeEvent.getTenantId(), deviceId); - if (device != null) { - CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device); - DeviceUpdateMsg deviceUpdateMsg = - ctx.getDeviceMsgConstructor().constructDeviceUpdatedMsg(msgType, device, customerId, null); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg)) - .build(); - } - break; - case DELETED: - case UNASSIGNED_FROM_EDGE: - DeviceUpdateMsg deviceUpdateMsg = - ctx.getDeviceMsgConstructor().constructDeviceDeleteMsg(deviceId); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg)) - .build(); - break; - case CREDENTIALS_UPDATED: - DeviceCredentials deviceCredentials = ctx.getDeviceCredentialsService().findDeviceCredentialsByDeviceId(edge.getTenantId(), deviceId); - if (deviceCredentials != null) { - DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg = - ctx.getDeviceMsgConstructor().constructDeviceCredentialsUpdatedMsg(deviceCredentials); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllDeviceCredentialsUpdateMsg(Collections.singletonList(deviceCredentialsUpdateMsg)) - .build(); - } - break; - } - log.trace("[{}] device processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private DownlinkMsg processDeviceProfile(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { - DeviceProfileId deviceProfileId = new DeviceProfileId(edgeEvent.getEntityId()); - DownlinkMsg downlinkMsg = null; - switch (action) { - case ADDED: - case UPDATED: - DeviceProfile deviceProfile = ctx.getDeviceProfileService().findDeviceProfileById(edgeEvent.getTenantId(), deviceProfileId); - if (deviceProfile != null) { - DeviceProfileUpdateMsg deviceProfileUpdateMsg = - ctx.getDeviceProfileMsgConstructor().constructDeviceProfileUpdatedMsg(msgType, deviceProfile); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllDeviceProfileUpdateMsg(Collections.singletonList(deviceProfileUpdateMsg)) - .build(); - } - break; - case DELETED: - DeviceProfileUpdateMsg deviceProfileUpdateMsg = - ctx.getDeviceProfileMsgConstructor().constructDeviceProfileDeleteMsg(deviceProfileId); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllDeviceProfileUpdateMsg(Collections.singletonList(deviceProfileUpdateMsg)) - .build(); - break; - } - log.trace("[{}] device profile processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private DownlinkMsg processAsset(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { - AssetId assetId = new AssetId(edgeEvent.getEntityId()); - DownlinkMsg downlinkMsg = null; - switch (action) { - case ADDED: - case UPDATED: - case ASSIGNED_TO_EDGE: - case ASSIGNED_TO_CUSTOMER: - case UNASSIGNED_FROM_CUSTOMER: - Asset asset = ctx.getAssetService().findAssetById(edgeEvent.getTenantId(), assetId); - if (asset != null) { - CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(asset); - AssetUpdateMsg assetUpdateMsg = - ctx.getAssetMsgConstructor().constructAssetUpdatedMsg(msgType, asset, customerId); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllAssetUpdateMsg(Collections.singletonList(assetUpdateMsg)) - .build(); - } - break; - case DELETED: - case UNASSIGNED_FROM_EDGE: - AssetUpdateMsg assetUpdateMsg = - ctx.getAssetMsgConstructor().constructAssetDeleteMsg(assetId); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllAssetUpdateMsg(Collections.singletonList(assetUpdateMsg)) - .build(); - break; - } - log.trace("[{}] asset processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private DownlinkMsg processEntityView(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { - EntityViewId entityViewId = new EntityViewId(edgeEvent.getEntityId()); - DownlinkMsg downlinkMsg = null; - switch (action) { - case ADDED: - case UPDATED: - case ASSIGNED_TO_EDGE: - case ASSIGNED_TO_CUSTOMER: - case UNASSIGNED_FROM_CUSTOMER: - EntityView entityView = ctx.getEntityViewService().findEntityViewById(edgeEvent.getTenantId(), entityViewId); - if (entityView != null) { - CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(entityView); - EntityViewUpdateMsg entityViewUpdateMsg = - ctx.getEntityViewMsgConstructor().constructEntityViewUpdatedMsg(msgType, entityView, customerId); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllEntityViewUpdateMsg(Collections.singletonList(entityViewUpdateMsg)) - .build(); - } - break; - case DELETED: - case UNASSIGNED_FROM_EDGE: - EntityViewUpdateMsg entityViewUpdateMsg = - ctx.getEntityViewMsgConstructor().constructEntityViewDeleteMsg(entityViewId); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllEntityViewUpdateMsg(Collections.singletonList(entityViewUpdateMsg)) - .build(); - break; - } - log.trace("[{}] entity view processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private DownlinkMsg processDashboard(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { - DashboardId dashboardId = new DashboardId(edgeEvent.getEntityId()); - DownlinkMsg downlinkMsg = null; - switch (action) { - case ADDED: - case UPDATED: - case ASSIGNED_TO_EDGE: - case ASSIGNED_TO_CUSTOMER: - case UNASSIGNED_FROM_CUSTOMER: - Dashboard dashboard = ctx.getDashboardService().findDashboardById(edgeEvent.getTenantId(), dashboardId); - if (dashboard != null) { - CustomerId customerId = null; - if (!edge.getCustomerId().isNullUid() && dashboard.isAssignedToCustomer(edge.getCustomerId())) { - customerId = edge.getCustomerId(); - } - DashboardUpdateMsg dashboardUpdateMsg = - ctx.getDashboardMsgConstructor().constructDashboardUpdatedMsg(msgType, dashboard, customerId); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllDashboardUpdateMsg(Collections.singletonList(dashboardUpdateMsg)) - .build(); - } - break; - case DELETED: - case UNASSIGNED_FROM_EDGE: - DashboardUpdateMsg dashboardUpdateMsg = - ctx.getDashboardMsgConstructor().constructDashboardDeleteMsg(dashboardId); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllDashboardUpdateMsg(Collections.singletonList(dashboardUpdateMsg)) - .build(); - break; - } - log.trace("[{}] dashboard processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private DownlinkMsg processCustomer(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { - CustomerId customerId = new CustomerId(edgeEvent.getEntityId()); - DownlinkMsg downlinkMsg = null; - switch (action) { - case ADDED: - case UPDATED: - Customer customer = ctx.getCustomerService().findCustomerById(edgeEvent.getTenantId(), customerId); - if (customer != null) { - CustomerUpdateMsg customerUpdateMsg = - ctx.getCustomerMsgConstructor().constructCustomerUpdatedMsg(msgType, customer); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllCustomerUpdateMsg(Collections.singletonList(customerUpdateMsg)) - .build(); - } - break; - case DELETED: - CustomerUpdateMsg customerUpdateMsg = - ctx.getCustomerMsgConstructor().constructCustomerDeleteMsg(customerId); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllCustomerUpdateMsg(Collections.singletonList(customerUpdateMsg)) - .build(); - break; - } - log.trace("[{}] customer processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private DownlinkMsg processRuleChain(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { - RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId()); - DownlinkMsg downlinkMsg = null; - switch (action) { - case ADDED: - case UPDATED: - case ASSIGNED_TO_EDGE: - RuleChain ruleChain = ctx.getRuleChainService().findRuleChainById(edgeEvent.getTenantId(), ruleChainId); - if (ruleChain != null) { - RuleChainUpdateMsg ruleChainUpdateMsg = - ctx.getRuleChainMsgConstructor().constructRuleChainUpdatedMsg(edge.getRootRuleChainId(), msgType, ruleChain); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllRuleChainUpdateMsg(Collections.singletonList(ruleChainUpdateMsg)) - .build(); - } - break; - case DELETED: - case UNASSIGNED_FROM_EDGE: - downlinkMsg = DownlinkMsg.newBuilder() - .addAllRuleChainUpdateMsg(Collections.singletonList(ctx.getRuleChainMsgConstructor().constructRuleChainDeleteMsg(ruleChainId))) - .build(); - break; - } - log.trace("[{}] rule chain processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private DownlinkMsg processRuleChainMetadata(EdgeEvent edgeEvent, UpdateMsgType msgType) { - RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId()); - RuleChain ruleChain = ctx.getRuleChainService().findRuleChainById(edgeEvent.getTenantId(), ruleChainId); - DownlinkMsg downlinkMsg = null; - if (ruleChain != null) { - RuleChainMetaData ruleChainMetaData = ctx.getRuleChainService().loadRuleChainMetaData(edgeEvent.getTenantId(), ruleChainId); - RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = - ctx.getRuleChainMsgConstructor().constructRuleChainMetadataUpdatedMsg(msgType, ruleChainMetaData); - if (ruleChainMetadataUpdateMsg != null) { - downlinkMsg = DownlinkMsg.newBuilder() - .addAllRuleChainMetadataUpdateMsg(Collections.singletonList(ruleChainMetadataUpdateMsg)) - .build(); - } - } - log.trace("[{}] rule chain metadata processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private DownlinkMsg processUser(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { - UserId userId = new UserId(edgeEvent.getEntityId()); - DownlinkMsg downlinkMsg = null; - switch (edgeEdgeEventActionType) { - case ADDED: - case UPDATED: - User user = ctx.getUserService().findUserById(edgeEvent.getTenantId(), userId); - if (user != null) { - CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(user); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllUserUpdateMsg(Collections.singletonList(ctx.getUserMsgConstructor().constructUserUpdatedMsg(msgType, user, customerId))) - .build(); - } - break; - case DELETED: - downlinkMsg = DownlinkMsg.newBuilder() - .addAllUserUpdateMsg(Collections.singletonList(ctx.getUserMsgConstructor().constructUserDeleteMsg(userId))) - .build(); - break; - case CREDENTIALS_UPDATED: - UserCredentials userCredentialsByUserId = ctx.getUserService().findUserCredentialsByUserId(edge.getTenantId(), userId); - if (userCredentialsByUserId != null && userCredentialsByUserId.isEnabled()) { - UserCredentialsUpdateMsg userCredentialsUpdateMsg = - ctx.getUserMsgConstructor().constructUserCredentialsUpdatedMsg(userCredentialsByUserId); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllUserCredentialsUpdateMsg(Collections.singletonList(userCredentialsUpdateMsg)) - .build(); - } - } - log.trace("[{}] user processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private CustomerId getCustomerIdIfEdgeAssignedToCustomer(HasCustomerId hasCustomerIdEntity) { - if (!edge.getCustomerId().isNullUid() && edge.getCustomerId().equals(hasCustomerIdEntity.getCustomerId())) { - return edge.getCustomerId(); - } else { - return null; - } - } - - private DownlinkMsg processRelation(EdgeEvent edgeEvent, UpdateMsgType msgType) { - EntityRelation entityRelation = mapper.convertValue(edgeEvent.getBody(), EntityRelation.class); - RelationUpdateMsg r = ctx.getRelationMsgConstructor().constructRelationUpdatedMsg(msgType, entityRelation); - DownlinkMsg downlinkMsg = DownlinkMsg.newBuilder() - .addAllRelationUpdateMsg(Collections.singletonList(r)) - .build(); - log.trace("[{}] relation processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private DownlinkMsg processAlarm(EdgeEvent edgeEvent, UpdateMsgType msgType) { - DownlinkMsg downlinkMsg = null; - try { - AlarmId alarmId = new AlarmId(edgeEvent.getEntityId()); - Alarm alarm = ctx.getAlarmService().findAlarmByIdAsync(edgeEvent.getTenantId(), alarmId).get(); - if (alarm != null) { - downlinkMsg = DownlinkMsg.newBuilder() - .addAllAlarmUpdateMsg(Collections.singletonList(ctx.getAlarmMsgConstructor().constructAlarmUpdatedMsg(edge.getTenantId(), msgType, alarm))) - .build(); - } - } catch (Exception e) { - log.error("Can't process alarm msg [{}] [{}]", edgeEvent, msgType, e); - } - log.trace("[{}] alarm processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private DownlinkMsg processWidgetsBundle(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { - WidgetsBundleId widgetsBundleId = new WidgetsBundleId(edgeEvent.getEntityId()); - DownlinkMsg downlinkMsg = null; - switch (edgeEdgeEventActionType) { - case ADDED: - case UPDATED: - WidgetsBundle widgetsBundle = ctx.getWidgetsBundleService().findWidgetsBundleById(edgeEvent.getTenantId(), widgetsBundleId); - if (widgetsBundle != null) { - WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = - ctx.getWidgetsBundleMsgConstructor().constructWidgetsBundleUpdateMsg(msgType, widgetsBundle); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllWidgetsBundleUpdateMsg(Collections.singletonList(widgetsBundleUpdateMsg)) - .build(); - } - break; - case DELETED: - WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = - ctx.getWidgetsBundleMsgConstructor().constructWidgetsBundleDeleteMsg(widgetsBundleId); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllWidgetsBundleUpdateMsg(Collections.singletonList(widgetsBundleUpdateMsg)) - .build(); - break; - } - log.trace("[{}] widget bundle processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private DownlinkMsg processWidgetType(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { - WidgetTypeId widgetTypeId = new WidgetTypeId(edgeEvent.getEntityId()); - DownlinkMsg downlinkMsg = null; - switch (edgeEdgeEventActionType) { - case ADDED: - case UPDATED: - WidgetType widgetType = ctx.getWidgetTypeService().findWidgetTypeById(edgeEvent.getTenantId(), widgetTypeId); - if (widgetType != null) { - WidgetTypeUpdateMsg widgetTypeUpdateMsg = - ctx.getWidgetTypeMsgConstructor().constructWidgetTypeUpdateMsg(msgType, widgetType); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllWidgetTypeUpdateMsg(Collections.singletonList(widgetTypeUpdateMsg)) - .build(); - } - break; - case DELETED: - WidgetTypeUpdateMsg widgetTypeUpdateMsg = - ctx.getWidgetTypeMsgConstructor().constructWidgetTypeDeleteMsg(widgetTypeId); - downlinkMsg = DownlinkMsg.newBuilder() - .addAllWidgetTypeUpdateMsg(Collections.singletonList(widgetTypeUpdateMsg)) - .build(); - break; - } - log.trace("[{}] widget type processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - - private DownlinkMsg processAdminSettings(EdgeEvent edgeEvent) { - AdminSettings adminSettings = mapper.convertValue(edgeEvent.getBody(), AdminSettings.class); - AdminSettingsUpdateMsg t = ctx.getAdminSettingsMsgConstructor().constructAdminSettingsUpdateMsg(adminSettings); - DownlinkMsg downlinkMsg = DownlinkMsg.newBuilder() - .addAllAdminSettingsUpdateMsg(Collections.singletonList(t)) - .build(); - log.trace("[{}] admin settings processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } - private UpdateMsgType getResponseMsgType(EdgeEventActionType actionType) { switch (actionType) { case UPDATED: @@ -972,41 +479,33 @@ public final class EdgeGrpcSession implements Closeable { } } - private DownlinkMsg constructEntityDataProtoMsg(EntityId entityId, EdgeEventActionType actionType, JsonElement entityData) { - EntityDataProto entityDataProto = ctx.getEntityDataMsgConstructor().constructEntityDataMsg(entityId, actionType, entityData); - DownlinkMsg downlinkMsg = DownlinkMsg.newBuilder() - .addAllEntityData(Collections.singletonList(entityDataProto)) - .build(); - log.trace("[{}] entity data proto processed [{}]", this.sessionId, downlinkMsg); - return downlinkMsg; - } private ListenableFuture> processUplinkMsg(UplinkMsg uplinkMsg) { List> result = new ArrayList<>(); try { if (uplinkMsg.getEntityDataCount() > 0) { for (EntityDataProto entityData : uplinkMsg.getEntityDataList()) { - result.addAll(ctx.getTelemetryProcessor().onTelemetryUpdate(edge.getTenantId(), edge.getCustomerId(), entityData)); + result.addAll(ctx.getTelemetryProcessor().processTelemetryFromEdge(edge.getTenantId(), edge.getCustomerId(), entityData)); } } if (uplinkMsg.getDeviceUpdateMsgCount() > 0) { for (DeviceUpdateMsg deviceUpdateMsg : uplinkMsg.getDeviceUpdateMsgList()) { - result.add(ctx.getDeviceProcessor().onDeviceUpdate(edge.getTenantId(), edge, deviceUpdateMsg)); + result.add(ctx.getDeviceProcessor().processDeviceFromEdge(edge.getTenantId(), edge, deviceUpdateMsg)); } } if (uplinkMsg.getDeviceCredentialsUpdateMsgCount() > 0) { for (DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg : uplinkMsg.getDeviceCredentialsUpdateMsgList()) { - result.add(ctx.getDeviceProcessor().onDeviceCredentialsUpdate(edge.getTenantId(), deviceCredentialsUpdateMsg)); + result.add(ctx.getDeviceProcessor().processDeviceCredentialsFromEdge(edge.getTenantId(), deviceCredentialsUpdateMsg)); } } if (uplinkMsg.getAlarmUpdateMsgCount() > 0) { for (AlarmUpdateMsg alarmUpdateMsg : uplinkMsg.getAlarmUpdateMsgList()) { - result.add(ctx.getAlarmProcessor().onAlarmUpdate(edge.getTenantId(), alarmUpdateMsg)); + result.add(ctx.getAlarmProcessor().processAlarmFromEdge(edge.getTenantId(), alarmUpdateMsg)); } } if (uplinkMsg.getRelationUpdateMsgCount() > 0) { for (RelationUpdateMsg relationUpdateMsg : uplinkMsg.getRelationUpdateMsgList()) { - result.add(ctx.getRelationProcessor().onRelationUpdate(edge.getTenantId(), relationUpdateMsg)); + result.add(ctx.getRelationProcessor().processRelationFromEdge(edge.getTenantId(), relationUpdateMsg)); } } if (uplinkMsg.getRuleChainMetadataRequestMsgCount() > 0) { @@ -1036,7 +535,7 @@ public final class EdgeGrpcSession implements Closeable { } if (uplinkMsg.getDeviceRpcCallMsgCount() > 0) { for (DeviceRpcCallMsg deviceRpcCallMsg : uplinkMsg.getDeviceRpcCallMsgList()) { - result.add(ctx.getDeviceProcessor().processDeviceRpcCallResponseMsg(edge.getTenantId(), deviceRpcCallMsg)); + result.add(ctx.getDeviceProcessor().processDeviceRpcCallResponseFromEdge(edge.getTenantId(), deviceRpcCallMsg)); } } if (uplinkMsg.getDeviceProfileDevicesRequestMsgCount() > 0) { @@ -1107,7 +606,7 @@ public final class EdgeGrpcSession implements Closeable { .setCloudType("CE"); if (edge.getCustomerId() != null) { builder.setCustomerIdMSB(edge.getCustomerId().getId().getMostSignificantBits()) - .setCustomerIdLSB(edge.getCustomerId().getId().getLeastSignificantBits()); + .setCustomerIdLSB(edge.getCustomerId().getId().getLeastSignificantBits()); } return builder .build(); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsProcessor.java new file mode 100644 index 0000000000..53f46900fa --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsProcessor.java @@ -0,0 +1,41 @@ +/** + * Copyright © 2016-2021 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.processor; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.AdminSettings; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.gen.edge.AdminSettingsUpdateMsg; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.Collections; + +@Component +@Slf4j +@TbCoreComponent +public class AdminSettingsProcessor extends BaseProcessor { + + public DownlinkMsg processAdminSettingsToEdge(EdgeEvent edgeEvent) { + AdminSettings adminSettings = mapper.convertValue(edgeEvent.getBody(), AdminSettings.class); + AdminSettingsUpdateMsg t = adminSettingsMsgConstructor.constructAdminSettingsUpdateMsg(adminSettings); + return DownlinkMsg.newBuilder() + .addAllAdminSettingsUpdateMsg(Collections.singletonList(t)) + .build(); + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmProcessor.java index 5e7e1e5844..5ceb82381a 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmProcessor.java @@ -23,17 +23,24 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmStatus; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.gen.edge.AlarmUpdateMsg; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; +import java.util.Collections; + @Component @Slf4j @TbCoreComponent public class AlarmProcessor extends BaseProcessor { - public ListenableFuture onAlarmUpdate(TenantId tenantId, AlarmUpdateMsg alarmUpdateMsg) { + public ListenableFuture processAlarmFromEdge(TenantId tenantId, AlarmUpdateMsg alarmUpdateMsg) { log.trace("[{}] onAlarmUpdate [{}]", tenantId, alarmUpdateMsg); EntityId originatorId = getAlarmOriginator(tenantId, alarmUpdateMsg.getOriginatorName(), EntityType.valueOf(alarmUpdateMsg.getOriginatorType())); @@ -96,4 +103,20 @@ public class AlarmProcessor extends BaseProcessor { return null; } } + + public DownlinkMsg processAlarmToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType) { + DownlinkMsg downlinkMsg = null; + try { + AlarmId alarmId = new AlarmId(edgeEvent.getEntityId()); + Alarm alarm = alarmService.findAlarmByIdAsync(edgeEvent.getTenantId(), alarmId).get(); + if (alarm != null) { + downlinkMsg = DownlinkMsg.newBuilder() + .addAllAlarmUpdateMsg(Collections.singletonList(alarmMsgConstructor.constructAlarmUpdatedMsg(edge.getTenantId(), msgType, alarm))) + .build(); + } + } catch (Exception e) { + log.error("Can't process alarm msg [{}] [{}]", edgeEvent, msgType, e); + } + return downlinkMsg; + } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetProcessor.java new file mode 100644 index 0000000000..e3c8d9d1e8 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetProcessor.java @@ -0,0 +1,68 @@ +/** + * Copyright © 2016-2021 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.processor; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.id.AssetId; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.gen.edge.AssetUpdateMsg; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.Collections; + +@Component +@Slf4j +@TbCoreComponent +public class AssetProcessor extends BaseProcessor { + + public DownlinkMsg processAssetToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { + AssetId assetId = new AssetId(edgeEvent.getEntityId()); + DownlinkMsg downlinkMsg = null; + switch (action) { + case ADDED: + case UPDATED: + case ASSIGNED_TO_EDGE: + case ASSIGNED_TO_CUSTOMER: + case UNASSIGNED_FROM_CUSTOMER: + Asset asset = assetService.findAssetById(edgeEvent.getTenantId(), assetId); + if (asset != null) { + CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(asset, edge); + AssetUpdateMsg assetUpdateMsg = + assetMsgConstructor.constructAssetUpdatedMsg(msgType, asset, customerId); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllAssetUpdateMsg(Collections.singletonList(assetUpdateMsg)) + .build(); + } + break; + case DELETED: + case UNASSIGNED_FROM_EDGE: + AssetUpdateMsg assetUpdateMsg = + assetMsgConstructor.constructAssetDeleteMsg(assetId); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllAssetUpdateMsg(Collections.singletonList(assetUpdateMsg)) + .build(); + break; + } + return downlinkMsg; + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java index cf7f9e21fb..8ea8eac1df 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java @@ -23,9 +23,12 @@ import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.beans.factory.annotation.Autowired; +import org.thingsboard.server.common.data.HasCustomerId; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -35,14 +38,31 @@ import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.device.DeviceCredentialsService; +import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.relation.RelationService; +import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.user.UserService; +import org.thingsboard.server.dao.widget.WidgetTypeService; +import org.thingsboard.server.dao.widget.WidgetsBundleService; +import org.thingsboard.server.service.edge.rpc.constructor.AdminSettingsMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.AlarmMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.AssetMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.CustomerMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.DashboardMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.DeviceMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.DeviceProfileMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.EntityDataMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.EntityViewMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.RelationMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.RuleChainMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.UserMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.WidgetTypeMsgConstructor; +import org.thingsboard.server.service.edge.rpc.constructor.WidgetsBundleMsgConstructor; import org.thingsboard.server.service.executors.DbCallbackExecutorService; -import org.thingsboard.server.service.profile.DefaultTbDeviceProfileCache; import org.thingsboard.server.service.profile.TbDeviceProfileCache; import org.thingsboard.server.service.queue.TbClusterService; import org.thingsboard.server.service.state.DeviceStateService; @@ -52,6 +72,9 @@ public abstract class BaseProcessor { protected static final ObjectMapper mapper = new ObjectMapper(); + @Autowired + protected RuleChainService ruleChainService; + @Autowired protected AlarmService alarmService; @@ -79,6 +102,9 @@ public abstract class BaseProcessor { @Autowired protected UserService userService; + @Autowired + protected DeviceProfileService deviceProfileService; + @Autowired protected RelationService relationService; @@ -97,6 +123,54 @@ public abstract class BaseProcessor { @Autowired protected EdgeEventService edgeEventService; + @Autowired + protected WidgetsBundleService widgetsBundleService; + + @Autowired + protected WidgetTypeService widgetTypeService; + + @Autowired + protected EntityDataMsgConstructor entityDataMsgConstructor; + + @Autowired + protected RuleChainMsgConstructor ruleChainMsgConstructor; + + @Autowired + protected AlarmMsgConstructor alarmMsgConstructor; + + @Autowired + protected DeviceMsgConstructor deviceMsgConstructor; + + @Autowired + protected AssetMsgConstructor assetMsgConstructor; + + @Autowired + protected EntityViewMsgConstructor entityViewMsgConstructor; + + @Autowired + protected DashboardMsgConstructor dashboardMsgConstructor; + + @Autowired + protected RelationMsgConstructor relationMsgConstructor; + + @Autowired + protected UserMsgConstructor userMsgConstructor; + + @Autowired + protected CustomerMsgConstructor customerMsgConstructor; + + @Autowired + protected DeviceProfileMsgConstructor deviceProfileMsgConstructor; + + @Autowired + protected WidgetsBundleMsgConstructor widgetsBundleMsgConstructor; + + @Autowired + protected WidgetTypeMsgConstructor widgetTypeMsgConstructor; + + @Autowired + protected AdminSettingsMsgConstructor adminSettingsMsgConstructor; + @Autowired protected DbCallbackExecutorService dbCallbackExecutorService; @@ -133,4 +207,12 @@ public abstract class BaseProcessor { }, dbCallbackExecutorService); return future; } + + protected CustomerId getCustomerIdIfEdgeAssignedToCustomer(HasCustomerId hasCustomerIdEntity, Edge edge) { + if (!edge.getCustomerId().isNullUid() && edge.getCustomerId().equals(hasCustomerIdEntity.getCustomerId())) { + return edge.getCustomerId(); + } else { + return null; + } + } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerProcessor.java new file mode 100644 index 0000000000..476458bd05 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerProcessor.java @@ -0,0 +1,61 @@ +/** + * Copyright © 2016-2021 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.processor; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.gen.edge.CustomerUpdateMsg; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.Collections; + +@Component +@Slf4j +@TbCoreComponent +public class CustomerProcessor extends BaseProcessor { + + public DownlinkMsg processCustomerToEdge(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { + CustomerId customerId = new CustomerId(edgeEvent.getEntityId()); + DownlinkMsg downlinkMsg = null; + switch (action) { + case ADDED: + case UPDATED: + Customer customer = customerService.findCustomerById(edgeEvent.getTenantId(), customerId); + if (customer != null) { + CustomerUpdateMsg customerUpdateMsg = + customerMsgConstructor.constructCustomerUpdatedMsg(msgType, customer); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllCustomerUpdateMsg(Collections.singletonList(customerUpdateMsg)) + .build(); + } + break; + case DELETED: + CustomerUpdateMsg customerUpdateMsg = + customerMsgConstructor.constructCustomerDeleteMsg(customerId); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllCustomerUpdateMsg(Collections.singletonList(customerUpdateMsg)) + .build(); + break; + } + return downlinkMsg; + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardProcessor.java new file mode 100644 index 0000000000..f6df66cf0e --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardProcessor.java @@ -0,0 +1,71 @@ +/** + * Copyright © 2016-2021 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.processor; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.Dashboard; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DashboardId; +import org.thingsboard.server.gen.edge.DashboardUpdateMsg; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.Collections; + +@Component +@Slf4j +@TbCoreComponent +public class DashboardProcessor extends BaseProcessor { + + public DownlinkMsg processDashboardToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { + DashboardId dashboardId = new DashboardId(edgeEvent.getEntityId()); + DownlinkMsg downlinkMsg = null; + switch (action) { + case ADDED: + case UPDATED: + case ASSIGNED_TO_EDGE: + case ASSIGNED_TO_CUSTOMER: + case UNASSIGNED_FROM_CUSTOMER: + Dashboard dashboard = dashboardService.findDashboardById(edgeEvent.getTenantId(), dashboardId); + if (dashboard != null) { + CustomerId customerId = null; + if (!edge.getCustomerId().isNullUid() && dashboard.isAssignedToCustomer(edge.getCustomerId())) { + customerId = edge.getCustomerId(); + } + DashboardUpdateMsg dashboardUpdateMsg = + dashboardMsgConstructor.constructDashboardUpdatedMsg(msgType, dashboard, customerId); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllDashboardUpdateMsg(Collections.singletonList(dashboardUpdateMsg)) + .build(); + } + break; + case DELETED: + case UNASSIGNED_FROM_EDGE: + DashboardUpdateMsg dashboardUpdateMsg = + dashboardMsgConstructor.constructDashboardDeleteMsg(dashboardId); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllDashboardUpdateMsg(Collections.singletonList(dashboardUpdateMsg)) + .build(); + break; + } + return downlinkMsg; + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java index 216e5560d5..2325b6736d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java @@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.CustomerId; @@ -51,12 +52,15 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; import org.thingsboard.server.gen.edge.DeviceUpdateMsg; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; import org.thingsboard.server.queue.TbQueueCallback; import org.thingsboard.server.queue.TbQueueMsgMetadata; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; +import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.concurrent.locks.ReentrantLock; @@ -68,7 +72,9 @@ public class DeviceProcessor extends BaseProcessor { private static final ReentrantLock deviceCreationLock = new ReentrantLock(); - public ListenableFuture onDeviceUpdate(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { + // TODO onDeviceUpdateFromEdge onDeviceUpdateToEdge + + public ListenableFuture processDeviceFromEdge(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { log.trace("[{}] onDeviceUpdate [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); switch (deviceUpdateMsg.getMsgType()) { case ENTITY_CREATED_RPC_MESSAGE: @@ -133,7 +139,7 @@ public class DeviceProcessor extends BaseProcessor { return Futures.immediateFuture(null); } - public ListenableFuture onDeviceCredentialsUpdate(TenantId tenantId, DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg) { + public ListenableFuture processDeviceCredentialsFromEdge(TenantId tenantId, DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg) { log.debug("Executing onDeviceCredentialsUpdate, deviceCredentialsUpdateMsg [{}]", deviceCredentialsUpdateMsg); DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsUpdateMsg.getDeviceIdMSB(), deviceCredentialsUpdateMsg.getDeviceIdLSB())); ListenableFuture deviceFuture = deviceService.findDeviceByIdAsync(tenantId, deviceId); @@ -264,7 +270,7 @@ public class DeviceProcessor extends BaseProcessor { return metaData; } - public ListenableFuture processDeviceRpcCallResponseMsg(TenantId tenantId, DeviceRpcCallMsg deviceRpcCallMsg) { + public ListenableFuture processDeviceRpcCallResponseFromEdge(TenantId tenantId, DeviceRpcCallMsg deviceRpcCallMsg) { log.trace("[{}] processDeviceRpcCallResponseMsg [{}]", tenantId, deviceRpcCallMsg); SettableFuture futureToSet = SettableFuture.create(); UUID requestUuid = new UUID(deviceRpcCallMsg.getRequestUuidMSB(), deviceRpcCallMsg.getRequestUuidLSB()); @@ -296,4 +302,54 @@ public class DeviceProcessor extends BaseProcessor { return futureToSet; } + public DownlinkMsg processDeviceToEdge(Edge edge, EdgeEvent edgeEvent, + UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { + DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); + DownlinkMsg downlinkMsg = null; + switch (edgeEdgeEventActionType) { + case ADDED: + case UPDATED: + case ASSIGNED_TO_EDGE: + case ASSIGNED_TO_CUSTOMER: + case UNASSIGNED_FROM_CUSTOMER: + Device device = deviceService.findDeviceById(edgeEvent.getTenantId(), deviceId); + if (device != null) { + CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device, edge); + DeviceUpdateMsg deviceUpdateMsg = + deviceMsgConstructor.constructDeviceUpdatedMsg(msgType, device, customerId, null); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg)) + .build(); + } + break; + case DELETED: + case UNASSIGNED_FROM_EDGE: + DeviceUpdateMsg deviceUpdateMsg = + deviceMsgConstructor.constructDeviceDeleteMsg(deviceId); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg)) + .build(); + break; + case CREDENTIALS_UPDATED: + DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(edge.getTenantId(), deviceId); + if (deviceCredentials != null) { + DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg = + deviceMsgConstructor.constructDeviceCredentialsUpdatedMsg(deviceCredentials); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllDeviceCredentialsUpdateMsg(Collections.singletonList(deviceCredentialsUpdateMsg)) + .build(); + } + break; + } + return downlinkMsg; + } + + public DownlinkMsg processRpcCallMsgToEdge(EdgeEvent edgeEvent) { + log.trace("Executing processRpcCall, edgeEvent [{}]", edgeEvent); + DeviceRpcCallMsg deviceRpcCallMsg = + deviceMsgConstructor.constructDeviceRpcCallMsg(edgeEvent.getEntityId(), edgeEvent.getBody()); + return DownlinkMsg.newBuilder() + .addAllDeviceRpcCallMsg(Collections.singletonList(deviceRpcCallMsg)) + .build(); + } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileProcessor.java new file mode 100644 index 0000000000..6aab6838fd --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileProcessor.java @@ -0,0 +1,62 @@ +/** + * Copyright © 2016-2021 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.processor; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.id.DeviceProfileId; +import org.thingsboard.server.gen.edge.DeviceProfileUpdateMsg; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.Collections; + +@Component +@Slf4j +@TbCoreComponent +public class DeviceProfileProcessor extends BaseProcessor { + + public DownlinkMsg processDeviceProfileToEdge(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { + DeviceProfileId deviceProfileId = new DeviceProfileId(edgeEvent.getEntityId()); + DownlinkMsg downlinkMsg = null; + switch (action) { + case ADDED: + case UPDATED: + DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(edgeEvent.getTenantId(), deviceProfileId); + if (deviceProfile != null) { + DeviceProfileUpdateMsg deviceProfileUpdateMsg = + deviceProfileMsgConstructor.constructDeviceProfileUpdatedMsg(msgType, deviceProfile); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllDeviceProfileUpdateMsg(Collections.singletonList(deviceProfileUpdateMsg)) + .build(); + } + break; + case DELETED: + DeviceProfileUpdateMsg deviceProfileUpdateMsg = + deviceProfileMsgConstructor.constructDeviceProfileDeleteMsg(deviceProfileId); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllDeviceProfileUpdateMsg(Collections.singletonList(deviceProfileUpdateMsg)) + .build(); + break; + } + return downlinkMsg; + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityProcessor.java new file mode 100644 index 0000000000..c5865b0ff9 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityProcessor.java @@ -0,0 +1,73 @@ +/** + * Copyright © 2016-2021 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.processor; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.DeviceUpdateMsg; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.Collections; + +@Component +@Slf4j +@TbCoreComponent +public class EntityProcessor extends BaseProcessor { + + public DownlinkMsg processEntityMergeRequestMessageToEdge(Edge edge, EdgeEvent edgeEvent) { + DownlinkMsg downlinkMsg = null; + if (EdgeEventType.DEVICE.equals(edgeEvent.getType())) { + DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); + Device device = deviceService.findDeviceById(edge.getTenantId(), deviceId); + CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device, edge); + String conflictName = null; + if(edgeEvent.getBody() != null) { + conflictName = edgeEvent.getBody().get("conflictName").asText(); + } + DeviceUpdateMsg d = deviceMsgConstructor + .constructDeviceUpdatedMsg(UpdateMsgType.ENTITY_MERGE_RPC_MESSAGE, device, customerId, conflictName); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllDeviceUpdateMsg(Collections.singletonList(d)) + .build(); + } + return downlinkMsg; + } + + public DownlinkMsg processCredentialsRequestMessageToEdge(EdgeEvent edgeEvent) { + DownlinkMsg downlinkMsg = null; + if (EdgeEventType.DEVICE.equals(edgeEvent.getType())) { + DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); + DeviceCredentialsRequestMsg deviceCredentialsRequestMsg = DeviceCredentialsRequestMsg.newBuilder() + .setDeviceIdMSB(deviceId.getId().getMostSignificantBits()) + .setDeviceIdLSB(deviceId.getId().getLeastSignificantBits()) + .build(); + DownlinkMsg.Builder builder = DownlinkMsg.newBuilder() + .addAllDeviceCredentialsRequestMsg(Collections.singletonList(deviceCredentialsRequestMsg)); + downlinkMsg = builder.build(); + } + return downlinkMsg; + } +} + diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewProcessor.java new file mode 100644 index 0000000000..e62e084471 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewProcessor.java @@ -0,0 +1,68 @@ +/** + * Copyright © 2016-2021 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.processor; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.EntityView; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EntityViewId; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.Collections; + +@Component +@Slf4j +@TbCoreComponent +public class EntityViewProcessor extends BaseProcessor { + + public DownlinkMsg processEntityViewToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { + EntityViewId entityViewId = new EntityViewId(edgeEvent.getEntityId()); + DownlinkMsg downlinkMsg = null; + switch (action) { + case ADDED: + case UPDATED: + case ASSIGNED_TO_EDGE: + case ASSIGNED_TO_CUSTOMER: + case UNASSIGNED_FROM_CUSTOMER: + EntityView entityView = entityViewService.findEntityViewById(edgeEvent.getTenantId(), entityViewId); + if (entityView != null) { + CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(entityView, edge); + EntityViewUpdateMsg entityViewUpdateMsg = + entityViewMsgConstructor.constructEntityViewUpdatedMsg(msgType, entityView, customerId); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllEntityViewUpdateMsg(Collections.singletonList(entityViewUpdateMsg)) + .build(); + } + break; + case DELETED: + case UNASSIGNED_FROM_EDGE: + EntityViewUpdateMsg entityViewUpdateMsg = + entityViewMsgConstructor.constructEntityViewDeleteMsg(entityViewId); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllEntityViewUpdateMsg(Collections.singletonList(entityViewUpdateMsg)) + .build(); + break; + } + return downlinkMsg; + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationProcessor.java index b21a5bd195..eb96df6729 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationProcessor.java @@ -20,6 +20,7 @@ import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.AssetId; @@ -33,9 +34,12 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.RelationTypeGroup; +import org.thingsboard.server.gen.edge.DownlinkMsg; import org.thingsboard.server.gen.edge.RelationUpdateMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; +import java.util.Collections; import java.util.UUID; @Component @@ -43,7 +47,7 @@ import java.util.UUID; @TbCoreComponent public class RelationProcessor extends BaseProcessor { - public ListenableFuture onRelationUpdate(TenantId tenantId, RelationUpdateMsg relationUpdateMsg) { + public ListenableFuture processRelationFromEdge(TenantId tenantId, RelationUpdateMsg relationUpdateMsg) { log.trace("[{}] onRelationUpdate [{}]", tenantId, relationUpdateMsg); try { EntityRelation entityRelation = new EntityRelation(); @@ -100,5 +104,12 @@ public class RelationProcessor extends BaseProcessor { } } + public DownlinkMsg processRelationToEdge(EdgeEvent edgeEvent, UpdateMsgType msgType) { + EntityRelation entityRelation = mapper.convertValue(edgeEvent.getBody(), EntityRelation.class); + RelationUpdateMsg r = relationMsgConstructor.constructRelationUpdatedMsg(msgType, entityRelation); + return DownlinkMsg.newBuilder() + .addAllRelationUpdateMsg(Collections.singletonList(r)) + .build(); + } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainProcessor.java new file mode 100644 index 0000000000..c30e9bf45f --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainProcessor.java @@ -0,0 +1,81 @@ +/** + * Copyright © 2016-2021 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.processor; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainMetaData; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg; +import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.Collections; + +@Component +@Slf4j +@TbCoreComponent +public class RuleChainProcessor extends BaseProcessor { + + public DownlinkMsg processRuleChainToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { + RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId()); + DownlinkMsg downlinkMsg = null; + switch (action) { + case ADDED: + case UPDATED: + case ASSIGNED_TO_EDGE: + RuleChain ruleChain = ruleChainService.findRuleChainById(edgeEvent.getTenantId(), ruleChainId); + if (ruleChain != null) { + RuleChainUpdateMsg ruleChainUpdateMsg = + ruleChainMsgConstructor.constructRuleChainUpdatedMsg(edge.getRootRuleChainId(), msgType, ruleChain); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllRuleChainUpdateMsg(Collections.singletonList(ruleChainUpdateMsg)) + .build(); + } + break; + case DELETED: + case UNASSIGNED_FROM_EDGE: + downlinkMsg = DownlinkMsg.newBuilder() + .addAllRuleChainUpdateMsg(Collections.singletonList(ruleChainMsgConstructor.constructRuleChainDeleteMsg(ruleChainId))) + .build(); + break; + } + return downlinkMsg; + } + + public DownlinkMsg processRuleChainMetadataToEdge(EdgeEvent edgeEvent, UpdateMsgType msgType) { + RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId()); + RuleChain ruleChain = ruleChainService.findRuleChainById(edgeEvent.getTenantId(), ruleChainId); + DownlinkMsg downlinkMsg = null; + if (ruleChain != null) { + RuleChainMetaData ruleChainMetaData = ruleChainService.loadRuleChainMetaData(edgeEvent.getTenantId(), ruleChainId); + RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = + ruleChainMsgConstructor.constructRuleChainMetadataUpdatedMsg(msgType, ruleChainMetaData); + if (ruleChainMetadataUpdateMsg != null) { + downlinkMsg = DownlinkMsg.newBuilder() + .addAllRuleChainMetadataUpdateMsg(Collections.singletonList(ruleChainMetadataUpdateMsg)) + .build(); + } + } + return downlinkMsg; + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryProcessor.java index 53ef04fe85..b42ceb40ab 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryProcessor.java @@ -15,11 +15,13 @@ */ package org.thingsboard.server.service.edge.rpc.processor; +import com.fasterxml.jackson.core.JsonProcessingException; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; import com.google.gson.Gson; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.ImmutablePair; @@ -32,10 +34,13 @@ import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.RuleChainId; @@ -50,6 +55,7 @@ import org.thingsboard.server.common.msg.session.SessionMsgType; import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.common.transport.util.JsonUtils; import org.thingsboard.server.gen.edge.AttributeDeleteMsg; +import org.thingsboard.server.gen.edge.DownlinkMsg; import org.thingsboard.server.gen.edge.EntityDataProto; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.TbQueueCallback; @@ -58,6 +64,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import javax.annotation.Nullable; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -70,7 +77,7 @@ public class TelemetryProcessor extends BaseProcessor { private final Gson gson = new Gson(); - public List> onTelemetryUpdate(TenantId tenantId, CustomerId customerId, EntityDataProto entityData) { + public List> processTelemetryFromEdge(TenantId tenantId, CustomerId customerId, EntityDataProto entityData) { log.trace("[{}] onTelemetryUpdate [{}]", tenantId, entityData); List> result = new ArrayList<>(); EntityId entityId = constructEntityId(entityData); @@ -279,4 +286,44 @@ public class TelemetryProcessor extends BaseProcessor { return null; } } + + public DownlinkMsg processTelemetryMessageToEdge(EdgeEvent edgeEvent) throws JsonProcessingException { + EntityId entityId = null; + switch (edgeEvent.getType()) { + case DEVICE: + entityId = new DeviceId(edgeEvent.getEntityId()); + break; + case ASSET: + entityId = new AssetId(edgeEvent.getEntityId()); + break; + case ENTITY_VIEW: + entityId = new EntityViewId(edgeEvent.getEntityId()); + break; + case DASHBOARD: + entityId = new DashboardId(edgeEvent.getEntityId()); + break; + case TENANT: + entityId = new TenantId(edgeEvent.getEntityId()); + break; + case CUSTOMER: + entityId = new CustomerId(edgeEvent.getEntityId()); + break; + case EDGE: + entityId = new EdgeId(edgeEvent.getEntityId()); + break; + } + DownlinkMsg downlinkMsg = null; + if (entityId != null) { + downlinkMsg = constructEntityDataProtoMsg(entityId, edgeEvent.getAction(), JsonUtils.parse(mapper.writeValueAsString(edgeEvent.getBody()))); + } + return downlinkMsg; + } + + private DownlinkMsg constructEntityDataProtoMsg(EntityId entityId, EdgeEventActionType actionType, JsonElement entityData) { + EntityDataProto entityDataProto = entityDataMsgConstructor.constructEntityDataMsg(entityId, actionType, entityData); + return DownlinkMsg.newBuilder() + .addAllEntityData(Collections.singletonList(entityDataProto)) + .build(); + } + } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserProcessor.java new file mode 100644 index 0000000000..74afa02b15 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserProcessor.java @@ -0,0 +1,71 @@ +/** + * Copyright © 2016-2021 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.processor; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.security.UserCredentials; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.Collections; + +@Component +@Slf4j +@TbCoreComponent +public class UserProcessor extends BaseProcessor { + + public DownlinkMsg processUserToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { + UserId userId = new UserId(edgeEvent.getEntityId()); + DownlinkMsg downlinkMsg = null; + switch (edgeEdgeEventActionType) { + case ADDED: + case UPDATED: + User user = userService.findUserById(edgeEvent.getTenantId(), userId); + if (user != null) { + CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(user, edge); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllUserUpdateMsg(Collections.singletonList(userMsgConstructor.constructUserUpdatedMsg(msgType, user, customerId))) + .build(); + } + break; + case DELETED: + downlinkMsg = DownlinkMsg.newBuilder() + .addAllUserUpdateMsg(Collections.singletonList(userMsgConstructor.constructUserDeleteMsg(userId))) + .build(); + break; + case CREDENTIALS_UPDATED: + UserCredentials userCredentialsByUserId = userService.findUserCredentialsByUserId(edge.getTenantId(), userId); + if (userCredentialsByUserId != null && userCredentialsByUserId.isEnabled()) { + UserCredentialsUpdateMsg userCredentialsUpdateMsg = + userMsgConstructor.constructUserCredentialsUpdatedMsg(userCredentialsByUserId); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllUserCredentialsUpdateMsg(Collections.singletonList(userCredentialsUpdateMsg)) + .build(); + } + } + return downlinkMsg; + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleProcessor.java new file mode 100644 index 0000000000..370cf3419f --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleProcessor.java @@ -0,0 +1,62 @@ +/** + * Copyright © 2016-2021 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.processor; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.id.WidgetsBundleId; +import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.Collections; + +@Component +@Slf4j +@TbCoreComponent +public class WidgetBundleProcessor extends BaseProcessor { + + public DownlinkMsg processWidgetsBundleToEdge(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { + WidgetsBundleId widgetsBundleId = new WidgetsBundleId(edgeEvent.getEntityId()); + DownlinkMsg downlinkMsg = null; + switch (edgeEdgeEventActionType) { + case ADDED: + case UPDATED: + WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleById(edgeEvent.getTenantId(), widgetsBundleId); + if (widgetsBundle != null) { + WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = + widgetsBundleMsgConstructor.constructWidgetsBundleUpdateMsg(msgType, widgetsBundle); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllWidgetsBundleUpdateMsg(Collections.singletonList(widgetsBundleUpdateMsg)) + .build(); + } + break; + case DELETED: + WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = + widgetsBundleMsgConstructor.constructWidgetsBundleDeleteMsg(widgetsBundleId); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllWidgetsBundleUpdateMsg(Collections.singletonList(widgetsBundleUpdateMsg)) + .build(); + break; + } + return downlinkMsg; + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeProcessor.java new file mode 100644 index 0000000000..795207567e --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeProcessor.java @@ -0,0 +1,62 @@ +/** + * Copyright © 2016-2021 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.processor; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.id.WidgetTypeId; +import org.thingsboard.server.common.data.widget.WidgetType; +import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.WidgetTypeUpdateMsg; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.Collections; + +@Component +@Slf4j +@TbCoreComponent +public class WidgetTypeProcessor extends BaseProcessor { + + public DownlinkMsg processWidgetTypeToEdge(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { + WidgetTypeId widgetTypeId = new WidgetTypeId(edgeEvent.getEntityId()); + DownlinkMsg downlinkMsg = null; + switch (edgeEdgeEventActionType) { + case ADDED: + case UPDATED: + WidgetType widgetType = widgetTypeService.findWidgetTypeById(edgeEvent.getTenantId(), widgetTypeId); + if (widgetType != null) { + WidgetTypeUpdateMsg widgetTypeUpdateMsg = + widgetTypeMsgConstructor.constructWidgetTypeUpdateMsg(msgType, widgetType); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllWidgetTypeUpdateMsg(Collections.singletonList(widgetTypeUpdateMsg)) + .build(); + } + break; + case DELETED: + WidgetTypeUpdateMsg widgetTypeUpdateMsg = + widgetTypeMsgConstructor.constructWidgetTypeDeleteMsg(widgetTypeId); + downlinkMsg = DownlinkMsg.newBuilder() + .addAllWidgetTypeUpdateMsg(Collections.singletonList(widgetTypeUpdateMsg)) + .build(); + break; + } + return downlinkMsg; + } + +} From ddfa1c156cfd729699344a9215c864457e5a25de Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 19 May 2021 16:45:36 +0300 Subject: [PATCH 12/52] added connected flag to imitator to avoid error in the test logs --- .../server/edge/imitator/EdgeImitator.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index 1496b0d061..c903913fe3 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -79,6 +79,8 @@ public class EdgeImitator { @Getter private List downlinkMsgs; + private boolean connected = false; + public EdgeImitator(String host, int port, String routingKey, String routingSecret) throws NoSuchFieldException, IllegalAccessException { edgeRpcClient = new EdgeGrpcClient(); messagesLatch = new CountDownLatch(0); @@ -100,6 +102,7 @@ public class EdgeImitator { } public void connect() { + connected = true; edgeRpcClient.connect(routingKey, routingSecret, this::onUplinkResponse, this::onEdgeUpdate, @@ -110,6 +113,7 @@ public class EdgeImitator { } public void disconnect() throws InterruptedException { + connected = false; edgeRpcClient.disconnect(false); } @@ -131,14 +135,18 @@ public class EdgeImitator { Futures.addCallback(future, new FutureCallback<>() { @Override public void onSuccess(@Nullable List result) { - DownlinkResponseMsg downlinkResponseMsg = DownlinkResponseMsg.newBuilder().setSuccess(true).build(); - edgeRpcClient.sendDownlinkResponseMsg(downlinkResponseMsg); + if (connected) { + DownlinkResponseMsg downlinkResponseMsg = DownlinkResponseMsg.newBuilder().setSuccess(true).build(); + edgeRpcClient.sendDownlinkResponseMsg(downlinkResponseMsg); + } } @Override public void onFailure(Throwable t) { - DownlinkResponseMsg downlinkResponseMsg = DownlinkResponseMsg.newBuilder().setSuccess(false).setErrorMsg(t.getMessage()).build(); - edgeRpcClient.sendDownlinkResponseMsg(downlinkResponseMsg); + if (connected) { + DownlinkResponseMsg downlinkResponseMsg = DownlinkResponseMsg.newBuilder().setSuccess(false).setErrorMsg(t.getMessage()).build(); + edgeRpcClient.sendDownlinkResponseMsg(downlinkResponseMsg); + } } }, MoreExecutors.directExecutor()); } From ed9d84a2022ec00a06596c7e475abb24aab3a6de Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 19 May 2021 17:08:49 +0300 Subject: [PATCH 13/52] Processors renaming --- .../service/edge/EdgeContextComponent.java | 85 +++++++------------ ...r.java => AdminSettingsEdgeProcessor.java} | 2 +- ...Processor.java => AlarmEdgeProcessor.java} | 2 +- ...Processor.java => AssetEdgeProcessor.java} | 2 +- ...eProcessor.java => BaseEdgeProcessor.java} | 2 +- ...cessor.java => CustomerEdgeProcessor.java} | 2 +- ...essor.java => DashboardEdgeProcessor.java} | 2 +- ...rocessor.java => DeviceEdgeProcessor.java} | 2 +- ...r.java => DeviceProfileEdgeProcessor.java} | 2 +- ...rocessor.java => EntityEdgeProcessor.java} | 2 +- ...ssor.java => EntityViewEdgeProcessor.java} | 2 +- ...cessor.java => RelationEdgeProcessor.java} | 2 +- ...essor.java => RuleChainEdgeProcessor.java} | 2 +- ...essor.java => TelemetryEdgeProcessor.java} | 2 +- ...rProcessor.java => UserEdgeProcessor.java} | 2 +- ...or.java => WidgetBundleEdgeProcessor.java} | 3 +- ...ssor.java => WidgetTypeEdgeProcessor.java} | 2 +- 17 files changed, 46 insertions(+), 72 deletions(-) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{AdminSettingsProcessor.java => AdminSettingsEdgeProcessor.java} (95%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{AlarmProcessor.java => AlarmEdgeProcessor.java} (99%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{AssetProcessor.java => AssetEdgeProcessor.java} (97%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{BaseProcessor.java => BaseEdgeProcessor.java} (99%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{CustomerProcessor.java => CustomerEdgeProcessor.java} (97%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{DashboardProcessor.java => DashboardEdgeProcessor.java} (97%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{DeviceProcessor.java => DeviceEdgeProcessor.java} (99%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{DeviceProfileProcessor.java => DeviceProfileEdgeProcessor.java} (97%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{EntityProcessor.java => EntityEdgeProcessor.java} (98%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{EntityViewProcessor.java => EntityViewEdgeProcessor.java} (97%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{RelationProcessor.java => RelationEdgeProcessor.java} (98%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{RuleChainProcessor.java => RuleChainEdgeProcessor.java} (98%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{TelemetryProcessor.java => TelemetryEdgeProcessor.java} (99%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{UserProcessor.java => UserEdgeProcessor.java} (98%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{WidgetBundleProcessor.java => WidgetBundleEdgeProcessor.java} (96%) rename application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/{WidgetTypeProcessor.java => WidgetTypeEdgeProcessor.java} (97%) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java b/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java index c1fbcbc69b..bdc5c26889 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java @@ -20,59 +20,34 @@ import lombok.Getter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; -import org.thingsboard.server.actors.service.ActorService; -import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.attributes.AttributesService; -import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.dashboard.DashboardService; -import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceProfileService; -import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.edge.EdgeService; -import org.thingsboard.server.dao.entityview.EntityViewService; -import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.user.UserService; -import org.thingsboard.server.dao.widget.WidgetTypeService; import org.thingsboard.server.dao.widget.WidgetsBundleService; -import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.edge.rpc.EdgeEventStorageSettings; -import org.thingsboard.server.service.edge.rpc.constructor.AdminSettingsMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.AlarmMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.AssetMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.CustomerMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.DashboardMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.DeviceMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.DeviceProfileMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.EntityDataMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.EntityViewMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.RelationMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.RuleChainMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.UserMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.WidgetTypeMsgConstructor; -import org.thingsboard.server.service.edge.rpc.constructor.WidgetsBundleMsgConstructor; -import org.thingsboard.server.service.edge.rpc.processor.AdminSettingsProcessor; -import org.thingsboard.server.service.edge.rpc.processor.AssetProcessor; -import org.thingsboard.server.service.edge.rpc.processor.CustomerProcessor; -import org.thingsboard.server.service.edge.rpc.processor.DashboardProcessor; -import org.thingsboard.server.service.edge.rpc.processor.DeviceProfileProcessor; -import org.thingsboard.server.service.edge.rpc.processor.EntityProcessor; -import org.thingsboard.server.service.edge.rpc.processor.EntityViewProcessor; -import org.thingsboard.server.service.edge.rpc.processor.RuleChainProcessor; -import org.thingsboard.server.service.edge.rpc.processor.UserProcessor; -import org.thingsboard.server.service.edge.rpc.processor.WidgetBundleProcessor; -import org.thingsboard.server.service.edge.rpc.processor.WidgetTypeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.AdminSettingsEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.AlarmEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.AssetEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.CustomerEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.DashboardEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.DeviceEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.DeviceProfileEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.EntityEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.EntityViewEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.RelationEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.RuleChainEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.TelemetryEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.UserEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.WidgetBundleEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.WidgetTypeEdgeProcessor; import org.thingsboard.server.service.edge.rpc.sync.EdgeRequestsService; -import org.thingsboard.server.service.edge.rpc.processor.AlarmProcessor; -import org.thingsboard.server.service.edge.rpc.processor.DeviceProcessor; -import org.thingsboard.server.service.edge.rpc.processor.RelationProcessor; -import org.thingsboard.server.service.edge.rpc.processor.TelemetryProcessor; import org.thingsboard.server.service.executors.DbCallbackExecutorService; -import org.thingsboard.server.service.queue.TbClusterService; -import org.thingsboard.server.service.state.DeviceStateService; @Component @TbCoreComponent @@ -121,63 +96,63 @@ public class EdgeContextComponent { @Lazy @Autowired - private AlarmProcessor alarmProcessor; + private AlarmEdgeProcessor alarmProcessor; @Lazy @Autowired - private DeviceProfileProcessor deviceProfileProcessor; + private DeviceProfileEdgeProcessor deviceProfileProcessor; @Lazy @Autowired - private DeviceProcessor deviceProcessor; + private DeviceEdgeProcessor deviceProcessor; @Lazy @Autowired - private EntityProcessor entityProcessor; + private EntityEdgeProcessor entityProcessor; @Lazy @Autowired - private AssetProcessor assetProcessor; + private AssetEdgeProcessor assetProcessor; @Lazy @Autowired - private EntityViewProcessor entityViewProcessor; + private EntityViewEdgeProcessor entityViewProcessor; @Lazy @Autowired - private UserProcessor userProcessor; + private UserEdgeProcessor userProcessor; @Lazy @Autowired - private RelationProcessor relationProcessor; + private RelationEdgeProcessor relationProcessor; @Lazy @Autowired - private TelemetryProcessor telemetryProcessor; + private TelemetryEdgeProcessor telemetryProcessor; @Lazy @Autowired - private DashboardProcessor dashboardProcessor; + private DashboardEdgeProcessor dashboardProcessor; @Lazy @Autowired - private RuleChainProcessor ruleChainProcessor; + private RuleChainEdgeProcessor ruleChainProcessor; @Lazy @Autowired - private CustomerProcessor customerProcessor; + private CustomerEdgeProcessor customerProcessor; @Lazy @Autowired - private WidgetBundleProcessor widgetBundleProcessor; + private WidgetBundleEdgeProcessor widgetBundleProcessor; @Lazy @Autowired - private WidgetTypeProcessor widgetTypeProcessor; + private WidgetTypeEdgeProcessor widgetTypeProcessor; @Lazy @Autowired - private AdminSettingsProcessor adminSettingsProcessor; + private AdminSettingsEdgeProcessor adminSettingsProcessor; @Lazy @Autowired diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java similarity index 95% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java index 53f46900fa..e39b3eda4c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java @@ -28,7 +28,7 @@ import java.util.Collections; @Component @Slf4j @TbCoreComponent -public class AdminSettingsProcessor extends BaseProcessor { +public class AdminSettingsEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processAdminSettingsToEdge(EdgeEvent edgeEvent) { AdminSettings adminSettings = mapper.convertValue(edgeEvent.getBody(), AdminSettings.class); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java similarity index 99% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java index 5ceb82381a..f936540290 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java @@ -38,7 +38,7 @@ import java.util.Collections; @Component @Slf4j @TbCoreComponent -public class AlarmProcessor extends BaseProcessor { +public class AlarmEdgeProcessor extends BaseEdgeProcessor { public ListenableFuture processAlarmFromEdge(TenantId tenantId, AlarmUpdateMsg alarmUpdateMsg) { log.trace("[{}] onAlarmUpdate [{}]", tenantId, alarmUpdateMsg); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java similarity index 97% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java index e3c8d9d1e8..cf0180c85f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java @@ -33,7 +33,7 @@ import java.util.Collections; @Component @Slf4j @TbCoreComponent -public class AssetProcessor extends BaseProcessor { +public class AssetEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processAssetToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { AssetId assetId = new AssetId(edgeEvent.getEntityId()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java similarity index 99% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java index 8ea8eac1df..6846cb8904 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java @@ -68,7 +68,7 @@ import org.thingsboard.server.service.queue.TbClusterService; import org.thingsboard.server.service.state.DeviceStateService; @Slf4j -public abstract class BaseProcessor { +public abstract class BaseEdgeProcessor { protected static final ObjectMapper mapper = new ObjectMapper(); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java similarity index 97% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java index 476458bd05..573152e103 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java @@ -31,7 +31,7 @@ import java.util.Collections; @Component @Slf4j @TbCoreComponent -public class CustomerProcessor extends BaseProcessor { +public class CustomerEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processCustomerToEdge(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { CustomerId customerId = new CustomerId(edgeEvent.getEntityId()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java similarity index 97% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java index f6df66cf0e..730e928a2d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java @@ -33,7 +33,7 @@ import java.util.Collections; @Component @Slf4j @TbCoreComponent -public class DashboardProcessor extends BaseProcessor { +public class DashboardEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processDashboardToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { DashboardId dashboardId = new DashboardId(edgeEvent.getEntityId()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java similarity index 99% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java index 2325b6736d..b3ec44195e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java @@ -68,7 +68,7 @@ import java.util.concurrent.locks.ReentrantLock; @Component @Slf4j @TbCoreComponent -public class DeviceProcessor extends BaseProcessor { +public class DeviceEdgeProcessor extends BaseEdgeProcessor { private static final ReentrantLock deviceCreationLock = new ReentrantLock(); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java similarity index 97% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java index 6aab6838fd..d66dc2b67c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java @@ -31,7 +31,7 @@ import java.util.Collections; @Component @Slf4j @TbCoreComponent -public class DeviceProfileProcessor extends BaseProcessor { +public class DeviceProfileEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processDeviceProfileToEdge(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { DeviceProfileId deviceProfileId = new DeviceProfileId(edgeEvent.getEntityId()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java similarity index 98% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java index c5865b0ff9..f930e316be 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java @@ -34,7 +34,7 @@ import java.util.Collections; @Component @Slf4j @TbCoreComponent -public class EntityProcessor extends BaseProcessor { +public class EntityEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processEntityMergeRequestMessageToEdge(Edge edge, EdgeEvent edgeEvent) { DownlinkMsg downlinkMsg = null; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java similarity index 97% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java index e62e084471..ab0e2e868f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java @@ -33,7 +33,7 @@ import java.util.Collections; @Component @Slf4j @TbCoreComponent -public class EntityViewProcessor extends BaseProcessor { +public class EntityViewEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processEntityViewToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { EntityViewId entityViewId = new EntityViewId(edgeEvent.getEntityId()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java similarity index 98% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java index eb96df6729..8e3a429d18 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java @@ -45,7 +45,7 @@ import java.util.UUID; @Component @Slf4j @TbCoreComponent -public class RelationProcessor extends BaseProcessor { +public class RelationEdgeProcessor extends BaseEdgeProcessor { public ListenableFuture processRelationFromEdge(TenantId tenantId, RelationUpdateMsg relationUpdateMsg) { log.trace("[{}] onRelationUpdate [{}]", tenantId, relationUpdateMsg); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java similarity index 98% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java index c30e9bf45f..90fc8abe0e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java @@ -34,7 +34,7 @@ import java.util.Collections; @Component @Slf4j @TbCoreComponent -public class RuleChainProcessor extends BaseProcessor { +public class RuleChainEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processRuleChainToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java similarity index 99% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java index b42ceb40ab..c475542892 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java @@ -73,7 +73,7 @@ import java.util.UUID; @Component @Slf4j @TbCoreComponent -public class TelemetryProcessor extends BaseProcessor { +public class TelemetryEdgeProcessor extends BaseEdgeProcessor { private final Gson gson = new Gson(); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java similarity index 98% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java index 74afa02b15..747d2ab4fd 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java @@ -34,7 +34,7 @@ import java.util.Collections; @Component @Slf4j @TbCoreComponent -public class UserProcessor extends BaseProcessor { +public class UserEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processUserToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { UserId userId = new UserId(edgeEvent.getEntityId()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java similarity index 96% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java index 370cf3419f..8c0d28226d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java @@ -17,7 +17,6 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.WidgetsBundleId; @@ -32,7 +31,7 @@ import java.util.Collections; @Component @Slf4j @TbCoreComponent -public class WidgetBundleProcessor extends BaseProcessor { +public class WidgetBundleEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processWidgetsBundleToEdge(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { WidgetsBundleId widgetsBundleId = new WidgetsBundleId(edgeEvent.getEntityId()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java similarity index 97% rename from application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeProcessor.java rename to application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java index 795207567e..891b224a6e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java @@ -31,7 +31,7 @@ import java.util.Collections; @Component @Slf4j @TbCoreComponent -public class WidgetTypeProcessor extends BaseProcessor { +public class WidgetTypeEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processWidgetTypeToEdge(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { WidgetTypeId widgetTypeId = new WidgetTypeId(edgeEvent.getEntityId()); From ce5c3441fa9c684793c908d7cce590aa17519485 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 19 May 2021 17:23:54 +0300 Subject: [PATCH 14/52] Refactoring - push notification code to processors --- .../edge/DefaultEdgeNotificationService.java | 364 ++---------------- .../rpc/processor/AlarmEdgeProcessor.java | 51 +++ .../edge/rpc/processor/BaseEdgeProcessor.java | 2 + .../rpc/processor/CustomerEdgeProcessor.java | 38 ++ .../edge/rpc/processor/EdgeProcessor.java | 102 +++++ .../rpc/processor/EntityEdgeProcessor.java | 154 ++++++++ .../rpc/processor/RelationEdgeProcessor.java | 50 +++ .../processor/WidgetBundleEdgeProcessor.java | 9 + 8 files changed, 428 insertions(+), 342 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EdgeProcessor.java diff --git a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java index 5d85ddf16f..aae6ac17ab 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java @@ -15,9 +15,7 @@ */ package org.thingsboard.server.service.edge; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -25,45 +23,30 @@ import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.EdgeUtils; -import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.User; -import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; -import org.thingsboard.server.common.data.id.AlarmId; -import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.page.PageData; -import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.common.data.page.TimePageLink; -import org.thingsboard.server.common.data.relation.EntityRelation; -import org.thingsboard.server.common.data.rule.RuleChain; -import org.thingsboard.server.common.data.rule.RuleChainConnectionInfo; import org.thingsboard.server.common.msg.queue.TbCallback; -import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.edge.EdgeService; -import org.thingsboard.server.dao.rule.RuleChainService; -import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.edge.rpc.processor.AlarmEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.CustomerEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.EdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.EntityEdgeProcessor; +import org.thingsboard.server.service.edge.rpc.processor.RelationEdgeProcessor; import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.queue.TbClusterService; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -73,30 +56,32 @@ import java.util.concurrent.Executors; @Slf4j public class DefaultEdgeNotificationService implements EdgeNotificationService { - private static final ObjectMapper mapper = new ObjectMapper(); + @Autowired + private EdgeService edgeService; - private static final int DEFAULT_LIMIT = 100; + @Autowired + private EdgeEventService edgeEventService; @Autowired - private EdgeService edgeService; + private TbClusterService clusterService; @Autowired - private AlarmService alarmService; + private DbCallbackExecutorService dbCallbackExecutorService; @Autowired - private UserService userService; + private EdgeProcessor edgeProcessor; @Autowired - private RuleChainService ruleChainService; + private EntityEdgeProcessor entityProcessor; @Autowired - private EdgeEventService edgeEventService; + private AlarmEdgeProcessor alarmProcessor; @Autowired - private TbClusterService clusterService; + private RelationEdgeProcessor relationProcessor; @Autowired - private DbCallbackExecutorService dbCallbackExecutorService; + private CustomerEdgeProcessor customerProcessor; private ExecutorService tsCallBackExecutor; @@ -160,7 +145,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); switch (type) { case EDGE: - processEdge(tenantId, edgeNotificationMsg); + edgeProcessor.processEdgeNotification(tenantId, edgeNotificationMsg); break; case USER: case ASSET: @@ -169,20 +154,20 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { case ENTITY_VIEW: case DASHBOARD: case RULE_CHAIN: - processEntity(tenantId, edgeNotificationMsg); + entityProcessor.processEntityNotification(tenantId, edgeNotificationMsg); break; case CUSTOMER: - processCustomer(tenantId, edgeNotificationMsg); + customerProcessor.processCustomerNotification(tenantId, edgeNotificationMsg); break; case WIDGETS_BUNDLE: case WIDGET_TYPE: - processWidgetBundleOrWidgetType(tenantId, edgeNotificationMsg); + entityProcessor.processEntityNotificationForAllEdges(tenantId, edgeNotificationMsg); break; case ALARM: - processAlarm(tenantId, edgeNotificationMsg); + alarmProcessor.processAlarmNotification(tenantId, edgeNotificationMsg); break; case RELATION: - processRelation(tenantId, edgeNotificationMsg); + relationProcessor.processRelationNotification(tenantId, edgeNotificationMsg); break; default: log.debug("Edge event type [{}] is not designed to be pushed to edge", type); @@ -195,311 +180,6 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { } } - private void processEdge(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { - try { - EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); - EdgeId edgeId = new EdgeId(new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); - ListenableFuture edgeFuture; - switch (actionType) { - case ASSIGNED_TO_CUSTOMER: - CustomerId customerId = mapper.readValue(edgeNotificationMsg.getBody(), CustomerId.class); - edgeFuture = edgeService.findEdgeByIdAsync(tenantId, edgeId); - Futures.addCallback(edgeFuture, new FutureCallback() { - @Override - public void onSuccess(@Nullable Edge edge) { - if (edge != null && !customerId.isNullUid()) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, customerId, null); - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = userService.findCustomerUsers(tenantId, customerId, pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - log.trace("[{}] [{}] user(s) are going to be added to edge.", edge.getId(), pageData.getData().size()); - for (User user : pageData.getData()) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, EdgeEventActionType.ADDED, user.getId(), null); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - } - } - - @Override - public void onFailure(Throwable t) { - log.error("Can't find edge by id [{}]", edgeNotificationMsg, t); - } - }, dbCallbackExecutorService); - break; - case UNASSIGNED_FROM_CUSTOMER: - CustomerId customerIdToDelete = mapper.readValue(edgeNotificationMsg.getBody(), CustomerId.class); - edgeFuture = edgeService.findEdgeByIdAsync(tenantId, edgeId); - Futures.addCallback(edgeFuture, new FutureCallback() { - @Override - public void onSuccess(@Nullable Edge edge) { - if (edge != null && !customerIdToDelete.isNullUid()) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.DELETED, customerIdToDelete, null); - } - } - - @Override - public void onFailure(Throwable t) { - log.error("Can't find edge by id [{}]", edgeNotificationMsg, t); - } - }, dbCallbackExecutorService); - break; - } - } catch (Exception e) { - log.error("Exception during processing edge event", e); - } - } - - private void processWidgetBundleOrWidgetType(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { - EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); - EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); - EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(type, new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); - switch (actionType) { - case ADDED: - case UPDATED: - case DELETED: - processActionForAllEdges(tenantId, type, actionType, entityId); - break; - } - } - - private void processCustomer(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { - EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); - EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); - UUID uuid = new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB()); - CustomerId customerId = new CustomerId(EntityIdFactory.getByEdgeEventTypeAndUuid(type, uuid).getId()); - switch (actionType) { - case UPDATED: - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = edgeService.findEdgesByTenantIdAndCustomerId(tenantId, customerId, pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - for (Edge edge : pageData.getData()) { - saveEdgeEvent(tenantId, edge.getId(), type, actionType, customerId, null); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - break; - case DELETED: - EdgeId edgeId = new EdgeId(new UUID(edgeNotificationMsg.getEdgeIdMSB(), edgeNotificationMsg.getEdgeIdLSB())); - saveEdgeEvent(tenantId, edgeId, type, actionType, customerId, null); - break; - } - } - - private void processEntity(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { - EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); - EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); - EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(type, - new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); - EdgeId edgeId = new EdgeId(new UUID(edgeNotificationMsg.getEdgeIdMSB(), edgeNotificationMsg.getEdgeIdLSB())); - ListenableFuture> edgeIdsFuture; - switch (actionType) { - case ADDED: // used only for USER entity - case UPDATED: - case CREDENTIALS_UPDATED: - edgeIdsFuture = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId); - Futures.addCallback(edgeIdsFuture, new FutureCallback>() { - @Override - public void onSuccess(@Nullable List edgeIds) { - if (edgeIds != null && !edgeIds.isEmpty()) { - for (EdgeId edgeId : edgeIds) { - saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null); - } - } - } - @Override - public void onFailure(Throwable throwable) { - log.error("Failed to find related edge ids [{}]", edgeNotificationMsg, throwable); - } - }, dbCallbackExecutorService); - break; - case ASSIGNED_TO_CUSTOMER: - case UNASSIGNED_FROM_CUSTOMER: - edgeIdsFuture = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId); - Futures.addCallback(edgeIdsFuture, new FutureCallback<>() { - @Override - public void onSuccess(@Nullable List edgeIds) { - if (edgeIds != null && !edgeIds.isEmpty()) { - for (EdgeId edgeId : edgeIds) { - try { - CustomerId customerId = mapper.readValue(edgeNotificationMsg.getBody(), CustomerId.class); - ListenableFuture future = edgeService.findEdgeByIdAsync(tenantId, edgeId); - Futures.addCallback(future, new FutureCallback() { - @Override - public void onSuccess(@Nullable Edge edge) { - if (edge != null && edge.getCustomerId() != null && - !edge.getCustomerId().isNullUid() && edge.getCustomerId().equals(customerId)) { - saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null); - } - } - @Override - public void onFailure(Throwable throwable) { - log.error("Failed to find edge by id [{}]", edgeNotificationMsg, throwable); - } - }, dbCallbackExecutorService); - } catch (Exception e) { - log.error("Can't parse customer id from entity body [{}]", edgeNotificationMsg, e); - } - } - } - } - - @Override - public void onFailure(Throwable throwable) { - log.error("Failed to find related edge ids [{}]", edgeNotificationMsg, throwable); - } - }, dbCallbackExecutorService); - break; - case DELETED: - saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null); - break; - case ASSIGNED_TO_EDGE: - case UNASSIGNED_FROM_EDGE: - saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null); - if (type.equals(EdgeEventType.RULE_CHAIN)) { - updateDependentRuleChains(tenantId, new RuleChainId(entityId.getId()), edgeId); - } - break; - } - } - - private void updateDependentRuleChains(TenantId tenantId, RuleChainId processingRuleChainId, EdgeId edgeId) { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edgeId, pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - for (RuleChain ruleChain : pageData.getData()) { - if (!ruleChain.getId().equals(processingRuleChainId)) { - List connectionInfos = - ruleChainService.loadRuleChainMetaData(ruleChain.getTenantId(), ruleChain.getId()).getRuleChainConnections(); - if (connectionInfos != null && !connectionInfos.isEmpty()) { - for (RuleChainConnectionInfo connectionInfo : connectionInfos) { - if (connectionInfo.getTargetRuleChainId().equals(processingRuleChainId)) { - saveEdgeEvent(tenantId, - edgeId, - EdgeEventType.RULE_CHAIN_METADATA, - EdgeEventActionType.UPDATED, - ruleChain.getId(), - null); - } - } - } - } - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - } - - private void processAlarm(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { - AlarmId alarmId = new AlarmId(new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); - ListenableFuture alarmFuture = alarmService.findAlarmByIdAsync(tenantId, alarmId); - Futures.addCallback(alarmFuture, new FutureCallback() { - @Override - public void onSuccess(@Nullable Alarm alarm) { - if (alarm != null) { - EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(alarm.getOriginator().getEntityType()); - if (type != null) { - ListenableFuture> relatedEdgeIdsByEntityIdFuture = edgeService.findRelatedEdgeIdsByEntityId(tenantId, alarm.getOriginator()); - Futures.addCallback(relatedEdgeIdsByEntityIdFuture, new FutureCallback>() { - @Override - public void onSuccess(@Nullable List relatedEdgeIdsByEntityId) { - if (relatedEdgeIdsByEntityId != null) { - for (EdgeId edgeId : relatedEdgeIdsByEntityId) { - saveEdgeEvent(tenantId, - edgeId, - EdgeEventType.ALARM, - EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()), - alarmId, - null); - } - } - } - - @Override - public void onFailure(Throwable t) { - log.warn("[{}] can't find related edge ids by entity id [{}]", tenantId.getId(), alarm.getOriginator(), t); - } - }, dbCallbackExecutorService); - } - } - } - - @Override - public void onFailure(Throwable t) { - log.warn("[{}] can't find alarm by id [{}]", tenantId.getId(), alarmId.getId(), t); - } - }, dbCallbackExecutorService); - } - - private void processRelation(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) throws JsonProcessingException { - EntityRelation relation = mapper.readValue(edgeNotificationMsg.getBody(), EntityRelation.class); - if (!relation.getFrom().getEntityType().equals(EntityType.EDGE) && - !relation.getTo().getEntityType().equals(EntityType.EDGE)) { - List>> futures = new ArrayList<>(); - futures.add(edgeService.findRelatedEdgeIdsByEntityId(tenantId, relation.getTo())); - futures.add(edgeService.findRelatedEdgeIdsByEntityId(tenantId, relation.getFrom())); - ListenableFuture>> combinedFuture = Futures.allAsList(futures); - Futures.addCallback(combinedFuture, new FutureCallback>>() { - @Override - public void onSuccess(@Nullable List> listOfListsEdgeIds) { - Set uniqueEdgeIds = new HashSet<>(); - if (listOfListsEdgeIds != null && !listOfListsEdgeIds.isEmpty()) { - for (List listOfListsEdgeId : listOfListsEdgeIds) { - if (listOfListsEdgeId != null) { - uniqueEdgeIds.addAll(listOfListsEdgeId); - } - } - } - if (!uniqueEdgeIds.isEmpty()) { - for (EdgeId edgeId : uniqueEdgeIds) { - saveEdgeEvent(tenantId, - edgeId, - EdgeEventType.RELATION, - EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()), - null, - mapper.valueToTree(relation)); - } - } - } - - @Override - public void onFailure(Throwable t) { - log.warn("[{}] can't find related edge ids by relation to id [{}] and relation from id [{}]" , - tenantId.getId(), relation.getTo().getId(), relation.getFrom().getId(), t); - } - }, dbCallbackExecutorService); - } - } - - private void processActionForAllEdges(TenantId tenantId, EdgeEventType type, EdgeEventActionType actionType, EntityId entityId) { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = edgeService.findEdgesByTenantId(tenantId, pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - for (Edge edge : pageData.getData()) { - saveEdgeEvent(tenantId, edge.getId(), type, actionType, entityId, null); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java index f936540290..3ff245b0d9 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java @@ -15,25 +15,34 @@ */ package org.thingsboard.server.service.edge.rpc.processor; +import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.AlarmId; +import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.gen.edge.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.DownlinkMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; +import java.util.List; +import java.util.UUID; @Component @Slf4j @@ -119,4 +128,46 @@ public class AlarmEdgeProcessor extends BaseEdgeProcessor { } return downlinkMsg; } + + public void processAlarmNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { + AlarmId alarmId = new AlarmId(new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); + ListenableFuture alarmFuture = alarmService.findAlarmByIdAsync(tenantId, alarmId); + Futures.addCallback(alarmFuture, new FutureCallback() { + @Override + public void onSuccess(@Nullable Alarm alarm) { + if (alarm != null) { + EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(alarm.getOriginator().getEntityType()); + if (type != null) { + ListenableFuture> relatedEdgeIdsByEntityIdFuture = edgeService.findRelatedEdgeIdsByEntityId(tenantId, alarm.getOriginator()); + Futures.addCallback(relatedEdgeIdsByEntityIdFuture, new FutureCallback>() { + @Override + public void onSuccess(@Nullable List relatedEdgeIdsByEntityId) { + if (relatedEdgeIdsByEntityId != null) { + for (EdgeId edgeId : relatedEdgeIdsByEntityId) { + saveEdgeEvent(tenantId, + edgeId, + EdgeEventType.ALARM, + EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()), + alarmId, + null); + } + } + } + + @Override + public void onFailure(Throwable t) { + log.warn("[{}] can't find related edge ids by entity id [{}]", tenantId.getId(), alarm.getOriginator(), t); + } + }, dbCallbackExecutorService); + } + } + } + + @Override + public void onFailure(Throwable t) { + log.warn("[{}] can't find alarm by id [{}]", tenantId.getId(), alarmId.getId(), t); + } + }, dbCallbackExecutorService); + } + } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java index 6846cb8904..717e70d7aa 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java @@ -72,6 +72,8 @@ public abstract class BaseEdgeProcessor { protected static final ObjectMapper mapper = new ObjectMapper(); + protected static final int DEFAULT_LIMIT = 100; + @Autowired protected RuleChainService ruleChainService; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java index 573152e103..63b2c5d577 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java @@ -18,15 +18,24 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityIdFactory; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.gen.edge.CustomerUpdateMsg; import org.thingsboard.server.gen.edge.DownlinkMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; +import java.util.UUID; @Component @Slf4j @@ -58,4 +67,33 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor { } return downlinkMsg; } + + public void processCustomerNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { + EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); + EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); + UUID uuid = new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB()); + CustomerId customerId = new CustomerId(EntityIdFactory.getByEdgeEventTypeAndUuid(type, uuid).getId()); + switch (actionType) { + case UPDATED: + PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageData pageData; + do { + pageData = edgeService.findEdgesByTenantIdAndCustomerId(tenantId, customerId, pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + for (Edge edge : pageData.getData()) { + saveEdgeEvent(tenantId, edge.getId(), type, actionType, customerId, null); + } + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } + } while (pageData != null && pageData.hasNext()); + break; + case DELETED: + EdgeId edgeId = new EdgeId(new UUID(edgeNotificationMsg.getEdgeIdMSB(), edgeNotificationMsg.getEdgeIdLSB())); + saveEdgeEvent(tenantId, edgeId, type, actionType, customerId, null); + break; + } + } + } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EdgeProcessor.java new file mode 100644 index 0000000000..c9cd0f4019 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EdgeProcessor.java @@ -0,0 +1,102 @@ +/** + * Copyright © 2016-2021 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.processor; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.UUID; + +@Component +@Slf4j +@TbCoreComponent +public class EdgeProcessor extends BaseEdgeProcessor { + + public void processEdgeNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { + try { + EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); + EdgeId edgeId = new EdgeId(new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); + ListenableFuture edgeFuture; + switch (actionType) { + case ASSIGNED_TO_CUSTOMER: + CustomerId customerId = mapper.readValue(edgeNotificationMsg.getBody(), CustomerId.class); + edgeFuture = edgeService.findEdgeByIdAsync(tenantId, edgeId); + Futures.addCallback(edgeFuture, new FutureCallback() { + @Override + public void onSuccess(@Nullable Edge edge) { + if (edge != null && !customerId.isNullUid()) { + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, customerId, null); + PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageData pageData; + do { + pageData = userService.findCustomerUsers(tenantId, customerId, pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + log.trace("[{}] [{}] user(s) are going to be added to edge.", edge.getId(), pageData.getData().size()); + for (User user : pageData.getData()) { + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, EdgeEventActionType.ADDED, user.getId(), null); + } + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } + } while (pageData != null && pageData.hasNext()); + } + } + + @Override + public void onFailure(Throwable t) { + log.error("Can't find edge by id [{}]", edgeNotificationMsg, t); + } + }, dbCallbackExecutorService); + break; + case UNASSIGNED_FROM_CUSTOMER: + CustomerId customerIdToDelete = mapper.readValue(edgeNotificationMsg.getBody(), CustomerId.class); + edgeFuture = edgeService.findEdgeByIdAsync(tenantId, edgeId); + Futures.addCallback(edgeFuture, new FutureCallback() { + @Override + public void onSuccess(@Nullable Edge edge) { + if (edge != null && !customerIdToDelete.isNullUid()) { + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.DELETED, customerIdToDelete, null); + } + } + + @Override + public void onFailure(Throwable t) { + log.error("Can't find edge by id [{}]", edgeNotificationMsg, t); + } + }, dbCallbackExecutorService); + break; + } + } catch (Exception e) { + log.error("Exception during processing edge event", e); + } + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java index f930e316be..56cdfe1c80 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java @@ -15,21 +15,38 @@ */ package org.thingsboard.server.service.edge.rpc.processor; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.EntityIdFactory; +import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainConnectionInfo; import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; import org.thingsboard.server.gen.edge.DeviceUpdateMsg; import org.thingsboard.server.gen.edge.DownlinkMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; +import java.util.List; +import java.util.UUID; @Component @Slf4j @@ -69,5 +86,142 @@ public class EntityEdgeProcessor extends BaseEdgeProcessor { } return downlinkMsg; } + + public void processEntityNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { + EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); + EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); + EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(type, + new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); + EdgeId edgeId = new EdgeId(new UUID(edgeNotificationMsg.getEdgeIdMSB(), edgeNotificationMsg.getEdgeIdLSB())); + ListenableFuture> edgeIdsFuture; + switch (actionType) { + case ADDED: // used only for USER entity + case UPDATED: + case CREDENTIALS_UPDATED: + edgeIdsFuture = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId); + Futures.addCallback(edgeIdsFuture, new FutureCallback>() { + @Override + public void onSuccess(@Nullable List edgeIds) { + if (edgeIds != null && !edgeIds.isEmpty()) { + for (EdgeId edgeId : edgeIds) { + saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null); + } + } + } + @Override + public void onFailure(Throwable throwable) { + log.error("Failed to find related edge ids [{}]", edgeNotificationMsg, throwable); + } + }, dbCallbackExecutorService); + break; + case ASSIGNED_TO_CUSTOMER: + case UNASSIGNED_FROM_CUSTOMER: + edgeIdsFuture = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId); + Futures.addCallback(edgeIdsFuture, new FutureCallback<>() { + @Override + public void onSuccess(@Nullable List edgeIds) { + if (edgeIds != null && !edgeIds.isEmpty()) { + for (EdgeId edgeId : edgeIds) { + try { + CustomerId customerId = mapper.readValue(edgeNotificationMsg.getBody(), CustomerId.class); + ListenableFuture future = edgeService.findEdgeByIdAsync(tenantId, edgeId); + Futures.addCallback(future, new FutureCallback() { + @Override + public void onSuccess(@Nullable Edge edge) { + if (edge != null && edge.getCustomerId() != null && + !edge.getCustomerId().isNullUid() && edge.getCustomerId().equals(customerId)) { + saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null); + } + } + @Override + public void onFailure(Throwable throwable) { + log.error("Failed to find edge by id [{}]", edgeNotificationMsg, throwable); + } + }, dbCallbackExecutorService); + } catch (Exception e) { + log.error("Can't parse customer id from entity body [{}]", edgeNotificationMsg, e); + } + } + } + } + + @Override + public void onFailure(Throwable throwable) { + log.error("Failed to find related edge ids [{}]", edgeNotificationMsg, throwable); + } + }, dbCallbackExecutorService); + break; + case DELETED: + saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null); + break; + case ASSIGNED_TO_EDGE: + case UNASSIGNED_FROM_EDGE: + saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null); + if (type.equals(EdgeEventType.RULE_CHAIN)) { + updateDependentRuleChains(tenantId, new RuleChainId(entityId.getId()), edgeId); + } + break; + } + } + + private void updateDependentRuleChains(TenantId tenantId, RuleChainId processingRuleChainId, EdgeId edgeId) { + PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageData pageData; + do { + pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edgeId, pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + for (RuleChain ruleChain : pageData.getData()) { + if (!ruleChain.getId().equals(processingRuleChainId)) { + List connectionInfos = + ruleChainService.loadRuleChainMetaData(ruleChain.getTenantId(), ruleChain.getId()).getRuleChainConnections(); + if (connectionInfos != null && !connectionInfos.isEmpty()) { + for (RuleChainConnectionInfo connectionInfo : connectionInfos) { + if (connectionInfo.getTargetRuleChainId().equals(processingRuleChainId)) { + saveEdgeEvent(tenantId, + edgeId, + EdgeEventType.RULE_CHAIN_METADATA, + EdgeEventActionType.UPDATED, + ruleChain.getId(), + null); + } + } + } + } + } + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } + } while (pageData != null && pageData.hasNext()); + } + + public void processEntityNotificationForAllEdges(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { + EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); + EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); + EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(type, new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); + switch (actionType) { + case ADDED: + case UPDATED: + case DELETED: + processActionForAllEdges(tenantId, type, actionType, entityId); + break; + } + } + + private void processActionForAllEdges(TenantId tenantId, EdgeEventType type, EdgeEventActionType actionType, EntityId entityId) { + PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageData pageData; + do { + pageData = edgeService.findEdgesByTenantId(tenantId, pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + for (Edge edge : pageData.getData()) { + saveEdgeEvent(tenantId, edge.getId(), type, actionType, entityId, null); + } + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } + } while (pageData != null && pageData.hasNext()); + } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java index 8e3a429d18..190d58fcef 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java @@ -15,18 +15,24 @@ */ package org.thingsboard.server.service.edge.rpc.processor; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityViewId; @@ -37,9 +43,14 @@ import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.gen.edge.DownlinkMsg; import org.thingsboard.server.gen.edge.RelationUpdateMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; +import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.UUID; @Component @@ -112,4 +123,43 @@ public class RelationEdgeProcessor extends BaseEdgeProcessor { .build(); } + public void processRelationNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) throws JsonProcessingException { + EntityRelation relation = mapper.readValue(edgeNotificationMsg.getBody(), EntityRelation.class); + if (!relation.getFrom().getEntityType().equals(EntityType.EDGE) && + !relation.getTo().getEntityType().equals(EntityType.EDGE)) { + List>> futures = new ArrayList<>(); + futures.add(edgeService.findRelatedEdgeIdsByEntityId(tenantId, relation.getTo())); + futures.add(edgeService.findRelatedEdgeIdsByEntityId(tenantId, relation.getFrom())); + ListenableFuture>> combinedFuture = Futures.allAsList(futures); + Futures.addCallback(combinedFuture, new FutureCallback>>() { + @Override + public void onSuccess(@Nullable List> listOfListsEdgeIds) { + Set uniqueEdgeIds = new HashSet<>(); + if (listOfListsEdgeIds != null && !listOfListsEdgeIds.isEmpty()) { + for (List listOfListsEdgeId : listOfListsEdgeIds) { + if (listOfListsEdgeId != null) { + uniqueEdgeIds.addAll(listOfListsEdgeId); + } + } + } + if (!uniqueEdgeIds.isEmpty()) { + for (EdgeId edgeId : uniqueEdgeIds) { + saveEdgeEvent(tenantId, + edgeId, + EdgeEventType.RELATION, + EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()), + null, + mapper.valueToTree(relation)); + } + } + } + + @Override + public void onFailure(Throwable t) { + log.warn("[{}] can't find related edge ids by relation to id [{}] and relation from id [{}]" , + tenantId.getId(), relation.getTo().getId(), relation.getFrom().getId(), t); + } + }, dbCallbackExecutorService); + } + } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java index 8c0d28226d..b13609b93d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java @@ -17,16 +17,25 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.EntityIdFactory; +import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetsBundleId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.gen.edge.DownlinkMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; +import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; +import java.util.UUID; @Component @Slf4j From 0b8d0e602902781b371c0944bbd0c76407a6fb20 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 19 May 2021 17:32:16 +0300 Subject: [PATCH 15/52] Move processActionForAllEdges to base class for PE --- .../edge/rpc/processor/BaseEdgeProcessor.java | 18 ++++++++++++++++++ .../rpc/processor/EntityEdgeProcessor.java | 16 ---------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java index 717e70d7aa..e982cca088 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java @@ -32,6 +32,8 @@ import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.attributes.AttributesService; @@ -217,4 +219,20 @@ public abstract class BaseEdgeProcessor { return null; } } + + protected void processActionForAllEdges(TenantId tenantId, EdgeEventType type, EdgeEventActionType actionType, EntityId entityId) { + PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageData pageData; + do { + pageData = edgeService.findEdgesByTenantId(tenantId, pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + for (Edge edge : pageData.getData()) { + saveEdgeEvent(tenantId, edge.getId(), type, actionType, entityId, null); + } + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } + } while (pageData != null && pageData.hasNext()); + } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java index 56cdfe1c80..5bf2e77044 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java @@ -207,21 +207,5 @@ public class EntityEdgeProcessor extends BaseEdgeProcessor { break; } } - - private void processActionForAllEdges(TenantId tenantId, EdgeEventType type, EdgeEventActionType actionType, EntityId entityId) { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - pageData = edgeService.findEdgesByTenantId(tenantId, pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - for (Edge edge : pageData.getData()) { - saveEdgeEvent(tenantId, edge.getId(), type, actionType, entityId, null); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - } } From c43bc3c8b11f41986b8872fad5f2030d570e05e6 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 19 May 2021 18:08:34 +0300 Subject: [PATCH 16/52] Organize imports --- .../edge/rpc/processor/WidgetBundleEdgeProcessor.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java index b13609b93d..8c0d28226d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java @@ -17,25 +17,16 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; -import org.thingsboard.server.common.data.edge.EdgeEventType; -import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.EntityIdFactory; -import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetsBundleId; -import org.thingsboard.server.common.data.page.PageData; -import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.gen.edge.DownlinkMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; -import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; -import java.util.UUID; @Component @Slf4j From 2c826c12cd86a4c27fd3ed74b9640074400adaa1 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 20 May 2021 13:05:21 +0300 Subject: [PATCH 17/52] added admin setting fetcher --- .../controller/RuleChainController.java | 2 +- .../service/edge/EdgeContextComponent.java | 5 + .../service/edge/rpc/EdgeGrpcSession.java | 8 +- .../DeviceProfileMsgConstructor.java | 2 +- .../fetch/AdminSettingsEdgeEventFetcher.java | 165 ++++++++++-------- .../fetch/BasePageableEdgeEventFetcher.java | 3 + .../edge/rpc/fetch/EdgeEventFetcher.java | 2 +- .../rpc/processor/DeviceEdgeProcessor.java | 2 - .../rpc/processor/TelemetryEdgeProcessor.java | 2 +- .../thingsboard/server/edge/BaseEdgeTest.java | 2 - .../server/dao/edge/EdgeServiceImpl.java | 2 +- .../dao/entity/AbstractEntityService.java | 2 +- .../rule/engine/edge/TbMsgPushToEdgeNode.java | 2 +- .../rule-chain-autocomplete.component.ts | 2 +- 14 files changed, 115 insertions(+), 86 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index 6f7cf4e81d..d3035b4f3b 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -635,7 +635,7 @@ public class RuleChainController extends BaseController { } } - // TODO: refactor this - add new config to edge rule chain to set it as auto-assign + // TODO: @voba refactor this - add new config to edge rule chain to set it as auto-assign @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/ruleChain/autoAssignToEdgeRuleChains", method = RequestMethod.GET) @ResponseBody diff --git a/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java b/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java index bdc5c26889..72b5831a4d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java @@ -27,6 +27,7 @@ import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.rule.RuleChainService; +import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.widget.WidgetsBundleService; import org.thingsboard.server.queue.util.TbCoreComponent; @@ -62,6 +63,10 @@ public class EdgeContextComponent { @Autowired private EdgeEventService edgeEventService; + @Lazy + @Autowired + private AdminSettingsService adminSettingsService; + @Lazy @Autowired private AssetService assetService; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index e95c5952f4..c168c20983 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -68,6 +68,7 @@ import org.thingsboard.server.gen.edge.UplinkResponseMsg; import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; import org.thingsboard.server.gen.edge.WidgetBundleTypesRequestMsg; import org.thingsboard.server.service.edge.EdgeContextComponent; +import org.thingsboard.server.service.edge.rpc.fetch.AdminSettingsEdgeEventFetcher; import org.thingsboard.server.service.edge.rpc.fetch.AssetsEdgeEventFetcher; import org.thingsboard.server.service.edge.rpc.fetch.CustomerUsersEdgeEventFetcher; import org.thingsboard.server.service.edge.rpc.fetch.DashboardsEdgeEventFetcher; @@ -207,8 +208,7 @@ public final class EdgeGrpcSession implements Closeable { startProcessingEdgeEvents(new CustomerUsersEdgeEventFetcher(ctx.getUserService(), edge.getCustomerId())); } - // TODO: voba - implement this functionality - // syncAdminSettings(edge); + startProcessingEdgeEvents(new AdminSettingsEdgeEventFetcher(ctx.getAdminSettingsService())); startProcessingEdgeEvents(new AssetsEdgeEventFetcher(ctx.getAssetService())); startProcessingEdgeEvents(new DashboardsEdgeEventFetcher(ctx.getDashboardService())); @@ -285,7 +285,7 @@ public final class EdgeGrpcSession implements Closeable { sendDownlinkMsg(edgeConfigMsg); } - void processEdgeEvents() throws ExecutionException, InterruptedException { + void processEdgeEvents() throws Exception { log.trace("[{}] processHandleMessages started", this.sessionId); if (isConnected() && isSyncCompleted()) { Long queueStartTs = getQueueStartTs().get(); @@ -301,7 +301,7 @@ public final class EdgeGrpcSession implements Closeable { log.trace("[{}] processHandleMessages finished", this.sessionId); } - private UUID startProcessingEdgeEvents(EdgeEventFetcher fetcher) throws InterruptedException { + private UUID startProcessingEdgeEvents(EdgeEventFetcher fetcher) throws Exception { PageLink pageLink = fetcher.getPageLink(ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount()); PageData pageData; UUID ifOffset = null; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceProfileMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceProfileMsgConstructor.java index c3f5346170..b5ec2cd396 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceProfileMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceProfileMsgConstructor.java @@ -41,7 +41,7 @@ public class DeviceProfileMsgConstructor { .setDefault(deviceProfile.isDefault()) .setType(deviceProfile.getType().name()) .setProfileDataBytes(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile.getProfileData()))); - // TODO: voba - should this be always null at the moment?? + // TODO: @voba - add possibility to setup edge rule chain as device profile default // if (deviceProfile.getDefaultRuleChainId() != null) { // builder.setDefaultRuleChainIdMSB(deviceProfile.getDefaultRuleChainId().getId().getMostSignificantBits()) // .setDefaultRuleChainIdLSB(deviceProfile.getDefaultRuleChainId().getId().getLeastSignificantBits()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java index be5344acd4..ec30e964b4 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java @@ -15,90 +15,115 @@ */ package org.thingsboard.server.service.edge.rpc.fetch; +import com.datastax.oss.driver.api.core.uuid.Uuids; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.text.WordUtils; +import org.springframework.core.io.DefaultResourceLoader; +import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.AdminSettingsId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.dao.settings.AdminSettingsService; +import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; + +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @AllArgsConstructor @Slf4j public class AdminSettingsEdgeEventFetcher extends BasePageableEdgeEventFetcher { + private final AdminSettingsService adminSettingsService; + @Override - public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { - return null; + public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) throws Exception { + List result = new ArrayList<>(); + + AdminSettings systemMailSettings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"); + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.ADMIN_SETTINGS, + EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailSettings))); + + AdminSettings tenantMailSettings = convertToTenantAdminSettings(systemMailSettings.getKey(), (ObjectNode) systemMailSettings.getJsonValue()); + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.ADMIN_SETTINGS, + EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailSettings))); + + AdminSettings systemMailTemplates = loadMailTemplates(); + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.ADMIN_SETTINGS, + EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailTemplates))); + + AdminSettings tenantMailTemplates = convertToTenantAdminSettings(systemMailTemplates.getKey(), (ObjectNode) systemMailTemplates.getJsonValue()); + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.ADMIN_SETTINGS, + EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailTemplates))); + + // @voba - returns PageData object to be in sync with other fetchers + return new PageData<>(result, 1, result.size(), false); } + private AdminSettings loadMailTemplates() throws Exception { + Map mailTemplates = new HashMap<>(); + Pattern startPattern = Pattern.compile("
"); + Pattern endPattern = Pattern.compile("
"); + File[] files = new DefaultResourceLoader().getResource("classpath:/templates/").getFile().listFiles(); + for (File file : files) { + Map mailTemplate = new HashMap<>(); + String name = validateName(file.getName()); + String stringTemplate = FileUtils.readFileToString(file, StandardCharsets.UTF_8); + Matcher start = startPattern.matcher(stringTemplate); + Matcher end = endPattern.matcher(stringTemplate); + if (start.find() && end.find()) { + String body = StringUtils.substringBetween(stringTemplate, start.group(), end.group()).replaceAll("\t", ""); + String subject = StringUtils.substringBetween(body, "

", "

"); + mailTemplate.put("subject", subject); + mailTemplate.put("body", body); + mailTemplates.put(name, mailTemplate); + } else { + log.error("Can't load mail template from file {}", file.getName()); + } + } + AdminSettings adminSettings = new AdminSettings(); + adminSettings.setId(new AdminSettingsId(Uuids.timeBased())); + adminSettings.setKey("mailTemplates"); + adminSettings.setJsonValue(mapper.convertValue(mailTemplates, JsonNode.class)); + return adminSettings; + } -// -// private void syncAdminSettings(TenantId tenantId, Edge edge) { -// log.trace("[{}] syncAdminSettings [{}]", tenantId, edge.getName()); -// try { -// AdminSettings systemMailSettings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"); -// saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailSettings)); -// AdminSettings tenantMailSettings = convertToTenantAdminSettings(systemMailSettings.getKey(), (ObjectNode) systemMailSettings.getJsonValue()); -// saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailSettings)); -// AdminSettings systemMailTemplates = loadMailTemplates(); -// saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailTemplates)); -// AdminSettings tenantMailTemplates = convertToTenantAdminSettings(systemMailTemplates.getKey(), (ObjectNode) systemMailTemplates.getJsonValue()); -// saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailTemplates)); -// } catch (Exception e) { -// log.error("Can't load admin settings", e); -// } -// } -// -// private AdminSettings loadMailTemplates() throws Exception { -// Map mailTemplates = new HashMap<>(); -// Pattern startPattern = Pattern.compile("
"); -// Pattern endPattern = Pattern.compile("
"); -// File[] files = new DefaultResourceLoader().getResource("classpath:/templates/").getFile().listFiles(); -// for (File file : files) { -// Map mailTemplate = new HashMap<>(); -// String name = validateName(file.getName()); -// String stringTemplate = FileUtils.readFileToString(file, StandardCharsets.UTF_8); -// Matcher start = startPattern.matcher(stringTemplate); -// Matcher end = endPattern.matcher(stringTemplate); -// if (start.find() && end.find()) { -// String body = StringUtils.substringBetween(stringTemplate, start.group(), end.group()).replaceAll("\t", ""); -// String subject = StringUtils.substringBetween(body, "

", "

"); -// mailTemplate.put("subject", subject); -// mailTemplate.put("body", body); -// mailTemplates.put(name, mailTemplate); -// } else { -// log.error("Can't load mail template from file {}", file.getName()); -// } -// } -// AdminSettings adminSettings = new AdminSettings(); -// adminSettings.setId(new AdminSettingsId(Uuids.timeBased())); -// adminSettings.setKey("mailTemplates"); -// adminSettings.setJsonValue(mapper.convertValue(mailTemplates, JsonNode.class)); -// return adminSettings; -// } -// -// private String validateName(String name) throws Exception { -// StringBuilder nameBuilder = new StringBuilder(); -// name = name.replace(".vm", ""); -// String[] nameParts = name.split("\\."); -// if (nameParts.length >= 1) { -// nameBuilder.append(nameParts[0]); -// for (int i = 1; i < nameParts.length; i++) { -// String word = WordUtils.capitalize(nameParts[i]); -// nameBuilder.append(word); -// } -// return nameBuilder.toString(); -// } else { -// throw new Exception("Error during filename validation"); -// } -// } -// -// private AdminSettings convertToTenantAdminSettings(String key, ObjectNode jsonValue) { -// AdminSettings tenantMailSettings = new AdminSettings(); -// jsonValue.put("useSystemMailSettings", true); -// tenantMailSettings.setJsonValue(jsonValue); -// tenantMailSettings.setKey(key); -// return tenantMailSettings; -// } + private String validateName(String name) throws Exception { + StringBuilder nameBuilder = new StringBuilder(); + name = name.replace(".vm", ""); + String[] nameParts = name.split("\\."); + if (nameParts.length >= 1) { + nameBuilder.append(nameParts[0]); + for (int i = 1; i < nameParts.length; i++) { + String word = WordUtils.capitalize(nameParts[i]); + nameBuilder.append(word); + } + return nameBuilder.toString(); + } else { + throw new Exception("Error during filename validation"); + } + } + + private AdminSettings convertToTenantAdminSettings(String key, ObjectNode jsonValue) { + AdminSettings tenantMailSettings = new AdminSettings(); + jsonValue.put("useSystemMailSettings", true); + tenantMailSettings.setJsonValue(jsonValue); + tenantMailSettings.setKey(key); + return tenantMailSettings; + } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java index 3c2f7f82fd..409e044864 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java @@ -15,10 +15,13 @@ */ package org.thingsboard.server.service.edge.rpc.fetch; +import com.fasterxml.jackson.databind.ObjectMapper; import org.thingsboard.server.common.data.page.PageLink; public abstract class BasePageableEdgeEventFetcher implements EdgeEventFetcher { + protected static final ObjectMapper mapper = new ObjectMapper(); + @Override public PageLink getPageLink(int pageSize) { return new PageLink(pageSize); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java index d36b072c3d..077a4105ed 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java @@ -25,5 +25,5 @@ public interface EdgeEventFetcher { PageLink getPageLink(int pageSize); - PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink); + PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) throws Exception; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java index b3ec44195e..c889b3a49c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java @@ -72,8 +72,6 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { private static final ReentrantLock deviceCreationLock = new ReentrantLock(); - // TODO onDeviceUpdateFromEdge onDeviceUpdateToEdge - public ListenableFuture processDeviceFromEdge(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { log.trace("[{}] onDeviceUpdate [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); switch (deviceUpdateMsg.getMsgType()) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java index c475542892..dcced3d687 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java @@ -82,7 +82,7 @@ public class TelemetryEdgeProcessor extends BaseEdgeProcessor { List> result = new ArrayList<>(); EntityId entityId = constructEntityId(entityData); if ((entityData.hasPostAttributesMsg() || entityData.hasPostTelemetryMsg() || entityData.hasAttributesUpdatedMsg()) && entityId != null) { - // TODO: voba - in terms of performance we should not fetch device from DB by id + // @voba - in terms of performance we should not fetch device from DB by id // TbMsgMetaData metaData = constructBaseMsgMetadata(tenantId, entityId); TbMsgMetaData metaData = new TbMsgMetaData(); metaData.putValue(DataConstants.MSG_SOURCE_KEY, DataConstants.EDGE_MSG_SOURCE); diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java index 8e3e8be882..c255ce93ea 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -171,8 +171,6 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { installation(); edgeImitator = new EdgeImitator("localhost", 7070, edge.getRoutingKey(), edge.getSecret()); - // TODO: voba - should be less, but events from SyncEdgeService stack with events from controller. will be fixed in next releases - // so ideally sync process should check current edge queue and add only missing entities to the edge queue edgeImitator.expectMessageAmount(9); edgeImitator.connect(); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index 21ca4228a3..aee1fe7d34 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -497,7 +497,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @Override public ListenableFuture> findRelatedEdgeIdsByEntityId(TenantId tenantId, EntityId entityId) { - // TODO: voba - rewrite 'find' to use native SQL queries instead of fetching relations + // TODO: @voba - rewrite 'find' to use native SQL queries instead of fetching relations log.trace("[{}] Executing findRelatedEdgeIdsByEntityId [{}]", tenantId, entityId); if (EntityType.TENANT.equals(entityId.getEntityType()) || diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java index 0c80195d9b..5da1d56181 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java @@ -77,7 +77,7 @@ public abstract class AbstractEntityService { List entityViews = entityViewService.findEntityViewsByTenantIdAndEntityIdAsync(tenantId, entityId).get(); if (entityViews != null && !entityViews.isEmpty()) { EntityView entityView = entityViews.get(0); - // TODO: voba - refactor this blocking operation in 3.3+ + // TODO: @voba - refactor this blocking operation in 3.3+ Boolean relationExists = relationService.checkRelation(tenantId,edgeId, entityView.getId(), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE).get(); if (relationExists) { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java index e766c2600c..f208213d63 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java @@ -223,7 +223,7 @@ public class TbMsgPushToEdgeNode implements TbNode { private String getScope(Map metadata) { String scope = metadata.get(SCOPE); if (StringUtils.isEmpty(scope)) { - // TODO: voba - move this to configuration of the node UI or some other place + // TODO: @voba - move this to configuration of the node UI or some other place scope = DataConstants.SERVER_SCOPE; } return scope; diff --git a/ui-ngx/src/app/modules/home/components/rule-chain/rule-chain-autocomplete.component.ts b/ui-ngx/src/app/modules/home/components/rule-chain/rule-chain-autocomplete.component.ts index b190b0d293..82241702ae 100644 --- a/ui-ngx/src/app/modules/home/components/rule-chain/rule-chain-autocomplete.component.ts +++ b/ui-ngx/src/app/modules/home/components/rule-chain/rule-chain-autocomplete.component.ts @@ -188,7 +188,7 @@ export class RuleChainAutocompleteComponent implements ControlValueAccessor, OnI fetchRuleChain(searchText?: string): Observable>> { this.searchText = searchText; - // voba: at the moment device profiles are not supported by edge, so 'core' hardcoded + // @voba: at the moment device profiles are not supported by edge, so 'core' hardcoded return this.entityService.getEntitiesByNameFilter(EntityType.RULE_CHAIN, searchText, 50, RuleChainType.CORE, {ignoreLoading: true}); } From a3d728f03e24a8c7bec08356506b9d7ba7e76673 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 20 May 2021 13:20:34 +0300 Subject: [PATCH 18/52] Changed signature of edge fetch method --- .../server/service/edge/rpc/EdgeGrpcSession.java | 4 +--- .../rpc/fetch/AdminSettingsEdgeEventFetcher.java | 12 ++++++------ .../edge/rpc/fetch/AssetsEdgeEventFetcher.java | 10 +++++----- .../edge/rpc/fetch/BaseUsersEdgeEventFetcher.java | 8 ++++---- .../fetch/BaseWidgetsBundlesEdgeEventFetcher.java | 8 ++++---- .../edge/rpc/fetch/DashboardsEdgeEventFetcher.java | 10 +++++----- .../rpc/fetch/DeviceProfilesEdgeEventFetcher.java | 8 ++++---- .../service/edge/rpc/fetch/EdgeEventFetcher.java | 4 ++-- .../edge/rpc/fetch/GeneralEdgeEventFetcher.java | 6 +++--- .../edge/rpc/fetch/RuleChainsEdgeEventFetcher.java | 10 +++++----- 10 files changed, 39 insertions(+), 41 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index c168c20983..9c676d2e6e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -87,7 +87,6 @@ import java.util.List; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; @@ -307,7 +306,7 @@ public final class EdgeGrpcSession implements Closeable { UUID ifOffset = null; boolean success; do { - pageData = fetcher.fetchEdgeEvents(edge.getTenantId(), edge.getId(), pageLink); + pageData = fetcher.fetchEdgeEvents(edge.getTenantId(), edge, pageLink); if (isConnected() && !pageData.getData().isEmpty()) { log.trace("[{}] [{}] event(s) are going to be processed.", this.sessionId, pageData.getData().size()); List downlinkMsgsPack = convertToDownlinkMsgsPack(pageData.getData()); @@ -479,7 +478,6 @@ public final class EdgeGrpcSession implements Closeable { } } - private ListenableFuture> processUplinkMsg(UplinkMsg uplinkMsg) { List> result = new ArrayList<>(); try { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java index ec30e964b4..94dd836dcd 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java @@ -25,11 +25,11 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.text.WordUtils; import org.springframework.core.io.DefaultResourceLoader; import org.thingsboard.server.common.data.AdminSettings; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.AdminSettingsId; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -52,23 +52,23 @@ public class AdminSettingsEdgeEventFetcher extends BasePageableEdgeEventFetcher private final AdminSettingsService adminSettingsService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) throws Exception { + public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) throws Exception { List result = new ArrayList<>(); AdminSettings systemMailSettings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"); - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.ADMIN_SETTINGS, + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailSettings))); AdminSettings tenantMailSettings = convertToTenantAdminSettings(systemMailSettings.getKey(), (ObjectNode) systemMailSettings.getJsonValue()); - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.ADMIN_SETTINGS, + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailSettings))); AdminSettings systemMailTemplates = loadMailTemplates(); - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.ADMIN_SETTINGS, + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailTemplates))); AdminSettings tenantMailTemplates = convertToTenantAdminSettings(systemMailTemplates.getKey(), (ObjectNode) systemMailTemplates.getJsonValue()); - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.ADMIN_SETTINGS, + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailTemplates))); // @voba - returns PageData object to be in sync with other fetchers diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java index 30bbcd0aa1..e2fcd40624 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java @@ -18,10 +18,10 @@ package org.thingsboard.server.service.edge.rpc.fetch; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -38,13 +38,13 @@ public class AssetsEdgeEventFetcher extends BasePageableEdgeEventFetcher { private final AssetService assetService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { - log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); - PageData pageData = assetService.findAssetsByTenantIdAndEdgeId(tenantId, edgeId, pageLink); + public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); + PageData pageData = assetService.findAssetsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); List result = new ArrayList<>(); if (!pageData.getData().isEmpty()) { for (Asset asset : pageData.getData()) { - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.ASSET, + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ASSET, EdgeEventActionType.ADDED, asset.getId(), null)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java index c4c0ee3a86..fc5f5a49fe 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java @@ -18,10 +18,10 @@ package org.thingsboard.server.service.edge.rpc.fetch; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -38,13 +38,13 @@ public abstract class BaseUsersEdgeEventFetcher extends BasePageableEdgeEventFet protected final UserService userService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { - log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); + public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); PageData pageData = findUsers(tenantId, pageLink); List result = new ArrayList<>(); if (!pageData.getData().isEmpty()) { for (User user : pageData.getData()) { - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.USER, + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER, EdgeEventActionType.ADDED, user.getId(), null)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java index d025009db9..166e78eafa 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java @@ -17,10 +17,10 @@ package org.thingsboard.server.service.edge.rpc.fetch; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -38,13 +38,13 @@ public abstract class BaseWidgetsBundlesEdgeEventFetcher extends BasePageableEdg protected final WidgetsBundleService widgetsBundleService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { - log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); + public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); PageData pageData = findWidgetsBundles(tenantId, pageLink); List result = new ArrayList<>(); if (!pageData.getData().isEmpty()) { for (WidgetsBundle widgetsBundle : pageData.getData()) { - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.WIDGETS_BUNDLE, + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGETS_BUNDLE, EdgeEventActionType.ADDED, widgetsBundle.getId(), null)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java index 751c6690c1..703ad9f83e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java @@ -18,10 +18,10 @@ package org.thingsboard.server.service.edge.rpc.fetch; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.DashboardInfo; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -38,13 +38,13 @@ public class DashboardsEdgeEventFetcher extends BasePageableEdgeEventFetcher { private final DashboardService dashboardService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { - log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); - PageData pageData = dashboardService.findDashboardsByTenantIdAndEdgeId(tenantId, edgeId, pageLink); + public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); + PageData pageData = dashboardService.findDashboardsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); List result = new ArrayList<>(); if (!pageData.getData().isEmpty()) { for (DashboardInfo dashboardInfo : pageData.getData()) { - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.DASHBOARD, + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DASHBOARD, EdgeEventActionType.ADDED, dashboardInfo.getId(), null)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java index 011761cf11..cfb2df290e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java @@ -18,10 +18,10 @@ package org.thingsboard.server.service.edge.rpc.fetch; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -38,13 +38,13 @@ public class DeviceProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher private final DeviceProfileService deviceProfileService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { - log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); + public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); PageData pageData = deviceProfileService.findDeviceProfiles(tenantId, pageLink); List result = new ArrayList<>(); if (!pageData.getData().isEmpty()) { for (DeviceProfile deviceProfile : pageData.getData()) { - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.DEVICE_PROFILE, + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE_PROFILE, EdgeEventActionType.ADDED, deviceProfile.getId(), null)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java index 077a4105ed..b3e50b2eb1 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.service.edge.rpc.fetch; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -25,5 +25,5 @@ public interface EdgeEventFetcher { PageLink getPageLink(int pageSize); - PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) throws Exception; + PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) throws Exception; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java index 39d0b482ed..b66aeb8abf 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java @@ -16,8 +16,8 @@ package org.thingsboard.server.service.edge.rpc.fetch; import lombok.AllArgsConstructor; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -43,7 +43,7 @@ public class GeneralEdgeEventFetcher implements EdgeEventFetcher { } @Override - public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { - return edgeEventService.findEdgeEvents(tenantId, edgeId, (TimePageLink) pageLink, true); + public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { + return edgeEventService.findEdgeEvents(tenantId, edge.getId(), (TimePageLink) pageLink, true); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java index 3da1dcc47c..1bb609d769 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java @@ -17,10 +17,10 @@ package org.thingsboard.server.service.edge.rpc.fetch; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -38,13 +38,13 @@ public class RuleChainsEdgeEventFetcher extends BasePageableEdgeEventFetcher { private final RuleChainService ruleChainService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, EdgeId edgeId, PageLink pageLink) { - log.trace("[{}] start fetching edge events [{}]", tenantId, edgeId); - PageData pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edgeId, pageLink); + public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); + PageData pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); List result = new ArrayList<>(); if (!pageData.getData().isEmpty()) { for (RuleChain ruleChain : pageData.getData()) { - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.RULE_CHAIN, + result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, EdgeEventActionType.ADDED, ruleChain.getId(), null)); } } From 19bbccce56ff4599e2e3c83e05cc4c633aaac36f Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 20 May 2021 16:03:41 +0300 Subject: [PATCH 19/52] Added edge rule chain if edges disabled - for future, when edges are enabled back --- .../org/thingsboard/server/controller/TenantController.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/TenantController.java b/application/src/main/java/org/thingsboard/server/controller/TenantController.java index 7621d05908..04d37371e3 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TenantController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TenantController.java @@ -95,9 +95,7 @@ public class TenantController extends BaseController { tenant = checkNotNull(tenantService.saveTenant(tenant)); if (newTenant) { installScripts.createDefaultRuleChains(tenant.getId()); - if (edgesEnabled) { - installScripts.createDefaultEdgeRuleChains(tenant.getId()); - } + installScripts.createDefaultEdgeRuleChains(tenant.getId()); } tenantProfileCache.evict(tenant.getId()); tbClusterService.onTenantChange(tenant, null); From 93de268018321ddf6020bf4413293670eb7725de Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 20 May 2021 18:33:12 +0300 Subject: [PATCH 20/52] Filter non null msgs. Add warn in case unknonw entity type --- .../server/service/edge/rpc/EdgeGrpcSession.java | 2 ++ .../edge/rpc/processor/TelemetryEdgeProcessor.java | 11 +++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 9c676d2e6e..b7127d4ee2 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -84,6 +84,7 @@ import java.io.Closeable; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CountDownLatch; @@ -393,6 +394,7 @@ public final class EdgeGrpcSession implements Closeable { return edgeEvents .stream() .map(this::convertToDownlinkMsg) + .filter(Objects::nonNull) .collect(Collectors.toList()); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java index dcced3d687..419cd95179 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java @@ -288,7 +288,7 @@ public class TelemetryEdgeProcessor extends BaseEdgeProcessor { } public DownlinkMsg processTelemetryMessageToEdge(EdgeEvent edgeEvent) throws JsonProcessingException { - EntityId entityId = null; + EntityId entityId; switch (edgeEvent.getType()) { case DEVICE: entityId = new DeviceId(edgeEvent.getEntityId()); @@ -311,12 +311,11 @@ public class TelemetryEdgeProcessor extends BaseEdgeProcessor { case EDGE: entityId = new EdgeId(edgeEvent.getEntityId()); break; + default: + log.warn("Unsupported edge event type [{}]", edgeEvent); + return null; } - DownlinkMsg downlinkMsg = null; - if (entityId != null) { - downlinkMsg = constructEntityDataProtoMsg(entityId, edgeEvent.getAction(), JsonUtils.parse(mapper.writeValueAsString(edgeEvent.getBody()))); - } - return downlinkMsg; + return constructEntityDataProtoMsg(entityId, edgeEvent.getAction(), JsonUtils.parse(mapper.writeValueAsString(edgeEvent.getBody()))); } private DownlinkMsg constructEntityDataProtoMsg(EntityId entityId, EdgeEventActionType actionType, JsonElement entityData) { From b0bfdfff8e8e3826fefa145856e8211892d5a35b Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 25 May 2021 10:38:12 +0300 Subject: [PATCH 21/52] Pagedata usage for get edges methods --- .../server/controller/BaseController.java | 22 +++- .../controller/RuleChainController.java | 4 +- .../rpc/processor/AlarmEdgeProcessor.java | 40 +++--- .../edge/rpc/processor/BaseEdgeProcessor.java | 4 +- .../rpc/processor/CustomerEdgeProcessor.java | 2 +- .../rpc/processor/DeviceEdgeProcessor.java | 60 ++++----- .../edge/rpc/processor/EdgeProcessor.java | 2 +- .../rpc/processor/EntityEdgeProcessor.java | 83 ++++++------- .../rpc/processor/RelationEdgeProcessor.java | 62 +++++----- .../rpc/sync/DefaultEdgeRequestsService.java | 4 +- .../server/dao/edge/EdgeService.java | 6 +- .../thingsboard/server/dao/edge/EdgeDao.java | 18 +-- .../server/dao/edge/EdgeServiceImpl.java | 117 ++++++------------ .../dao/entity/AbstractEntityService.java | 4 +- .../server/dao/rule/BaseRuleChainService.java | 22 ++-- .../server/dao/sql/edge/EdgeRepository.java | 11 ++ .../server/dao/sql/edge/JpaEdgeDao.java | 23 ++-- .../rule/engine/edge/TbMsgPushToEdgeNode.java | 105 +++++++--------- 18 files changed, 257 insertions(+), 332 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 9f6379cf6c..0543fdd47f 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -83,6 +83,7 @@ import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.DataType; import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.SortOrder; import org.thingsboard.server.common.data.page.TimePageLink; @@ -145,6 +146,7 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; import javax.mail.MessagingException; import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; @@ -164,6 +166,8 @@ public abstract class BaseController { protected static final String DEFAULT_DASHBOARD = "defaultDashboardId"; protected static final String HOME_DASHBOARD = "homeDashboardId"; + private static final int DEFAULT_PAGE_SIZE = 1000; + private static final ObjectMapper json = new ObjectMapper(); @Autowired @@ -1082,12 +1086,18 @@ public abstract class BaseController { if (!edgesEnabled) { return null; } - List result = null; - try { - result = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId).get(); - } catch (Exception e) { - log.error("[{}] can't find related edge ids for entity [{}]", tenantId, entityId, e); - } + List result = new ArrayList<>(); + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); + PageData pageData; + do { + pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId, pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + result.addAll(pageData.getData()); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } + } while (pageData != null && pageData.hasNext()); return result; } diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index d3035b4f3b..1f09e29e6e 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -86,7 +86,7 @@ public class RuleChainController extends BaseController { public static final String RULE_CHAIN_ID = "ruleChainId"; public static final String RULE_NODE_ID = "ruleNodeId"; - private static final int DEFAULT_LIMIT = 100; + private static final int DEFAULT_PAGE_SIZE = 1000; private static final ObjectMapper objectMapper = new ObjectMapper(); @@ -643,7 +643,7 @@ public class RuleChainController extends BaseController { try { TenantId tenantId = getCurrentUser().getTenantId(); List result = new ArrayList<>(); - PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); PageData pageData; do { pageData = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId, pageLink); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java index 3ff245b0d9..5893840728 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java @@ -34,6 +34,8 @@ import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.gen.edge.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.DownlinkMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; @@ -41,7 +43,6 @@ import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; -import java.util.List; import java.util.UUID; @Component @@ -138,34 +139,31 @@ public class AlarmEdgeProcessor extends BaseEdgeProcessor { if (alarm != null) { EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(alarm.getOriginator().getEntityType()); if (type != null) { - ListenableFuture> relatedEdgeIdsByEntityIdFuture = edgeService.findRelatedEdgeIdsByEntityId(tenantId, alarm.getOriginator()); - Futures.addCallback(relatedEdgeIdsByEntityIdFuture, new FutureCallback>() { - @Override - public void onSuccess(@Nullable List relatedEdgeIdsByEntityId) { - if (relatedEdgeIdsByEntityId != null) { - for (EdgeId edgeId : relatedEdgeIdsByEntityId) { - saveEdgeEvent(tenantId, - edgeId, - EdgeEventType.ALARM, - EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()), - alarmId, - null); - } + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); + PageData pageData; + do { + pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, alarm.getOriginator(), pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + for (EdgeId edgeId : pageData.getData()) { + saveEdgeEvent(tenantId, + edgeId, + EdgeEventType.ALARM, + EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()), + alarmId, + null); + } + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); } } - - @Override - public void onFailure(Throwable t) { - log.warn("[{}] can't find related edge ids by entity id [{}]", tenantId.getId(), alarm.getOriginator(), t); - } - }, dbCallbackExecutorService); + } while (pageData != null && pageData.hasNext()); } } } @Override public void onFailure(Throwable t) { - log.warn("[{}] can't find alarm by id [{}]", tenantId.getId(), alarmId.getId(), t); + log.warn("[{}] can't find alarm by id [{}] {}", tenantId.getId(), alarmId.getId(), t); } }, dbCallbackExecutorService); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java index e982cca088..f32576499e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java @@ -74,7 +74,7 @@ public abstract class BaseEdgeProcessor { protected static final ObjectMapper mapper = new ObjectMapper(); - protected static final int DEFAULT_LIMIT = 100; + protected static final int DEFAULT_PAGE_SIZE = 1000; @Autowired protected RuleChainService ruleChainService; @@ -221,7 +221,7 @@ public abstract class BaseEdgeProcessor { } protected void processActionForAllEdges(TenantId tenantId, EdgeEventType type, EdgeEventActionType actionType, EntityId entityId) { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); PageData pageData; do { pageData = edgeService.findEdgesByTenantId(tenantId, pageLink); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java index 63b2c5d577..00de4eb576 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java @@ -75,7 +75,7 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor { CustomerId customerId = new CustomerId(EntityIdFactory.getByEdgeEventTypeAndUuid(type, uuid).getId()); switch (actionType) { case UPDATED: - PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); PageData pageData; do { pageData = edgeService.findEdgesByTenantIdAndCustomerId(tenantId, customerId, pageLink); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java index c889b3a49c..f540186976 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java @@ -17,14 +17,12 @@ package org.thingsboard.server.service.edge.rpc.processor; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; -import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.stereotype.Component; import org.thingsboard.rule.engine.api.RpcError; import org.thingsboard.server.common.data.Customer; @@ -40,6 +38,8 @@ import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.security.DeviceCredentials; @@ -61,7 +61,6 @@ import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; import java.util.Collections; -import java.util.List; import java.util.UUID; import java.util.concurrent.locks.ReentrantLock; @@ -79,41 +78,34 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { String deviceName = deviceUpdateMsg.getName(); Device device = deviceService.findDeviceByTenantIdAndName(tenantId, deviceName); if (device != null) { - ListenableFuture> future = edgeService.findRelatedEdgeIdsByEntityId(tenantId, device.getId()); - SettableFuture futureToSet = SettableFuture.create(); - Futures.addCallback(future, new FutureCallback>() { - @Override - public void onSuccess(@Nullable List edgeIds) { - boolean update = false; - if (edgeIds != null && !edgeIds.isEmpty()) { - if (edgeIds.contains(edge.getId())) { - update = true; - } + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); + PageData pageData; + do { + pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, device.getId(), pageLink); + boolean update = false; + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + if (pageData.getData().contains(edge.getId())) { + update = true; } - Device device; - if (update) { - log.info("[{}] Device with name '{}' already exists on the cloud, and related to this edge [{}]. " + - "deviceUpdateMsg [{}], Updating device", tenantId, deviceName, edge.getId(), deviceUpdateMsg); - updateDevice(tenantId, edge, deviceUpdateMsg); - } else { - log.info("[{}] Device with name '{}' already exists on the cloud, but not related to this edge [{}]. deviceUpdateMsg [{}]." + - "Creating a new device with random prefix and relate to this edge", tenantId, deviceName, edge.getId(), deviceUpdateMsg); - String newDeviceName = deviceUpdateMsg.getName() + "_" + RandomStringUtils.randomAlphabetic(15); - device = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName); - ObjectNode body = mapper.createObjectNode(); - body.put("conflictName", deviceName); - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, device.getId(), body); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); } - futureToSet.set(null); } - - @Override - public void onFailure(Throwable t) { - log.error("[{}] Failed to get related edge ids by device id [{}], edge [{}]", tenantId, deviceUpdateMsg, edge.getId(), t); - futureToSet.setException(t); + Device newDevice; + if (update) { + log.info("[{}] Device with name '{}' already exists on the cloud, and related to this edge [{}]. " + + "deviceUpdateMsg [{}], Updating device", tenantId, deviceName, edge.getId(), deviceUpdateMsg); + updateDevice(tenantId, edge, deviceUpdateMsg); + } else { + log.info("[{}] Device with name '{}' already exists on the cloud, but not related to this edge [{}]. deviceUpdateMsg [{}]." + + "Creating a new device with random prefix and relate to this edge", tenantId, deviceName, edge.getId(), deviceUpdateMsg); + String newDeviceName = deviceUpdateMsg.getName() + "_" + RandomStringUtils.randomAlphabetic(15); + newDevice = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName); + ObjectNode body = mapper.createObjectNode(); + body.put("conflictName", deviceName); + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, newDevice.getId(), body); } - }, dbCallbackExecutorService); - return futureToSet; + } while (pageData != null && pageData.hasNext()); } else { log.info("[{}] Creating new device and replacing device entity on the edge [{}]", tenantId, deviceUpdateMsg); device = createDevice(tenantId, edge, deviceUpdateMsg, deviceUpdateMsg.getName()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EdgeProcessor.java index c9cd0f4019..c225fb9c60 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EdgeProcessor.java @@ -54,7 +54,7 @@ public class EdgeProcessor extends BaseEdgeProcessor { public void onSuccess(@Nullable Edge edge) { if (edge != null && !customerId.isNullUid()) { saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, customerId, null); - PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); PageData pageData; do { pageData = userService.findCustomerUsers(tenantId, customerId, pageLink); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java index 5bf2e77044..feb50ce750 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java @@ -93,63 +93,56 @@ public class EntityEdgeProcessor extends BaseEdgeProcessor { EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(type, new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); EdgeId edgeId = new EdgeId(new UUID(edgeNotificationMsg.getEdgeIdMSB(), edgeNotificationMsg.getEdgeIdLSB())); - ListenableFuture> edgeIdsFuture; + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); + PageData pageData; switch (actionType) { case ADDED: // used only for USER entity case UPDATED: case CREDENTIALS_UPDATED: - edgeIdsFuture = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId); - Futures.addCallback(edgeIdsFuture, new FutureCallback>() { - @Override - public void onSuccess(@Nullable List edgeIds) { - if (edgeIds != null && !edgeIds.isEmpty()) { - for (EdgeId edgeId : edgeIds) { - saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null); - } + do { + pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId, pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + for (EdgeId relatedEdgeId : pageData.getData()) { + saveEdgeEvent(tenantId, relatedEdgeId, type, actionType, entityId, null); + } + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); } } - @Override - public void onFailure(Throwable throwable) { - log.error("Failed to find related edge ids [{}]", edgeNotificationMsg, throwable); - } - }, dbCallbackExecutorService); + } while (pageData != null && pageData.hasNext()); break; case ASSIGNED_TO_CUSTOMER: case UNASSIGNED_FROM_CUSTOMER: - edgeIdsFuture = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId); - Futures.addCallback(edgeIdsFuture, new FutureCallback<>() { - @Override - public void onSuccess(@Nullable List edgeIds) { - if (edgeIds != null && !edgeIds.isEmpty()) { - for (EdgeId edgeId : edgeIds) { - try { - CustomerId customerId = mapper.readValue(edgeNotificationMsg.getBody(), CustomerId.class); - ListenableFuture future = edgeService.findEdgeByIdAsync(tenantId, edgeId); - Futures.addCallback(future, new FutureCallback() { - @Override - public void onSuccess(@Nullable Edge edge) { - if (edge != null && edge.getCustomerId() != null && - !edge.getCustomerId().isNullUid() && edge.getCustomerId().equals(customerId)) { - saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null); - } + do { + pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId, pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + for (EdgeId relatedEdgeId : pageData.getData()) { + try { + CustomerId customerId = mapper.readValue(edgeNotificationMsg.getBody(), CustomerId.class); + ListenableFuture future = edgeService.findEdgeByIdAsync(tenantId, relatedEdgeId); + Futures.addCallback(future, new FutureCallback<>() { + @Override + public void onSuccess(@Nullable Edge edge) { + if (edge != null && edge.getCustomerId() != null && + !edge.getCustomerId().isNullUid() && edge.getCustomerId().equals(customerId)) { + saveEdgeEvent(tenantId, relatedEdgeId, type, actionType, entityId, null); } - @Override - public void onFailure(Throwable throwable) { - log.error("Failed to find edge by id [{}]", edgeNotificationMsg, throwable); - } - }, dbCallbackExecutorService); - } catch (Exception e) { - log.error("Can't parse customer id from entity body [{}]", edgeNotificationMsg, e); - } + } + + @Override + public void onFailure(Throwable t) { + log.error("Failed to find edge by id [{}] {}", edgeNotificationMsg, t); + } + }, dbCallbackExecutorService); + } catch (Exception e) { + log.error("Can't parse customer id from entity body [{}]", edgeNotificationMsg, e); } } + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } } - - @Override - public void onFailure(Throwable throwable) { - log.error("Failed to find related edge ids [{}]", edgeNotificationMsg, throwable); - } - }, dbCallbackExecutorService); + } while (pageData != null && pageData.hasNext()); break; case DELETED: saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null); @@ -165,7 +158,7 @@ public class EntityEdgeProcessor extends BaseEdgeProcessor { } private void updateDependentRuleChains(TenantId tenantId, RuleChainId processingRuleChainId, EdgeId edgeId) { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); PageData pageData; do { pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edgeId, pageLink); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java index 190d58fcef..ddaf55a73b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java @@ -16,11 +16,9 @@ package org.thingsboard.server.service.edge.rpc.processor; import com.fasterxml.jackson.core.JsonProcessingException; -import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; -import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.edge.EdgeEvent; @@ -38,6 +36,8 @@ import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.gen.edge.DownlinkMsg; @@ -127,39 +127,35 @@ public class RelationEdgeProcessor extends BaseEdgeProcessor { EntityRelation relation = mapper.readValue(edgeNotificationMsg.getBody(), EntityRelation.class); if (!relation.getFrom().getEntityType().equals(EntityType.EDGE) && !relation.getTo().getEntityType().equals(EntityType.EDGE)) { - List>> futures = new ArrayList<>(); - futures.add(edgeService.findRelatedEdgeIdsByEntityId(tenantId, relation.getTo())); - futures.add(edgeService.findRelatedEdgeIdsByEntityId(tenantId, relation.getFrom())); - ListenableFuture>> combinedFuture = Futures.allAsList(futures); - Futures.addCallback(combinedFuture, new FutureCallback>>() { - @Override - public void onSuccess(@Nullable List> listOfListsEdgeIds) { - Set uniqueEdgeIds = new HashSet<>(); - if (listOfListsEdgeIds != null && !listOfListsEdgeIds.isEmpty()) { - for (List listOfListsEdgeId : listOfListsEdgeIds) { - if (listOfListsEdgeId != null) { - uniqueEdgeIds.addAll(listOfListsEdgeId); - } - } - } - if (!uniqueEdgeIds.isEmpty()) { - for (EdgeId edgeId : uniqueEdgeIds) { - saveEdgeEvent(tenantId, - edgeId, - EdgeEventType.RELATION, - EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()), - null, - mapper.valueToTree(relation)); - } - } + Set uniqueEdgeIds = new HashSet<>(); + uniqueEdgeIds.addAll(findRelatedEdgeIds(tenantId, relation.getTo())); + uniqueEdgeIds.addAll(findRelatedEdgeIds(tenantId, relation.getFrom())); + if (!uniqueEdgeIds.isEmpty()) { + for (EdgeId edgeId : uniqueEdgeIds) { + saveEdgeEvent(tenantId, + edgeId, + EdgeEventType.RELATION, + EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()), + null, + mapper.valueToTree(relation)); } + } + } + } - @Override - public void onFailure(Throwable t) { - log.warn("[{}] can't find related edge ids by relation to id [{}] and relation from id [{}]" , - tenantId.getId(), relation.getTo().getId(), relation.getFrom().getId(), t); + private List findRelatedEdgeIds(TenantId tenantId, EntityId entityId) { + List result = new ArrayList<>(); + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); + PageData pageData; + do { + pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId, pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + result.addAll(pageData.getData()); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); } - }, dbCallbackExecutorService); - } + } + } while (pageData != null && pageData.hasNext()); + return result; } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java index bccc6cedd0..bad62b0945 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java @@ -87,7 +87,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { private static final ObjectMapper mapper = new ObjectMapper(); - private static final int DEFAULT_LIMIT = 100; + private static final int DEFAULT_PAGE_SIZE = 1000; @Autowired private EdgeEventService edgeEventService; @@ -351,7 +351,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { List> futures = new ArrayList<>(); log.trace("[{}] syncDevices [{}][{}]", tenantId, edge.getName(), deviceType); try { - PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); PageData pageData; do { pageData = deviceService.findDevicesByTenantIdAndEdgeIdAndType(tenantId, edge.getId(), deviceType, pageLink); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java index a7b9145c01..93e1a0c51f 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java @@ -82,11 +82,9 @@ public interface EdgeService { void assignDefaultRuleChainsToEdge(TenantId tenantId, EdgeId edgeId); - ListenableFuture> findEdgesByTenantIdAndRuleChainId(TenantId tenantId, RuleChainId ruleChainId); + PageData findEdgesByTenantIdAndEntityId(TenantId tenantId, EntityId ruleChainId, PageLink pageLink); - ListenableFuture> findEdgesByTenantIdAndDashboardId(TenantId tenantId, DashboardId dashboardId); - - ListenableFuture> findRelatedEdgeIdsByEntityId(TenantId tenantId, EntityId entityId); + PageData findRelatedEdgeIdsByEntityId(TenantId tenantId, EntityId entityId, PageLink pageLink); Object checkInstance(Object request); diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeDao.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeDao.java index d254c5ee9a..49cbfce81c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeDao.java @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.edge; import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.EntitySubtype; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeInfo; import org.thingsboard.server.common.data.id.TenantId; @@ -160,20 +161,13 @@ public interface EdgeDao extends Dao { PageData findEdgeInfosByTenantId(UUID tenantId, PageLink pageLink); /** - * Find edges by tenantId and ruleChainId. + * Find edges by tenantId and entityId. * * @param tenantId the tenantId - * @param ruleChainId the ruleChainId - * @return the list of rule chain objects + * @param entityId the entityId + * @param entityType the entityType + * @return the list of edge objects */ - ListenableFuture> findEdgesByTenantIdAndRuleChainId(UUID tenantId, UUID ruleChainId); + PageData findEdgesByTenantIdAndEntityId(UUID tenantId, UUID entityId, EntityType entityType, PageLink pageLink); - /** - * Find edges by tenantId and dashboardId. - * - * @param tenantId the tenantId - * @param dashboardId the dashboardId - * @return the list of rule chain objects - */ - ListenableFuture> findEdgesByTenantIdAndDashboardId(UUID tenantId, UUID dashboardId); } \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index aee1fe7d34..b19733ff17 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -48,7 +48,6 @@ import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeInfo; import org.thingsboard.server.common.data.edge.EdgeSearchQuery; import org.thingsboard.server.common.data.id.CustomerId; -import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.IdBased; @@ -59,7 +58,6 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; -import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainConnectionInfo; import org.thingsboard.server.dao.customer.CustomerDao; @@ -106,7 +104,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic private static final ObjectMapper mapper = new ObjectMapper(); - private static final int DEFAULT_LIMIT = 100; + private static final int DEFAULT_PAGE_SIZE = 1000; private RestTemplate restTemplate; @@ -380,7 +378,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @Override public void assignDefaultRuleChainsToEdge(TenantId tenantId, EdgeId edgeId) { log.trace("Executing assignDefaultRuleChainsToEdge, tenantId [{}], edgeId [{}]", tenantId, edgeId); - PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); PageData pageData; do { pageData = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId, pageLink); @@ -396,19 +394,11 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic } @Override - public ListenableFuture> findEdgesByTenantIdAndRuleChainId(TenantId tenantId, RuleChainId ruleChainId) { - log.trace("Executing findEdgesByTenantIdAndRuleChainId, tenantId [{}], ruleChainId [{}]", tenantId, ruleChainId); + public PageData findEdgesByTenantIdAndEntityId(TenantId tenantId, EntityId entityId, PageLink pageLink) { + log.trace("Executing findEdgesByTenantIdAndEntityId, tenantId [{}], entityId [{}], pageLink [{}]", tenantId, entityId, pageLink); Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); - Validator.validateId(ruleChainId, "Incorrect ruleChainId " + ruleChainId); - return edgeDao.findEdgesByTenantIdAndRuleChainId(tenantId.getId(), ruleChainId.getId()); - } - - @Override - public ListenableFuture> findEdgesByTenantIdAndDashboardId(TenantId tenantId, DashboardId dashboardId) { - log.trace("Executing findEdgesByTenantIdAndDashboardId, tenantId [{}], dashboardId [{}]", tenantId, dashboardId); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); - Validator.validateId(dashboardId, "Incorrect dashboardId " + dashboardId); - return edgeDao.findEdgesByTenantIdAndDashboardId(tenantId.getId(), dashboardId.getId()); + validatePageLink(pageLink); + return edgeDao.findEdgesByTenantIdAndEntityId(tenantId.getId(), entityId.getId(), entityId.getEntityType(), pageLink); } private DataValidator edgeValidator = @@ -496,88 +486,55 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic }; @Override - public ListenableFuture> findRelatedEdgeIdsByEntityId(TenantId tenantId, EntityId entityId) { - // TODO: @voba - rewrite 'find' to use native SQL queries instead of fetching relations - - log.trace("[{}] Executing findRelatedEdgeIdsByEntityId [{}]", tenantId, entityId); + public PageData findRelatedEdgeIdsByEntityId(TenantId tenantId, EntityId entityId, PageLink pageLink) { + log.trace("[{}] Executing findRelatedEdgeIdsByEntityId [{}] [{}]", tenantId, entityId, pageLink); if (EntityType.TENANT.equals(entityId.getEntityType()) || EntityType.CUSTOMER.equals(entityId.getEntityType()) || EntityType.DEVICE_PROFILE.equals(entityId.getEntityType())) { - List result = new ArrayList<>(); - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - if (EntityType.TENANT.equals(entityId.getEntityType()) || - EntityType.DEVICE_PROFILE.equals(entityId.getEntityType())) { - pageData = findEdgesByTenantId(tenantId, pageLink); - } else { - pageData = findEdgesByTenantIdAndCustomerId(tenantId, new CustomerId(entityId.getId()), pageLink); - } - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - for (Edge edge : pageData.getData()) { - result.add(edge.getId()); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - return Futures.immediateFuture(result); + if (EntityType.TENANT.equals(entityId.getEntityType()) || + EntityType.DEVICE_PROFILE.equals(entityId.getEntityType())) { + return convertToEdgeIds(findEdgesByTenantId(tenantId, pageLink)); + } else { + return convertToEdgeIds(findEdgesByTenantIdAndCustomerId(tenantId, new CustomerId(entityId.getId()), pageLink)); + } } else { switch (entityId.getEntityType()) { case DEVICE: case ASSET: case ENTITY_VIEW: - ListenableFuture> originatorEdgeRelationsFuture = - relationService.findByToAndTypeAsync(tenantId, entityId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE); - return Futures.transform(originatorEdgeRelationsFuture, originatorEdgeRelations -> { - if (originatorEdgeRelations != null && originatorEdgeRelations.size() > 0 && - originatorEdgeRelations.get(0).getFrom() != null) { - return Collections.singletonList(new EdgeId(originatorEdgeRelations.get(0).getFrom().getId())); - } else { - return Collections.emptyList(); - } - }, MoreExecutors.directExecutor()); case DASHBOARD: - return convertToEdgeIds(findEdgesByTenantIdAndDashboardId(tenantId, new DashboardId(entityId.getId()))); case RULE_CHAIN: - return convertToEdgeIds(findEdgesByTenantIdAndRuleChainId(tenantId, new RuleChainId(entityId.getId()))); + return convertToEdgeIds(findEdgesByTenantIdAndEntityId(tenantId, entityId, pageLink)); case USER: User userById = userService.findUserById(tenantId, new UserId(entityId.getId())); if (userById == null) { - return Futures.immediateFuture(Collections.emptyList()); + return createEmptyEdgeIdPageData(); + } + if (userById.getCustomerId() == null || userById.getCustomerId().isNullUid()) { + return convertToEdgeIds(findEdgesByTenantId(tenantId, pageLink)); + } else { + return convertToEdgeIds(findEdgesByTenantIdAndCustomerId(tenantId, userById.getCustomerId(), pageLink)); } - List result = new ArrayList<>(); - PageLink pageLink = new PageLink(DEFAULT_LIMIT); - PageData pageData; - do { - if (userById.getCustomerId() == null || userById.getCustomerId().isNullUid()) { - pageData = findEdgesByTenantId(tenantId, pageLink); - } else { - pageData = findEdgesByTenantIdAndCustomerId(tenantId, userById.getCustomerId(), pageLink); - } - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - result.addAll(pageData.getData()); - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - return convertToEdgeIds(Futures.immediateFuture(result)); default: - return Futures.immediateFuture(Collections.emptyList()); + log.warn("[{}] Unsupported entity type {}", tenantId, entityId.getEntityType()); + return createEmptyEdgeIdPageData(); } } } - private ListenableFuture> convertToEdgeIds(ListenableFuture> future) { - return Futures.transform(future, edges -> { - if (edges != null && !edges.isEmpty()) { - return edges.stream().map(IdBased::getId).collect(Collectors.toList()); - } else { - return Collections.emptyList(); - } - }, MoreExecutors.directExecutor()); + private PageData createEmptyEdgeIdPageData() { + return new PageData<>(new ArrayList<>(), 0, 0, false); + } + + private PageData convertToEdgeIds(PageData pageData) { + if (pageData == null) { + return createEmptyEdgeIdPageData(); + } + List edgeIds = new ArrayList<>(); + if (pageData.getData() != null && !pageData.getData().isEmpty()) { + edgeIds = pageData.getData().stream().map(IdBased::getId).collect(Collectors.toList()); + } + return new PageData<>(edgeIds, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); } @Override @@ -625,7 +582,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic private List findEdgeRuleChains(TenantId tenantId, EdgeId edgeId) { List result = new ArrayList<>(); - PageLink pageLink = new PageLink(DEFAULT_LIMIT); + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); PageData pageData; do { pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edgeId, pageLink); diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java index 5da1d56181..4d2a299576 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java @@ -77,8 +77,8 @@ public abstract class AbstractEntityService { List entityViews = entityViewService.findEntityViewsByTenantIdAndEntityIdAsync(tenantId, entityId).get(); if (entityViews != null && !entityViews.isEmpty()) { EntityView entityView = entityViews.get(0); - // TODO: @voba - refactor this blocking operation in 3.3+ - Boolean relationExists = relationService.checkRelation(tenantId,edgeId, entityView.getId(), + // TODO: @voba - refactor this blocking operation + Boolean relationExists = relationService.checkRelation(tenantId, edgeId, entityView.getId(), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE).get(); if (relationExists) { throw new DataValidationException("Can't unassign device/asset from edge that is related to entity view and entity view is assigned to edge!"); diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 38eeab9546..2ead3f4334 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -66,7 +66,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; import static org.thingsboard.server.common.data.DataConstants.TENANT; @@ -375,18 +374,21 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC throw new DataValidationException("Deletion of Root Tenant Rule Chain is prohibited!"); } if (RuleChainType.EDGE.equals(ruleChain.getType())) { - try { - List edges = edgeService.findEdgesByTenantIdAndRuleChainId(tenantId, ruleChainId).get(); - if (edges != null && !edges.isEmpty()) { - for (Edge edge : edges) { + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); + PageData pageData; + do { + pageData = edgeService.findEdgesByTenantIdAndEntityId(tenantId, ruleChainId, pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + for (Edge edge : pageData.getData()) { if (edge.getRootRuleChainId() != null && edge.getRootRuleChainId().equals(ruleChainId)) { throw new DataValidationException("Can't delete rule chain that is root for edge [" + edge.getName() + "]. Please assign another root rule chain first to the edge!"); } } + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } } - } catch (InterruptedException | ExecutionException e) { - log.error("Can't get edges by tenant id [{}] and rule chain id [{}]", tenantId.getId(), ruleChainId.getId(), e); - } + } while (pageData != null && pageData.hasNext()); } } checkRuleNodesAndDelete(tenantId, ruleChainId); @@ -638,7 +640,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC } private void checkRuleNodesAndDelete(TenantId tenantId, RuleChainId ruleChainId) { - try{ + try { ruleChainDao.removeById(tenantId, ruleChainId.getId()); } catch (Exception t) { ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); @@ -673,7 +675,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override protected void validateCreate(TenantId tenantId, RuleChain data) { DefaultTenantProfileConfiguration profileConfiguration = - (DefaultTenantProfileConfiguration)tenantProfileCache.get(tenantId).getProfileData().getConfiguration(); + (DefaultTenantProfileConfiguration) tenantProfileCache.get(tenantId).getProfileData().getConfiguration(); long maxRuleChains = profileConfiguration.getMaxRuleChains(); validateNumberOfEntitiesPerTenant(tenantId, ruleChainDao, maxRuleChains, EntityType.RULE_CHAIN); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeRepository.java index a5216033b3..f12dda790d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeRepository.java @@ -22,6 +22,7 @@ import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; import org.thingsboard.server.dao.model.sql.EdgeEntity; import org.thingsboard.server.dao.model.sql.EdgeInfoEntity; +import org.thingsboard.server.dao.model.sql.RuleChainEntity; import java.util.List; import java.util.UUID; @@ -110,6 +111,16 @@ public interface EdgeRepository extends PagingAndSortingRepository findByTenantIdAndEntityId(@Param("tenantId") UUID tenantId, + @Param("entityId") UUID entityId, + @Param("entityType") String entityType, + @Param("searchText") String searchText, + Pageable pageable); + @Query("SELECT DISTINCT d.type FROM EdgeEntity d WHERE d.tenantId = :tenantId") List findTenantEdgeTypes(@Param("tenantId") UUID tenantId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaEdgeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaEdgeDao.java index f17196fe93..eec6ee7f29 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaEdgeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaEdgeDao.java @@ -26,13 +26,10 @@ import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeInfo; -import org.thingsboard.server.common.data.id.DashboardId; -import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.relation.EntityRelation; -import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.edge.EdgeDao; import org.thingsboard.server.dao.model.sql.EdgeEntity; @@ -181,17 +178,15 @@ public class JpaEdgeDao extends JpaAbstractSearchTextDao imple } @Override - public ListenableFuture> findEdgesByTenantIdAndRuleChainId(UUID tenantId, UUID ruleChainId) { - log.debug("Try to find edges by tenantId [{}], ruleChainId [{}]", tenantId, ruleChainId); - ListenableFuture> relations = relationDao.findAllByToAndType(new TenantId(tenantId), new RuleChainId(ruleChainId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE); - return transformFromRelationToEdge(tenantId, relations); - } - - @Override - public ListenableFuture> findEdgesByTenantIdAndDashboardId(UUID tenantId, UUID dashboardId) { - log.debug("Try to find edges by tenantId [{}], dashboardId [{}]", tenantId, dashboardId); - ListenableFuture> relations = relationDao.findAllByToAndType(new TenantId(tenantId), new DashboardId(dashboardId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE); - return transformFromRelationToEdge(tenantId, relations); + public PageData findEdgesByTenantIdAndEntityId(UUID tenantId, UUID entityId, EntityType entityType, PageLink pageLink) { + log.debug("Try to find edges by tenantId [{}], entityId [{}], entityType [{}], pageLink [{}]", tenantId, entityId, entityType, pageLink); + return DaoUtil.toPageData( + edgeRepository.findByTenantIdAndEntityId( + tenantId, + entityId, + entityType.name(), + Objects.toString(pageLink.getTextSearch(), ""), + DaoUtil.toPageable(pageLink))); } private ListenableFuture> transformFromRelationToEdge(UUID tenantId, ListenableFuture> relations) { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java index f208213d63..ce46ccffbf 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java @@ -15,7 +15,6 @@ */ package org.thingsboard.rule.engine.edge; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.FutureCallback; @@ -39,6 +38,8 @@ import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.msg.TbMsg; @@ -90,6 +91,8 @@ public class TbMsgPushToEdgeNode implements TbNode { private static final String SCOPE = "scope"; + private static final int DEFAULT_PAGE_SIZE = 1000; + @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { this.config = TbNodeUtils.convert(configuration, EmptyNodeConfiguration.class); @@ -117,77 +120,53 @@ public class TbMsgPushToEdgeNode implements TbNode { private void processMsg(TbContext ctx, TbMsg msg) { if (EntityType.EDGE.equals(msg.getOriginator().getEntityType())) { - try { - EdgeEvent edgeEvent = buildEdgeEvent(msg, ctx); - if (edgeEvent != null) { - EdgeId edgeId = new EdgeId(msg.getOriginator().getId()); - edgeEvent.setEdgeId(edgeId); - ListenableFuture saveFuture = ctx.getEdgeEventService().saveAsync(edgeEvent); - Futures.addCallback(saveFuture, new FutureCallback() { - @Override - public void onSuccess(@Nullable EdgeEvent event) { - ctx.tellNext(msg, SUCCESS); - ctx.onEdgeEventUpdate(ctx.getTenantId(), edgeId); - } - - @Override - public void onFailure(Throwable th) { - log.warn("[{}] Can't save edge event [{}] for edge [{}]", ctx.getTenantId().getId(), edgeEvent, edgeId.getId(), th); - ctx.tellFailure(msg, th); - } - }, ctx.getDbCallbackExecutor()); - } - } catch (JsonProcessingException e) { - log.error("Failed to build edge event", e); - ctx.tellFailure(msg, e); + EdgeEvent edgeEvent = buildEdgeEvent(msg, ctx); + if (edgeEvent != null) { + EdgeId edgeId = new EdgeId(msg.getOriginator().getId()); + notifyEdge(ctx, msg, edgeEvent, edgeId); } } else { - ListenableFuture> getEdgeIdsFuture = ctx.getEdgeService().findRelatedEdgeIdsByEntityId(ctx.getTenantId(), msg.getOriginator()); - Futures.addCallback(getEdgeIdsFuture, new FutureCallback>() { - @Override - public void onSuccess(@Nullable List edgeIds) { - if (edgeIds != null && !edgeIds.isEmpty()) { - for (EdgeId edgeId : edgeIds) { - try { - EdgeEvent edgeEvent = buildEdgeEvent(msg, ctx); - if (edgeEvent == null) { - log.debug("Edge event type is null. Entity Type {}", msg.getOriginator().getEntityType()); - ctx.tellFailure(msg, new RuntimeException("Edge event type is null. Entity Type '" + msg.getOriginator().getEntityType() + "'")); - } else { - edgeEvent.setEdgeId(edgeId); - ListenableFuture saveFuture = ctx.getEdgeEventService().saveAsync(edgeEvent); - Futures.addCallback(saveFuture, new FutureCallback() { - @Override - public void onSuccess(@Nullable EdgeEvent event) { - ctx.tellNext(msg, SUCCESS); - ctx.onEdgeEventUpdate(ctx.getTenantId(), edgeId); - } - - @Override - public void onFailure(Throwable th) { - log.warn("[{}] Can't save edge event [{}] for edge [{}]", ctx.getTenantId().getId(), edgeEvent, edgeId.getId(), th); - ctx.tellFailure(msg, th); - } - }, ctx.getDbCallbackExecutor()); - } - } catch (JsonProcessingException e) { - log.error("Failed to build edge event", e); - ctx.tellFailure(msg, e); - } + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); + PageData pageData; + do { + pageData = ctx.getEdgeService().findRelatedEdgeIdsByEntityId(ctx.getTenantId(), msg.getOriginator(), pageLink); + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { + for (EdgeId edgeId : pageData.getData()) { + EdgeEvent edgeEvent = buildEdgeEvent(msg, ctx); + if (edgeEvent == null) { + log.debug("Edge event type is null. Entity Type {}", msg.getOriginator().getEntityType()); + ctx.tellFailure(msg, new RuntimeException("Edge event type is null. Entity Type '" + msg.getOriginator().getEntityType() + "'")); + } else { + notifyEdge(ctx, msg, edgeEvent, edgeId); } } + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } } + } while (pageData != null && pageData.hasNext()); + } + } - @Override - public void onFailure(Throwable t) { - ctx.tellFailure(msg, t); - } + private void notifyEdge(TbContext ctx, TbMsg msg, EdgeEvent edgeEvent, EdgeId edgeId) { + edgeEvent.setEdgeId(edgeId); + ListenableFuture saveFuture = ctx.getEdgeEventService().saveAsync(edgeEvent); + Futures.addCallback(saveFuture, new FutureCallback() { + @Override + public void onSuccess(@Nullable EdgeEvent event) { + ctx.tellNext(msg, SUCCESS); + ctx.onEdgeEventUpdate(ctx.getTenantId(), edgeId); + } - }, ctx.getDbCallbackExecutor()); - } + @Override + public void onFailure(Throwable th) { + log.warn("[{}] Can't save edge event [{}] for edge [{}]", ctx.getTenantId().getId(), edgeEvent, edgeId.getId(), th); + ctx.tellFailure(msg, th); + } + }, ctx.getDbCallbackExecutor()); } - private EdgeEvent buildEdgeEvent(TbMsg msg, TbContext ctx) throws JsonProcessingException { + private EdgeEvent buildEdgeEvent(TbMsg msg, TbContext ctx) { String msgType = msg.getType(); if (DataConstants.ALARM.equals(msgType)) { return buildEdgeEvent(ctx.getTenantId(), EdgeEventActionType.ADDED, getUUIDFromMsgData(msg), EdgeEventType.ALARM, null); From 8e08ddcbca2f183c62dd5c07dc8d97dea81c8a41 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 25 May 2021 11:00:05 +0300 Subject: [PATCH 22/52] Return fast if entity is edge --- .../org/thingsboard/server/controller/BaseController.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 0543fdd47f..958b6c0261 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -147,6 +147,7 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; import javax.mail.MessagingException; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -1086,6 +1087,9 @@ public abstract class BaseController { if (!edgesEnabled) { return null; } + if (EntityType.EDGE.equals(entityId.getEntityType())) { + return Collections.singletonList(new EdgeId(entityId.getId())); + } List result = new ArrayList<>(); PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); PageData pageData; From 616c1df36fefb7c74d8e4898a1700305ec5b6d05 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 25 May 2021 13:52:55 +0300 Subject: [PATCH 23/52] Return edge id in case EDGE type --- .../java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index b19733ff17..3e828424d9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -499,6 +499,9 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic } } else { switch (entityId.getEntityType()) { + case EDGE: + List edgeIds = Collections.singletonList(new EdgeId(entityId.getId())); + return new PageData<>(edgeIds, 1, 1, false); case DEVICE: case ASSET: case ENTITY_VIEW: From 8b98b2e48f0b97dc537a905522a9b21d227f4153 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 27 May 2021 12:32:33 +0300 Subject: [PATCH 24/52] NullPointer exception fix --- .../thingsboard/server/service/edge/rpc/EdgeGrpcService.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index e9c93d0396..09df0f4a4a 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -28,7 +28,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Service; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; @@ -180,7 +179,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i @Override public void onEdgeEvent(TenantId tenantId, EdgeId edgeId) { log.trace("[{}] onEdgeEvent [{}]", tenantId, edgeId.getId()); - if (!sessionNewEvents.get(edgeId)) { + if (Boolean.FALSE.equals(sessionNewEvents.get(edgeId))) { log.trace("[{}] set session new events flag to true [{}]", tenantId, edgeId.getId()); sessionNewEvents.put(edgeId, true); } @@ -213,7 +212,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i if (sessions.containsKey(edgeId)) { ScheduledFuture schedule = scheduler.schedule(() -> { try { - if (sessionNewEvents.get(edgeId)) { + if (Boolean.TRUE.equals(sessionNewEvents.get(edgeId))) { log.trace("[{}] Set session new events flag to false", edgeId.getId()); sessionNewEvents.put(edgeId, false); session.processEdgeEvents(); From 9ac73768e82c0a496f912636c2147bbbe78517af Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 28 May 2021 15:34:54 +0300 Subject: [PATCH 25/52] Added rule chain controller and service get edge rule chains test --- .../BaseRuleChainControllerTest.java | 163 ++++++++++++++++++ .../sql/RuleChainControllerSqlTest.java | 23 +++ .../dao/service/BaseRuleChainServiceTest.java | 96 +++++++++++ 3 files changed, 282 insertions(+) create mode 100644 application/src/test/java/org/thingsboard/server/controller/BaseRuleChainControllerTest.java create mode 100644 application/src/test/java/org/thingsboard/server/controller/sql/RuleChainControllerSqlTest.java diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseRuleChainControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseRuleChainControllerTest.java new file mode 100644 index 0000000000..67addcd947 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/controller/BaseRuleChainControllerTest.java @@ -0,0 +1,163 @@ +/** + * Copyright © 2016-2021 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.controller; + +import com.fasterxml.jackson.core.type.TypeReference; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainType; +import org.thingsboard.server.common.data.security.Authority; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public abstract class BaseRuleChainControllerTest extends AbstractControllerTest { + + private IdComparator idComparator = new IdComparator<>(); + + private Tenant savedTenant; + private User tenantAdmin; + + @Before + public void beforeTest() throws Exception { + loginSysAdmin(); + + Tenant tenant = new Tenant(); + tenant.setTitle("My tenant"); + savedTenant = doPost("/api/tenant", tenant, Tenant.class); + Assert.assertNotNull(savedTenant); + + tenantAdmin = new User(); + tenantAdmin.setAuthority(Authority.TENANT_ADMIN); + tenantAdmin.setTenantId(savedTenant.getId()); + tenantAdmin.setEmail("tenant2@thingsboard.org"); + tenantAdmin.setFirstName("Joe"); + tenantAdmin.setLastName("Downs"); + + tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); + } + + @After + public void afterTest() throws Exception { + loginSysAdmin(); + + doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) + .andExpect(status().isOk()); + } + + @Test + public void testSaveRuleChain() throws Exception { + RuleChain ruleChain = new RuleChain(); + ruleChain.setName("RuleChain"); + RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); + Assert.assertNotNull(savedRuleChain); + Assert.assertNotNull(savedRuleChain.getId()); + Assert.assertTrue(savedRuleChain.getCreatedTime() > 0); + Assert.assertEquals(ruleChain.getName(), savedRuleChain.getName()); + savedRuleChain.setName("New RuleChain"); + doPost("/api/ruleChain", savedRuleChain, RuleChain.class); + RuleChain foundRuleChain = doGet("/api/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); + Assert.assertEquals(savedRuleChain.getName(), foundRuleChain.getName()); + } + + @Test + public void testFindRuleChainById() throws Exception { + RuleChain ruleChain = new RuleChain(); + ruleChain.setName("RuleChain"); + RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); + RuleChain foundRuleChain = doGet("/api/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); + Assert.assertNotNull(foundRuleChain); + Assert.assertEquals(savedRuleChain, foundRuleChain); + } + + @Test + public void testDeleteRuleChain() throws Exception { + RuleChain ruleChain = new RuleChain(); + ruleChain.setName("RuleChain"); + RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); + + doDelete("/api/ruleChain/" + savedRuleChain.getId().getId().toString()) + .andExpect(status().isOk()); + + doGet("/api/ruleChain/" + savedRuleChain.getId().getId().toString()) + .andExpect(status().isNotFound()); + } + + @Test + public void testFindEdgeRuleChainsByTenantIdAndName() throws Exception { + Edge edge = constructEdge("My edge", "default"); + Edge savedEdge = doPost("/api/edge", edge, Edge.class); + + List edgeRuleChains = new ArrayList<>(); + PageLink pageLink = new PageLink(17); + PageData pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId() + "/ruleChains?", + new TypeReference<>() {}, pageLink); + Assert.assertFalse(pageData.hasNext()); + Assert.assertEquals(1, pageData.getTotalElements()); + edgeRuleChains.addAll(pageData.getData()); + + for (int i = 0; i < 28; i++) { + RuleChain ruleChain = new RuleChain(); + ruleChain.setName("RuleChain " + i); + ruleChain.setType(RuleChainType.EDGE); + RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); + doPost("/api/edge/" + savedEdge.getId().getId().toString() + + "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); + edgeRuleChains.add(savedRuleChain); + } + + List loadedEdgeRuleChains = new ArrayList<>(); + pageLink = new PageLink(17); + do { + pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId() + "/ruleChains?", + new TypeReference<>() {}, pageLink); + loadedEdgeRuleChains.addAll(pageData.getData()); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } while (pageData.hasNext()); + + Collections.sort(edgeRuleChains, idComparator); + Collections.sort(loadedEdgeRuleChains, idComparator); + + Assert.assertEquals(edgeRuleChains, loadedEdgeRuleChains); + + for (RuleChain ruleChain : loadedEdgeRuleChains) { + if (!ruleChain.isRoot()) { + doDelete("/api/edge/" + savedEdge.getId().getId().toString() + + "/ruleChain/" + ruleChain.getId().getId().toString(), RuleChain.class); + } + } + + pageLink = new PageLink(17); + pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId() + "/ruleChains?", + new TypeReference<>() {}, pageLink); + Assert.assertFalse(pageData.hasNext()); + Assert.assertEquals(1, pageData.getTotalElements()); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/controller/sql/RuleChainControllerSqlTest.java b/application/src/test/java/org/thingsboard/server/controller/sql/RuleChainControllerSqlTest.java new file mode 100644 index 0000000000..bdc3e01de6 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/controller/sql/RuleChainControllerSqlTest.java @@ -0,0 +1,23 @@ +/** + * Copyright © 2016-2021 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.controller.sql; + +import org.thingsboard.server.controller.BaseRuleChainControllerTest; +import org.thingsboard.server.dao.service.DaoSqlTest; + +@DaoSqlTest +public class RuleChainControllerSqlTest extends BaseRuleChainControllerTest { +} diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java index 62df8c208d..b86afde0b7 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java @@ -23,6 +23,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -490,4 +491,99 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest { return ruleChainMetaData; } + + @Test + public void testFindEdgeRuleChainsByTenantIdAndName() { + Edge edge = constructEdge("My edge", "default"); + Edge savedEdge = edgeService.saveEdge(edge); + + String name1 = "Edge RuleChain name 1"; + List ruleChainsName1 = new ArrayList<>(); + for (int i = 0; i < 123; i++) { + RuleChain ruleChain = new RuleChain(); + ruleChain.setTenantId(tenantId); + String suffix = RandomStringUtils.randomAlphanumeric((int) (Math.random() * 17)); + String name = name1 + suffix; + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); + ruleChain.setName(name); + ruleChain.setType(RuleChainType.EDGE); + ruleChainsName1.add(ruleChainService.saveRuleChain(ruleChain)); + } + ruleChainsName1.forEach(ruleChain -> ruleChainService.assignRuleChainToEdge(tenantId, ruleChain.getId(), savedEdge.getId())); + + String name2 = "Edge RuleChain name 2"; + List ruleChainsName2 = new ArrayList<>(); + for (int i = 0; i < 193; i++) { + RuleChain ruleChain = new RuleChain(); + ruleChain.setTenantId(tenantId); + String suffix = RandomStringUtils.randomAlphanumeric((int) (Math.random() * 15)); + String name = name2 + suffix; + name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); + ruleChain.setName(name); + ruleChain.setType(RuleChainType.EDGE); + ruleChainsName2.add(ruleChainService.saveRuleChain(ruleChain)); + } + ruleChainsName2.forEach(ruleChain -> ruleChainService.assignRuleChainToEdge(tenantId, ruleChain.getId(), savedEdge.getId())); + + List loadedRuleChainsName1 = new ArrayList<>(); + PageLink pageLink = new PageLink(19, 0, name1); + PageData pageData = null; + do { + pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, savedEdge.getId(), pageLink); + loadedRuleChainsName1.addAll(pageData.getData()); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } while (pageData.hasNext()); + + Collections.sort(ruleChainsName1, idComparator); + Collections.sort(loadedRuleChainsName1, idComparator); + + Assert.assertEquals(ruleChainsName1, loadedRuleChainsName1); + + List loadedRuleChainsName2 = new ArrayList<>(); + pageLink = new PageLink(4, 0, name2); + do { + pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, savedEdge.getId(), pageLink); + loadedRuleChainsName2.addAll(pageData.getData()); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } while (pageData.hasNext()); + + Collections.sort(ruleChainsName2, idComparator); + Collections.sort(loadedRuleChainsName2, idComparator); + + Assert.assertEquals(ruleChainsName2, loadedRuleChainsName2); + + for (RuleChain ruleChain : loadedRuleChainsName1) { + ruleChainService.deleteRuleChainById(tenantId, ruleChain.getId()); + } + + pageLink = new PageLink(4, 0, name1); + pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, savedEdge.getId(), pageLink); + Assert.assertFalse(pageData.hasNext()); + Assert.assertEquals(0, pageData.getData().size()); + + for (RuleChain ruleChain : loadedRuleChainsName2) { + ruleChainService.deleteRuleChainById(tenantId, ruleChain.getId()); + } + + pageLink = new PageLink(4, 0, name2); + pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, savedEdge.getId(), pageLink); + Assert.assertFalse(pageData.hasNext()); + Assert.assertEquals(0, pageData.getData().size()); + } + + private Edge constructEdge(String name, String type) { + Edge edge = new Edge(); + edge.setTenantId(tenantId); + edge.setName(name); + edge.setType(type); + edge.setSecret(RandomStringUtils.randomAlphanumeric(20)); + edge.setRoutingKey(RandomStringUtils.randomAlphanumeric(20)); + edge.setEdgeLicenseKey(RandomStringUtils.randomAlphanumeric(20)); + edge.setCloudEndpoint("http://localhost:8080"); + return edge; + } } From 667d7ac517473751971b750f81d9cffe4ddfbe10 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 28 May 2021 18:20:51 +0300 Subject: [PATCH 26/52] Moved constuct edge method to parent --- .../server/dao/service/AbstractServiceTest.java | 13 +++++++++++++ .../dao/service/BaseRuleChainServiceTest.java | 14 +------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java index 091ab1741e..d36a728a8a 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.service; import com.datastax.oss.driver.api.core.uuid.Uuids; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.RandomStringUtils; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -36,6 +37,7 @@ import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; +import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; @@ -241,4 +243,15 @@ public abstract class AbstractServiceTest { return savedTenant.getId(); } + protected Edge constructEdge(TenantId tenantId, String name, String type) { + Edge edge = new Edge(); + edge.setTenantId(tenantId); + edge.setName(name); + edge.setType(type); + edge.setSecret(RandomStringUtils.randomAlphanumeric(20)); + edge.setRoutingKey(RandomStringUtils.randomAlphanumeric(20)); + edge.setEdgeLicenseKey(RandomStringUtils.randomAlphanumeric(20)); + edge.setCloudEndpoint("http://localhost:8080"); + return edge; + } } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java index b86afde0b7..f0e1f687be 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java @@ -494,7 +494,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest { @Test public void testFindEdgeRuleChainsByTenantIdAndName() { - Edge edge = constructEdge("My edge", "default"); + Edge edge = constructEdge(tenantId, "My edge", "default"); Edge savedEdge = edgeService.saveEdge(edge); String name1 = "Edge RuleChain name 1"; @@ -574,16 +574,4 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest { Assert.assertFalse(pageData.hasNext()); Assert.assertEquals(0, pageData.getData().size()); } - - private Edge constructEdge(String name, String type) { - Edge edge = new Edge(); - edge.setTenantId(tenantId); - edge.setName(name); - edge.setType(type); - edge.setSecret(RandomStringUtils.randomAlphanumeric(20)); - edge.setRoutingKey(RandomStringUtils.randomAlphanumeric(20)); - edge.setEdgeLicenseKey(RandomStringUtils.randomAlphanumeric(20)); - edge.setCloudEndpoint("http://localhost:8080"); - return edge; - } } From 3d1f0c61f76899824fa66bc8e698cfae0fd4668b Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 28 May 2021 18:57:14 +0300 Subject: [PATCH 27/52] Fixed compilation --- .../server/dao/service/BaseEdgeServiceTest.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeServiceTest.java index e123039cc5..1d8b6b6cb0 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeServiceTest.java @@ -583,18 +583,6 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { return constructEdge(tenantId, name, type); } - private Edge constructEdge(TenantId tenantId, String name, String type) { - Edge edge = new Edge(); - edge.setTenantId(tenantId); - edge.setName(name); - edge.setType(type); - edge.setSecret(RandomStringUtils.randomAlphanumeric(20)); - edge.setRoutingKey(RandomStringUtils.randomAlphanumeric(20)); - edge.setEdgeLicenseKey(RandomStringUtils.randomAlphanumeric(20)); - edge.setCloudEndpoint("http://localhost:8080"); - return edge; - } - @Test public void testCleanCacheIfEdgeRenamed() { String edgeNameBeforeRename = RandomStringUtils.randomAlphanumeric(15); From d79ab8880d8768d7392c3b6dbd657fe1fbe387c9 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 28 May 2021 20:01:12 +0300 Subject: [PATCH 28/52] Added scope to push to cloud and push to edge rule nodes configuration --- .../engine/edge/TbMsgPushToCloudNode.java | 7 ++-- .../TbMsgPushToCloudNodeConfiguration.java | 33 +++++++++++++++++++ .../rule/engine/edge/TbMsgPushToEdgeNode.java | 13 ++++---- .../TbMsgPushToEdgeNodeConfiguration.java | 33 +++++++++++++++++++ 4 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToCloudNodeConfiguration.java create mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNodeConfiguration.java diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToCloudNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToCloudNode.java index 0d6a62c4c1..0adc1e6cc9 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToCloudNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToCloudNode.java @@ -16,7 +16,6 @@ package org.thingsboard.rule.engine.edge; import lombok.extern.slf4j.Slf4j; -import org.thingsboard.rule.engine.api.EmptyNodeConfiguration; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNode; @@ -31,7 +30,7 @@ import org.thingsboard.server.common.msg.TbMsg; @RuleNode( type = ComponentType.ACTION, name = "push to cloud", - configClazz = EmptyNodeConfiguration.class, + configClazz = TbMsgPushToCloudNodeConfiguration.class, nodeDescription = "Pushes messages from edge to cloud", nodeDetails = "Push messages from edge to cloud. " + "This node used only on edge to push messages from edge to cloud. " + @@ -60,11 +59,11 @@ import org.thingsboard.server.common.msg.TbMsg; ) public class TbMsgPushToCloudNode implements TbNode { - private EmptyNodeConfiguration config; + private TbMsgPushToCloudNodeConfiguration config; @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { - this.config = TbNodeUtils.convert(configuration, EmptyNodeConfiguration.class); + this.config = TbNodeUtils.convert(configuration, TbMsgPushToCloudNodeConfiguration.class); } @Override diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToCloudNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToCloudNodeConfiguration.java new file mode 100644 index 0000000000..2bdd0d8a2f --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToCloudNodeConfiguration.java @@ -0,0 +1,33 @@ +/** + * Copyright © 2016-2021 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.rule.engine.edge; + +import lombok.Data; +import org.thingsboard.rule.engine.api.NodeConfiguration; +import org.thingsboard.server.common.data.DataConstants; + +@Data +public class TbMsgPushToCloudNodeConfiguration implements NodeConfiguration { + + private String scope; + + @Override + public TbMsgPushToCloudNodeConfiguration defaultConfiguration() { + TbMsgPushToCloudNodeConfiguration configuration = new TbMsgPushToCloudNodeConfiguration(); + configuration.setScope(DataConstants.SERVER_SCOPE); + return configuration; + } +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java index ce46ccffbf..c7f5415d02 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java @@ -23,7 +23,6 @@ import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.springframework.util.StringUtils; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.rule.engine.api.EmptyNodeConfiguration; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNode; @@ -57,7 +56,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; @RuleNode( type = ComponentType.ACTION, name = "push to edge", - configClazz = EmptyNodeConfiguration.class, + configClazz = TbMsgPushToEdgeNodeConfiguration.class, nodeDescription = "Push messages from cloud to edge", nodeDetails = "Push messages from cloud to edge. " + "Message originator must be assigned to particular edge or message originator is EDGE entity itself. " + @@ -87,7 +86,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; ) public class TbMsgPushToEdgeNode implements TbNode { - private EmptyNodeConfiguration config; + private TbMsgPushToEdgeNodeConfiguration config; private static final String SCOPE = "scope"; @@ -95,7 +94,7 @@ public class TbMsgPushToEdgeNode implements TbNode { @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { - this.config = TbNodeUtils.convert(configuration, EmptyNodeConfiguration.class); + this.config = TbNodeUtils.convert(configuration, TbMsgPushToEdgeNodeConfiguration.class); } @Override @@ -186,7 +185,8 @@ public class TbMsgPushToEdgeNode implements TbNode { entityBody.put(SCOPE, getScope(metadata)); break; case ATTRIBUTES_DELETED: - List keys = JacksonUtil.convertValue(dataJson.get("attributes"), new TypeReference<>() {}); + List keys = JacksonUtil.convertValue(dataJson.get("attributes"), new TypeReference<>() { + }); entityBody.put("keys", keys); entityBody.put(SCOPE, getScope(metadata)); break; @@ -202,8 +202,7 @@ public class TbMsgPushToEdgeNode implements TbNode { private String getScope(Map metadata) { String scope = metadata.get(SCOPE); if (StringUtils.isEmpty(scope)) { - // TODO: @voba - move this to configuration of the node UI or some other place - scope = DataConstants.SERVER_SCOPE; + scope = config.getScope(); } return scope; } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNodeConfiguration.java new file mode 100644 index 0000000000..75b0762cc7 --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNodeConfiguration.java @@ -0,0 +1,33 @@ +/** + * Copyright © 2016-2021 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.rule.engine.edge; + +import lombok.Data; +import org.thingsboard.rule.engine.api.NodeConfiguration; +import org.thingsboard.server.common.data.DataConstants; + +@Data +public class TbMsgPushToEdgeNodeConfiguration implements NodeConfiguration { + + private String scope; + + @Override + public TbMsgPushToEdgeNodeConfiguration defaultConfiguration() { + TbMsgPushToEdgeNodeConfiguration configuration = new TbMsgPushToEdgeNodeConfiguration(); + configuration.setScope(DataConstants.SERVER_SCOPE); + return configuration; + } +} From 7fa6cbd53f7f03305190562f7c1c88aebe6b3f82 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 1 Jun 2021 16:16:51 +0300 Subject: [PATCH 29/52] Resend only failed messages and not the entire pack --- .../service/edge/rpc/EdgeGrpcSession.java | 28 +++++++++++++++---- .../processor/AdminSettingsEdgeProcessor.java | 2 ++ .../rpc/processor/AlarmEdgeProcessor.java | 1 + .../rpc/processor/AssetEdgeProcessor.java | 3 ++ .../rpc/processor/CustomerEdgeProcessor.java | 3 ++ .../rpc/processor/DashboardEdgeProcessor.java | 3 ++ .../rpc/processor/DeviceEdgeProcessor.java | 7 ++++- .../processor/DeviceProfileEdgeProcessor.java | 3 ++ .../rpc/processor/EntityEdgeProcessor.java | 3 ++ .../processor/EntityViewEdgeProcessor.java | 3 ++ .../rpc/processor/RelationEdgeProcessor.java | 2 ++ .../rpc/processor/RuleChainEdgeProcessor.java | 4 +++ .../rpc/processor/TelemetryEdgeProcessor.java | 2 ++ .../edge/rpc/processor/UserEdgeProcessor.java | 4 +++ .../processor/WidgetBundleEdgeProcessor.java | 3 ++ .../processor/WidgetTypeEdgeProcessor.java | 3 ++ .../server/common/data/EdgeUtils.java | 6 ++++ common/edge-api/src/main/proto/edge.proto | 2 ++ 18 files changed, 75 insertions(+), 7 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index b7127d4ee2..f3626c0650 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -27,6 +27,7 @@ import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.Nullable; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; @@ -83,7 +84,9 @@ import org.thingsboard.server.service.edge.rpc.fetch.TenantWidgetsBundlesEdgeEve import java.io.Closeable; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.UUID; @@ -108,6 +111,8 @@ public final class EdgeGrpcSession implements Closeable { private final Consumer sessionCloseListener; private final ObjectMapper mapper; + private final Map pendingMsgsMap; + private EdgeContextComponent ctx; private Edge edge; private StreamObserver inputStream; @@ -128,6 +133,7 @@ public final class EdgeGrpcSession implements Closeable { this.sessionCloseListener = sessionCloseListener; this.mapper = mapper; this.syncExecutorService = syncExecutorService; + this.pendingMsgsMap = new HashMap<>(); initInputStream(); } @@ -214,6 +220,7 @@ public final class EdgeGrpcSession implements Closeable { startProcessingEdgeEvents(new DashboardsEdgeEventFetcher(ctx.getDashboardService())); DownlinkMsg syncCompleteDownlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .setSyncCompletedMsg(SyncCompletedMsg.newBuilder().build()) .build(); sendDownlinkMsgsPack(Collections.singletonList(syncCompleteDownlinkMsg)); @@ -228,7 +235,9 @@ public final class EdgeGrpcSession implements Closeable { Futures.addCallback(future, new FutureCallback<>() { @Override public void onSuccess(@Nullable List result) { - UplinkResponseMsg uplinkResponseMsg = UplinkResponseMsg.newBuilder().setSuccess(true).build(); + UplinkResponseMsg uplinkResponseMsg = UplinkResponseMsg.newBuilder() + .setUplinkMsgId(uplinkMsg.getUplinkMsgId()) + .setSuccess(true).build(); sendDownlinkMsg(ResponseMsg.newBuilder() .setUplinkResponseMsg(uplinkResponseMsg) .build()); @@ -236,7 +245,9 @@ public final class EdgeGrpcSession implements Closeable { @Override public void onFailure(Throwable t) { - UplinkResponseMsg uplinkResponseMsg = UplinkResponseMsg.newBuilder().setSuccess(false).setErrorMsg(t.getMessage()).build(); + UplinkResponseMsg uplinkResponseMsg = UplinkResponseMsg.newBuilder() + .setUplinkMsgId(uplinkMsg.getUplinkMsgId()) + .setSuccess(false).setErrorMsg(t.getMessage()).build(); sendDownlinkMsg(ResponseMsg.newBuilder() .setUplinkResponseMsg(uplinkResponseMsg) .build()); @@ -247,6 +258,7 @@ public final class EdgeGrpcSession implements Closeable { private void onDownlinkResponse(DownlinkResponseMsg msg) { try { if (msg.getSuccess()) { + pendingMsgsMap.remove(msg.getDownlinkMsgId()); log.debug("[{}] Msg has been processed successfully! {}", edge.getRoutingKey(), msg); } else { log.error("[{}] Msg processing failed! Error msg: {}", edge.getRoutingKey(), msg.getErrorMsg()); @@ -325,17 +337,19 @@ public final class EdgeGrpcSession implements Closeable { private boolean sendDownlinkMsgsPack(List downlinkMsgsPack) throws InterruptedException { boolean success; + pendingMsgsMap.clear(); + downlinkMsgsPack.forEach(msg -> pendingMsgsMap.put(msg.getDownlinkMsgId(), msg)); do { - log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, downlinkMsgsPack.size()); - latch = new CountDownLatch(downlinkMsgsPack.size()); - for (DownlinkMsg downlinkMsg : downlinkMsgsPack) { + log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, pendingMsgsMap.values().size()); + latch = new CountDownLatch(pendingMsgsMap.values().size()); + for (DownlinkMsg downlinkMsg : pendingMsgsMap.values()) { sendDownlinkMsg(ResponseMsg.newBuilder() .setDownlinkMsg(downlinkMsg) .build()); } success = latch.await(10, TimeUnit.SECONDS); if (!success) { - log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, downlinkMsgsPack); + log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, pendingMsgsMap.values()); } if (isConnected() && !success) { try { @@ -383,6 +397,8 @@ public final class EdgeGrpcSession implements Closeable { case RPC_CALL: downlinkMsg = ctx.getDeviceProcessor().processRpcCallMsgToEdge(edgeEvent); break; + default: + log.warn("[{}][{}] Unsupported action type [{}]", edge.getTenantId(), this.sessionId, edgeEvent.getAction()); } } catch (Exception e) { log.error("[{}][{}] Exception during converting edge event to downlink msg", edge.getTenantId(), this.sessionId, e); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java index e39b3eda4c..9eda3e3f81 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java @@ -18,6 +18,7 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.AdminSettings; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.gen.edge.AdminSettingsUpdateMsg; import org.thingsboard.server.gen.edge.DownlinkMsg; @@ -34,6 +35,7 @@ public class AdminSettingsEdgeProcessor extends BaseEdgeProcessor { AdminSettings adminSettings = mapper.convertValue(edgeEvent.getBody(), AdminSettings.class); AdminSettingsUpdateMsg t = adminSettingsMsgConstructor.constructAdminSettingsUpdateMsg(adminSettings); return DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllAdminSettingsUpdateMsg(Collections.singletonList(t)) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java index 5893840728..9113c39ff0 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java @@ -121,6 +121,7 @@ public class AlarmEdgeProcessor extends BaseEdgeProcessor { Alarm alarm = alarmService.findAlarmByIdAsync(edgeEvent.getTenantId(), alarmId).get(); if (alarm != null) { downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllAlarmUpdateMsg(Collections.singletonList(alarmMsgConstructor.constructAlarmUpdatedMsg(edge.getTenantId(), msgType, alarm))) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java index cf0180c85f..bd108e04e6 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; @@ -50,6 +51,7 @@ public class AssetEdgeProcessor extends BaseEdgeProcessor { AssetUpdateMsg assetUpdateMsg = assetMsgConstructor.constructAssetUpdatedMsg(msgType, asset, customerId); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllAssetUpdateMsg(Collections.singletonList(assetUpdateMsg)) .build(); } @@ -59,6 +61,7 @@ public class AssetEdgeProcessor extends BaseEdgeProcessor { AssetUpdateMsg assetUpdateMsg = assetMsgConstructor.constructAssetDeleteMsg(assetId); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllAssetUpdateMsg(Collections.singletonList(assetUpdateMsg)) .build(); break; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java index 00de4eb576..d8c1c00c2e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java @@ -18,6 +18,7 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; @@ -53,6 +54,7 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor { CustomerUpdateMsg customerUpdateMsg = customerMsgConstructor.constructCustomerUpdatedMsg(msgType, customer); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllCustomerUpdateMsg(Collections.singletonList(customerUpdateMsg)) .build(); } @@ -61,6 +63,7 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor { CustomerUpdateMsg customerUpdateMsg = customerMsgConstructor.constructCustomerDeleteMsg(customerId); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllCustomerUpdateMsg(Collections.singletonList(customerUpdateMsg)) .build(); break; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java index 730e928a2d..585298af03 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java @@ -18,6 +18,7 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Dashboard; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; @@ -53,6 +54,7 @@ public class DashboardEdgeProcessor extends BaseEdgeProcessor { DashboardUpdateMsg dashboardUpdateMsg = dashboardMsgConstructor.constructDashboardUpdatedMsg(msgType, dashboard, customerId); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllDashboardUpdateMsg(Collections.singletonList(dashboardUpdateMsg)) .build(); } @@ -62,6 +64,7 @@ public class DashboardEdgeProcessor extends BaseEdgeProcessor { DashboardUpdateMsg dashboardUpdateMsg = dashboardMsgConstructor.constructDashboardDeleteMsg(dashboardId); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllDashboardUpdateMsg(Collections.singletonList(dashboardUpdateMsg)) .build(); break; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java index f540186976..013e50482b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java @@ -24,10 +24,12 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.RpcError; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; @@ -48,7 +50,6 @@ import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; import org.thingsboard.server.gen.edge.DeviceUpdateMsg; @@ -308,6 +309,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { DeviceUpdateMsg deviceUpdateMsg = deviceMsgConstructor.constructDeviceUpdatedMsg(msgType, device, customerId, null); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg)) .build(); } @@ -317,6 +319,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { DeviceUpdateMsg deviceUpdateMsg = deviceMsgConstructor.constructDeviceDeleteMsg(deviceId); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg)) .build(); break; @@ -326,6 +329,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg = deviceMsgConstructor.constructDeviceCredentialsUpdatedMsg(deviceCredentials); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllDeviceCredentialsUpdateMsg(Collections.singletonList(deviceCredentialsUpdateMsg)) .build(); } @@ -339,6 +343,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { DeviceRpcCallMsg deviceRpcCallMsg = deviceMsgConstructor.constructDeviceRpcCallMsg(edgeEvent.getEntityId(), edgeEvent.getBody()); return DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllDeviceRpcCallMsg(Collections.singletonList(deviceRpcCallMsg)) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java index d66dc2b67c..a9bc4841df 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java @@ -18,6 +18,7 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -44,6 +45,7 @@ public class DeviceProfileEdgeProcessor extends BaseEdgeProcessor { DeviceProfileUpdateMsg deviceProfileUpdateMsg = deviceProfileMsgConstructor.constructDeviceProfileUpdatedMsg(msgType, deviceProfile); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllDeviceProfileUpdateMsg(Collections.singletonList(deviceProfileUpdateMsg)) .build(); } @@ -52,6 +54,7 @@ public class DeviceProfileEdgeProcessor extends BaseEdgeProcessor { DeviceProfileUpdateMsg deviceProfileUpdateMsg = deviceProfileMsgConstructor.constructDeviceProfileDeleteMsg(deviceProfileId); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllDeviceProfileUpdateMsg(Collections.singletonList(deviceProfileUpdateMsg)) .build(); break; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java index feb50ce750..b4a591e4cc 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java @@ -22,6 +22,7 @@ import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; @@ -66,6 +67,7 @@ public class EntityEdgeProcessor extends BaseEdgeProcessor { DeviceUpdateMsg d = deviceMsgConstructor .constructDeviceUpdatedMsg(UpdateMsgType.ENTITY_MERGE_RPC_MESSAGE, device, customerId, conflictName); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllDeviceUpdateMsg(Collections.singletonList(d)) .build(); } @@ -81,6 +83,7 @@ public class EntityEdgeProcessor extends BaseEdgeProcessor { .setDeviceIdLSB(deviceId.getId().getLeastSignificantBits()) .build(); DownlinkMsg.Builder builder = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllDeviceCredentialsRequestMsg(Collections.singletonList(deviceCredentialsRequestMsg)); downlinkMsg = builder.build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java index ab0e2e868f..77eebccb8d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; @@ -50,6 +51,7 @@ public class EntityViewEdgeProcessor extends BaseEdgeProcessor { EntityViewUpdateMsg entityViewUpdateMsg = entityViewMsgConstructor.constructEntityViewUpdatedMsg(msgType, entityView, customerId); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllEntityViewUpdateMsg(Collections.singletonList(entityViewUpdateMsg)) .build(); } @@ -59,6 +61,7 @@ public class EntityViewEdgeProcessor extends BaseEdgeProcessor { EntityViewUpdateMsg entityViewUpdateMsg = entityViewMsgConstructor.constructEntityViewDeleteMsg(entityViewId); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllEntityViewUpdateMsg(Collections.singletonList(entityViewUpdateMsg)) .build(); break; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java index ddaf55a73b..94b1c97968 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java @@ -20,6 +20,7 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; @@ -119,6 +120,7 @@ public class RelationEdgeProcessor extends BaseEdgeProcessor { EntityRelation entityRelation = mapper.convertValue(edgeEvent.getBody(), EntityRelation.class); RelationUpdateMsg r = relationMsgConstructor.constructRelationUpdatedMsg(msgType, entityRelation); return DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllRelationUpdateMsg(Collections.singletonList(r)) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java index 90fc8abe0e..6988c13892 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; @@ -48,6 +49,7 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor { RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainMsgConstructor.constructRuleChainUpdatedMsg(edge.getRootRuleChainId(), msgType, ruleChain); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllRuleChainUpdateMsg(Collections.singletonList(ruleChainUpdateMsg)) .build(); } @@ -55,6 +57,7 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor { case DELETED: case UNASSIGNED_FROM_EDGE: downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllRuleChainUpdateMsg(Collections.singletonList(ruleChainMsgConstructor.constructRuleChainDeleteMsg(ruleChainId))) .build(); break; @@ -72,6 +75,7 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor { ruleChainMsgConstructor.constructRuleChainMetadataUpdatedMsg(msgType, ruleChainMetaData); if (ruleChainMetadataUpdateMsg != null) { downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllRuleChainMetadataUpdateMsg(Collections.singletonList(ruleChainMetadataUpdateMsg)) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java index 419cd95179..008b20951c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java @@ -31,6 +31,7 @@ import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.asset.Asset; @@ -321,6 +322,7 @@ public class TelemetryEdgeProcessor extends BaseEdgeProcessor { private DownlinkMsg constructEntityDataProtoMsg(EntityId entityId, EdgeEventActionType actionType, JsonElement entityData) { EntityDataProto entityDataProto = entityDataMsgConstructor.constructEntityDataMsg(entityId, actionType, entityData); return DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllEntityData(Collections.singletonList(entityDataProto)) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java index 747d2ab4fd..175b601905 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; @@ -46,12 +47,14 @@ public class UserEdgeProcessor extends BaseEdgeProcessor { if (user != null) { CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(user, edge); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllUserUpdateMsg(Collections.singletonList(userMsgConstructor.constructUserUpdatedMsg(msgType, user, customerId))) .build(); } break; case DELETED: downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllUserUpdateMsg(Collections.singletonList(userMsgConstructor.constructUserDeleteMsg(userId))) .build(); break; @@ -61,6 +64,7 @@ public class UserEdgeProcessor extends BaseEdgeProcessor { UserCredentialsUpdateMsg userCredentialsUpdateMsg = userMsgConstructor.constructUserCredentialsUpdatedMsg(userCredentialsByUserId); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllUserCredentialsUpdateMsg(Collections.singletonList(userCredentialsUpdateMsg)) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java index 8c0d28226d..bc8f92b45b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.WidgetsBundleId; @@ -44,6 +45,7 @@ public class WidgetBundleEdgeProcessor extends BaseEdgeProcessor { WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = widgetsBundleMsgConstructor.constructWidgetsBundleUpdateMsg(msgType, widgetsBundle); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllWidgetsBundleUpdateMsg(Collections.singletonList(widgetsBundleUpdateMsg)) .build(); } @@ -52,6 +54,7 @@ public class WidgetBundleEdgeProcessor extends BaseEdgeProcessor { WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = widgetsBundleMsgConstructor.constructWidgetsBundleDeleteMsg(widgetsBundleId); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllWidgetsBundleUpdateMsg(Collections.singletonList(widgetsBundleUpdateMsg)) .build(); break; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java index 891b224a6e..dcf2c447bb 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.edge.rpc.processor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.WidgetTypeId; @@ -44,6 +45,7 @@ public class WidgetTypeEdgeProcessor extends BaseEdgeProcessor { WidgetTypeUpdateMsg widgetTypeUpdateMsg = widgetTypeMsgConstructor.constructWidgetTypeUpdateMsg(msgType, widgetType); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllWidgetTypeUpdateMsg(Collections.singletonList(widgetTypeUpdateMsg)) .build(); } @@ -52,6 +54,7 @@ public class WidgetTypeEdgeProcessor extends BaseEdgeProcessor { WidgetTypeUpdateMsg widgetTypeUpdateMsg = widgetTypeMsgConstructor.constructWidgetTypeDeleteMsg(widgetTypeId); downlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addAllWidgetTypeUpdateMsg(Collections.singletonList(widgetTypeUpdateMsg)) .build(); break; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EdgeUtils.java b/common/data/src/main/java/org/thingsboard/server/common/data/EdgeUtils.java index 8b78bcab3a..de8e7e0308 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EdgeUtils.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EdgeUtils.java @@ -18,6 +18,8 @@ package org.thingsboard.server.common.data; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.edge.EdgeEventType; +import java.util.concurrent.ThreadLocalRandom; + @Slf4j public final class EdgeUtils { @@ -57,4 +59,8 @@ public final class EdgeUtils { return null; } } + + public static int nextPositiveInt() { + return ThreadLocalRandom.current().nextInt(0, Integer.MAX_VALUE); + } } diff --git a/common/edge-api/src/main/proto/edge.proto b/common/edge-api/src/main/proto/edge.proto index a630e64066..ea6b47defb 100644 --- a/common/edge-api/src/main/proto/edge.proto +++ b/common/edge-api/src/main/proto/edge.proto @@ -434,11 +434,13 @@ message UplinkMsg { message UplinkResponseMsg { bool success = 1; string errorMsg = 2; + int32 uplinkMsgId = 3; } message DownlinkResponseMsg { bool success = 1; string errorMsg = 2; + int32 downlinkMsgId = 3; } message DownlinkMsg { From 046578130367beea95261c58d1cfd75d952bb164 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 1 Jun 2021 18:53:39 +0300 Subject: [PATCH 30/52] Updated edge root rule chain. Fixed handling of failed rpc messages --- .../rule_chains/edge_root_rule_chain.json | 15 +++-- .../rule_chains/edge_root_rule_chain.json | 15 +++-- .../service/edge/rpc/EdgeGrpcSession.java | 59 +++++++++++-------- .../service/install/InstallScripts.java | 1 + 4 files changed, 55 insertions(+), 35 deletions(-) diff --git a/application/src/main/data/json/demo/edge_management/rule_chains/edge_root_rule_chain.json b/application/src/main/data/json/demo/edge_management/rule_chains/edge_root_rule_chain.json index 740d64627e..a065279cce 100644 --- a/application/src/main/data/json/demo/edge_management/rule_chains/edge_root_rule_chain.json +++ b/application/src/main/data/json/demo/edge_management/rule_chains/edge_root_rule_chain.json @@ -14,8 +14,8 @@ { "additionalInfo": { "description": "Process incoming messages from devices with the alarm rules defined in the device profile. Dispatch all incoming messages with \"Success\" relation type.", - "layoutX": 203, - "layoutY": 259 + "layoutX": 187, + "layoutY": 468 }, "type": "org.thingsboard.rule.engine.profile.TbDeviceProfileNode", "name": "Device Profile Node", @@ -99,14 +99,14 @@ }, { "additionalInfo": { - "layoutX": 1134, - "layoutY": 132 + "layoutX": 1129, + "layoutY": 52 }, "type": "org.thingsboard.rule.engine.edge.TbMsgPushToCloudNode", "name": "Push to cloud", "debugMode": false, "configuration": { - "version": 0 + "scope": "SERVER_SCOPE" } } ], @@ -151,6 +151,11 @@ "toIndex": 4, "type": "RPC Request from Device" }, + { + "fromIndex": 3, + "toIndex": 7, + "type": "Attributes Updated" + }, { "fromIndex": 4, "toIndex": 7, diff --git a/application/src/main/data/json/tenant/edge_management/rule_chains/edge_root_rule_chain.json b/application/src/main/data/json/tenant/edge_management/rule_chains/edge_root_rule_chain.json index 740d64627e..a065279cce 100644 --- a/application/src/main/data/json/tenant/edge_management/rule_chains/edge_root_rule_chain.json +++ b/application/src/main/data/json/tenant/edge_management/rule_chains/edge_root_rule_chain.json @@ -14,8 +14,8 @@ { "additionalInfo": { "description": "Process incoming messages from devices with the alarm rules defined in the device profile. Dispatch all incoming messages with \"Success\" relation type.", - "layoutX": 203, - "layoutY": 259 + "layoutX": 187, + "layoutY": 468 }, "type": "org.thingsboard.rule.engine.profile.TbDeviceProfileNode", "name": "Device Profile Node", @@ -99,14 +99,14 @@ }, { "additionalInfo": { - "layoutX": 1134, - "layoutY": 132 + "layoutX": 1129, + "layoutY": 52 }, "type": "org.thingsboard.rule.engine.edge.TbMsgPushToCloudNode", "name": "Push to cloud", "debugMode": false, "configuration": { - "version": 0 + "scope": "SERVER_SCOPE" } } ], @@ -151,6 +151,11 @@ "toIndex": 4, "type": "RPC Request from Device" }, + { + "fromIndex": 3, + "toIndex": 7, + "type": "Attributes Updated" + }, { "fromIndex": 4, "toIndex": 7, diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index f3626c0650..15f591694a 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -83,8 +83,10 @@ import org.thingsboard.server.service.edge.rpc.fetch.TenantWidgetsBundlesEdgeEve import java.io.Closeable; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -103,6 +105,7 @@ import java.util.stream.Collectors; public final class EdgeGrpcSession implements Closeable { private static final ReentrantLock downlinkMsgLock = new ReentrantLock(); + private static final ReentrantLock downlinkMsgsPackLock = new ReentrantLock(); private static final String QUEUE_START_TS_ATTR_KEY = "queueStartTs"; @@ -111,7 +114,7 @@ public final class EdgeGrpcSession implements Closeable { private final Consumer sessionCloseListener; private final ObjectMapper mapper; - private final Map pendingMsgsMap; + private final Map pendingMsgsMap = new HashMap<>(); private EdgeContextComponent ctx; private Edge edge; @@ -133,7 +136,6 @@ public final class EdgeGrpcSession implements Closeable { this.sessionCloseListener = sessionCloseListener; this.mapper = mapper; this.syncExecutorService = syncExecutorService; - this.pendingMsgsMap = new HashMap<>(); initInputStream(); } @@ -197,6 +199,7 @@ public final class EdgeGrpcSession implements Closeable { public void startSyncProcess(TenantId tenantId, EdgeId edgeId) { log.trace("[{}][{}] Staring edge sync process", tenantId, edgeId); + syncCompleted = false; syncExecutorService.submit(() -> { try { startProcessingEdgeEvents(new SystemWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService())); @@ -336,30 +339,36 @@ public final class EdgeGrpcSession implements Closeable { } private boolean sendDownlinkMsgsPack(List downlinkMsgsPack) throws InterruptedException { - boolean success; - pendingMsgsMap.clear(); - downlinkMsgsPack.forEach(msg -> pendingMsgsMap.put(msg.getDownlinkMsgId(), msg)); - do { - log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, pendingMsgsMap.values().size()); - latch = new CountDownLatch(pendingMsgsMap.values().size()); - for (DownlinkMsg downlinkMsg : pendingMsgsMap.values()) { - sendDownlinkMsg(ResponseMsg.newBuilder() - .setDownlinkMsg(downlinkMsg) - .build()); - } - success = latch.await(10, TimeUnit.SECONDS); - if (!success) { - log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, pendingMsgsMap.values()); - } - if (isConnected() && !success) { - try { - Thread.sleep(ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches()); - } catch (InterruptedException e) { - log.error("[{}] Error during sleep between next send of single downlink msg", this.sessionId, e); + try { + downlinkMsgsPackLock.lock(); + boolean success; + pendingMsgsMap.clear(); + downlinkMsgsPack.forEach(msg -> pendingMsgsMap.put(msg.getDownlinkMsgId(), msg)); + do { + log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, pendingMsgsMap.values().size()); + latch = new CountDownLatch(pendingMsgsMap.values().size()); + Collection copy = new ArrayList<>(pendingMsgsMap.values()); + for (DownlinkMsg downlinkMsg : copy) { + sendDownlinkMsg(ResponseMsg.newBuilder() + .setDownlinkMsg(downlinkMsg) + .build()); } - } - } while (isConnected() && !success); - return success; + success = latch.await(10, TimeUnit.SECONDS); + if (!success || pendingMsgsMap.values().size() > 0) { + log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, pendingMsgsMap.values()); + } + if (isConnected() && (!success || pendingMsgsMap.values().size() > 0)) { + try { + Thread.sleep(ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches()); + } catch (InterruptedException e) { + log.error("[{}] Error during sleep between batches", this.sessionId, e); + } + } + } while (isConnected() && (!success || pendingMsgsMap.values().size() > 0)); + return success; + } finally { + downlinkMsgsPackLock.unlock(); + } } private DownlinkMsg convertToDownlinkMsg(EdgeEvent edgeEvent) { diff --git a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java index 909c2a3b03..bf71f94847 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java +++ b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java @@ -232,6 +232,7 @@ public class InstallScripts { try { createDefaultRuleChains(tenantId); createDefaultRuleChain(tenantId, "Thermostat"); + createDefaultEdgeRuleChains(tenantId); } catch (Exception e) { log.error("Unable to load dashboard from json", e); throw new RuntimeException("Unable to load dashboard from json", e); From ea8e55dbabd9c6840a4d8e4d09a8d285b2e0bae5 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 2 Jun 2021 11:24:19 +0300 Subject: [PATCH 31/52] Set downlink msg id in the response msg --- .../thingsboard/server/edge/imitator/EdgeImitator.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index c903913fe3..864f2e6a52 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -136,7 +136,9 @@ public class EdgeImitator { @Override public void onSuccess(@Nullable List result) { if (connected) { - DownlinkResponseMsg downlinkResponseMsg = DownlinkResponseMsg.newBuilder().setSuccess(true).build(); + DownlinkResponseMsg downlinkResponseMsg = DownlinkResponseMsg.newBuilder() + .setDownlinkMsgId(downlinkMsg.getDownlinkMsgId()) + .setSuccess(true).build(); edgeRpcClient.sendDownlinkResponseMsg(downlinkResponseMsg); } } @@ -144,7 +146,9 @@ public class EdgeImitator { @Override public void onFailure(Throwable t) { if (connected) { - DownlinkResponseMsg downlinkResponseMsg = DownlinkResponseMsg.newBuilder().setSuccess(false).setErrorMsg(t.getMessage()).build(); + DownlinkResponseMsg downlinkResponseMsg = DownlinkResponseMsg.newBuilder() + .setDownlinkMsgId(downlinkMsg.getDownlinkMsgId()) + .setSuccess(false).setErrorMsg(t.getMessage()).build(); edgeRpcClient.sendDownlinkResponseMsg(downlinkResponseMsg); } } From 86fb9f076a0612dda52715d17944e7bb9af5203b Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 2 Jun 2021 21:57:51 +0300 Subject: [PATCH 32/52] Added test to validate timeseries with failures on downlinks --- .../thingsboard/server/edge/BaseEdgeTest.java | 55 ++++++++++++++++++- .../server/edge/imitator/EdgeImitator.java | 27 +++++++-- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java index c255ce93ea..a7a1282dc0 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -173,6 +173,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { edgeImitator = new EdgeImitator("localhost", 7070, edge.getRoutingKey(), edge.getSecret()); edgeImitator.expectMessageAmount(9); edgeImitator.connect(); + + testReceivedInitialData(); } @After @@ -188,9 +190,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { } @Test - public void test() throws Exception { - testReceivedInitialData(); - + public void generalTest() throws Exception { testDevices(); testAssets(); @@ -218,6 +218,55 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { testRpcCall(); } + @Test + public void testTimeseriesWithFailures() throws Exception { + log.info("Testing timeseries with failures"); + + int numberOfTimeseriesToSend = 1000; + + edgeImitator.setRandomFailuresOnTimeseriesDownlink(true); + // imitator will generate failure in 5% of cases + edgeImitator.setFailureProbability(5.0); + + edgeImitator.expectMessageAmount(numberOfTimeseriesToSend); + Device device = findDeviceByName("Edge Device 1"); + for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { + String timeseriesData = "{\"data\":{\"idx\":" + idx + "},\"ts\":" + System.currentTimeMillis() + "}"; + JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, + device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); + edgeEventService.saveAsync(edgeEvent); + clusterService.onEdgeEventUpdate(tenantId, edge.getId()); + } + + Assert.assertTrue(edgeImitator.waitForMessages(60)); + + List allTelemetryMsgs = edgeImitator.findAllMessagesByType(EntityDataProto.class); + Assert.assertEquals(numberOfTimeseriesToSend, allTelemetryMsgs.size()); + + for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { + Assert.assertTrue(isIdxExistsInTheDownlinkList(idx, allTelemetryMsgs)); + } + + edgeImitator.setRandomFailuresOnTimeseriesDownlink(false); + log.info("Timeseries with failures tested successfully"); + } + + private boolean isIdxExistsInTheDownlinkList(int idx, List allTelemetryMsgs) { + for (EntityDataProto proto : allTelemetryMsgs) { + TransportProtos.PostTelemetryMsg postTelemetryMsg = proto.getPostTelemetryMsg(); + Assert.assertEquals(1, postTelemetryMsg.getTsKvListCount()); + TransportProtos.TsKvListProto tsKvListProto = postTelemetryMsg.getTsKvList(0); + Assert.assertEquals(1, tsKvListProto.getKvCount()); + TransportProtos.KeyValueProto keyValueProto = tsKvListProto.getKv(0); + Assert.assertEquals("idx", keyValueProto.getKey()); + if (keyValueProto.getLongV() == idx) { + return true; + } + } + return false; + } + private Device findDeviceByName(String deviceName) throws Exception { List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", new TypeReference>() { diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index 864f2e6a52..4988f7d1cf 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -21,11 +21,11 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.AbstractMessage; import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.Nullable; import org.thingsboard.edge.rpc.EdgeGrpcClient; import org.thingsboard.edge.rpc.EdgeRpcClient; -import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.gen.edge.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.AssetUpdateMsg; import org.thingsboard.server.gen.edge.CustomerUpdateMsg; @@ -55,6 +55,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -74,6 +75,11 @@ public class EdgeImitator { private CountDownLatch responsesLatch; private List> ignoredTypes; + @Setter + private boolean randomFailuresOnTimeseriesDownlink = false; + @Setter + private double failureProbability = 0.0; + @Getter private EdgeConfiguration configuration; @Getter @@ -208,7 +214,15 @@ public class EdgeImitator { } if (downlinkMsg.getEntityDataCount() > 0) { for (EntityDataProto entityData : downlinkMsg.getEntityDataList()) { - result.add(saveDownlinkMsg(entityData)); + if (randomFailuresOnTimeseriesDownlink) { + if (getRandomBoolean()) { + result.add(Futures.immediateFailedFuture(new RuntimeException("Random failure"))); + } else { + result.add(saveDownlinkMsg(entityData)); + } + } else { + result.add(saveDownlinkMsg(entityData)); + } } } if (downlinkMsg.getEntityViewUpdateMsgCount() > 0) { @@ -254,6 +268,11 @@ public class EdgeImitator { return Futures.allAsList(result); } + private boolean getRandomBoolean() { + double randomValue = ThreadLocalRandom.current().nextDouble() * 100; + return randomValue <= this.failureProbability; + } + private ListenableFuture saveDownlinkMsg(AbstractMessage message) { if (!ignoredTypes.contains(message.getClass())) { try { @@ -271,8 +290,8 @@ public class EdgeImitator { return waitForMessages(5); } - public boolean waitForMessages(int timeout) throws InterruptedException { - return messagesLatch.await(timeout, TimeUnit.SECONDS); + public boolean waitForMessages(int timeoutInSeconds) throws InterruptedException { + return messagesLatch.await(timeoutInSeconds, TimeUnit.SECONDS); } public void expectMessageAmount(int messageAmount) { From b4b6f7eb55721c761eb3e31a623c551dfa5f47e5 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 3 Jun 2021 21:19:52 +0300 Subject: [PATCH 33/52] Decreased execution time of test --- .../thingsboard/server/edge/BaseEdgeTest.java | 749 +++++++++--------- .../resources/application-test.properties | 2 + 2 files changed, 379 insertions(+), 372 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java index a7a1282dc0..a50c2b4bc1 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -166,7 +166,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { // sleep 1 seconds to avoid CREDENTIALS updated message for the user // user credentials is going to be stored and updated event pushed to edge notification service // while service will be processing this event edge could be already added and additional message will be pushed - Thread.sleep(1000); + Thread.sleep(500); installation(); @@ -177,6 +177,22 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { testReceivedInitialData(); } + private void installation() throws Exception { + edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); + + DeviceProfile deviceProfile = this.createDeviceProfile(CUSTOM_DEVICE_PROFILE_NAME, null); + extendDeviceProfileData(deviceProfile); + doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); + + Device savedDevice = saveDevice("Edge Device 1", CUSTOM_DEVICE_PROFILE_NAME); + doPost("/api/edge/" + edge.getId().getId().toString() + + "/device/" + savedDevice.getId().getId().toString(), Device.class); + + Asset savedAsset = saveAsset("Edge Asset 1"); + doPost("/api/edge/" + edge.getId().getId().toString() + + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); + } + @After public void afterTest() throws Exception { try { @@ -190,7 +206,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { } @Test - public void generalTest() throws Exception { + public void test() throws Exception { testDevices(); testAssets(); @@ -216,179 +232,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { testSendMessagesToCloud(); testRpcCall(); - } - - @Test - public void testTimeseriesWithFailures() throws Exception { - log.info("Testing timeseries with failures"); - - int numberOfTimeseriesToSend = 1000; - - edgeImitator.setRandomFailuresOnTimeseriesDownlink(true); - // imitator will generate failure in 5% of cases - edgeImitator.setFailureProbability(5.0); - - edgeImitator.expectMessageAmount(numberOfTimeseriesToSend); - Device device = findDeviceByName("Edge Device 1"); - for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { - String timeseriesData = "{\"data\":{\"idx\":" + idx + "},\"ts\":" + System.currentTimeMillis() + "}"; - JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); - EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, - device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); - edgeEventService.saveAsync(edgeEvent); - clusterService.onEdgeEventUpdate(tenantId, edge.getId()); - } - Assert.assertTrue(edgeImitator.waitForMessages(60)); - - List allTelemetryMsgs = edgeImitator.findAllMessagesByType(EntityDataProto.class); - Assert.assertEquals(numberOfTimeseriesToSend, allTelemetryMsgs.size()); - - for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { - Assert.assertTrue(isIdxExistsInTheDownlinkList(idx, allTelemetryMsgs)); - } - - edgeImitator.setRandomFailuresOnTimeseriesDownlink(false); - log.info("Timeseries with failures tested successfully"); - } - - private boolean isIdxExistsInTheDownlinkList(int idx, List allTelemetryMsgs) { - for (EntityDataProto proto : allTelemetryMsgs) { - TransportProtos.PostTelemetryMsg postTelemetryMsg = proto.getPostTelemetryMsg(); - Assert.assertEquals(1, postTelemetryMsg.getTsKvListCount()); - TransportProtos.TsKvListProto tsKvListProto = postTelemetryMsg.getTsKvList(0); - Assert.assertEquals(1, tsKvListProto.getKvCount()); - TransportProtos.KeyValueProto keyValueProto = tsKvListProto.getKv(0); - Assert.assertEquals("idx", keyValueProto.getKey()); - if (keyValueProto.getLongV() == idx) { - return true; - } - } - return false; - } - - private Device findDeviceByName(String deviceName) throws Exception { - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() { - }, new PageLink(100)).getData(); - Optional foundDevice = edgeDevices.stream().filter(d -> d.getName().equals(deviceName)).findAny(); - Assert.assertTrue(foundDevice.isPresent()); - Device device = foundDevice.get(); - Assert.assertEquals(deviceName, device.getName()); - return device; - } - - private Asset findAssetByName(String assetName) throws Exception { - List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", - new TypeReference>() { - }, new PageLink(100)).getData(); - - Assert.assertEquals(1, edgeAssets.size()); - Asset asset = edgeAssets.get(0); - Assert.assertEquals(assetName, asset.getName()); - return asset; - } - - private Device saveDevice(String deviceName, String type) throws Exception { - Device device = new Device(); - device.setName(deviceName); - device.setType(type); - return doPost("/api/device", device, Device.class); - } - - private Asset saveAsset(String assetName) throws Exception { - Asset asset = new Asset(); - asset.setName(assetName); - asset.setType("test"); - return doPost("/api/asset", asset, Asset.class); - } - - private void testRpcCall() throws Exception { - Device device = findDeviceByName("Edge Device 1"); - - ObjectNode body = mapper.createObjectNode(); - body.put("requestId", new Random().nextInt()); - body.put("requestUUID", Uuids.timeBased().toString()); - body.put("oneway", false); - body.put("expirationTime", System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10)); - body.put("method", "test_method"); - body.put("params", "{\"param1\":\"value1\"}"); - - EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.RPC_CALL, device.getId().getId(), EdgeEventType.DEVICE, body); - edgeImitator.expectMessageAmount(1); - edgeEventService.saveAsync(edgeEvent); - clusterService.onEdgeEventUpdate(tenantId, edge.getId()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceRpcCallMsg); - DeviceRpcCallMsg latestDeviceRpcCallMsg = (DeviceRpcCallMsg) latestMessage; - Assert.assertEquals("test_method", latestDeviceRpcCallMsg.getRequestMsg().getMethod()); - } - - private void testReceivedInitialData() throws Exception { - log.info("Checking received data"); - Assert.assertTrue(edgeImitator.waitForMessages()); - - EdgeConfiguration configuration = edgeImitator.getConfiguration(); - Assert.assertNotNull(configuration); - - testAutoGeneratedCodeByProtobuf(configuration); - - Optional deviceUpdateMsgOpt = edgeImitator.findMessageByType(DeviceUpdateMsg.class); - Assert.assertTrue(deviceUpdateMsgOpt.isPresent()); - DeviceUpdateMsg deviceUpdateMsg = deviceUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); - UUID deviceUUID = new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()); - Device device = doGet("/api/device/" + deviceUUID.toString(), Device.class); - Assert.assertNotNull(device); - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertTrue(edgeDevices.contains(device)); - - List deviceProfileUpdateMsgList = edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class); - Assert.assertEquals(3, deviceProfileUpdateMsgList.size()); - Optional deviceProfileUpdateMsgOpt = - deviceProfileUpdateMsgList.stream().filter(dfum -> CUSTOM_DEVICE_PROFILE_NAME.equals(dfum.getName())).findAny(); - Assert.assertTrue(deviceProfileUpdateMsgOpt.isPresent()); - DeviceProfileUpdateMsg deviceProfileUpdateMsg = deviceProfileUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); - UUID deviceProfileUUID = new UUID(deviceProfileUpdateMsg.getIdMSB(), deviceProfileUpdateMsg.getIdLSB()); - DeviceProfile deviceProfile = doGet("/api/deviceProfile/" + deviceProfileUUID.toString(), DeviceProfile.class); - Assert.assertNotNull(deviceProfile); - Assert.assertNotNull(deviceProfile.getProfileData()); - Assert.assertNotNull(deviceProfile.getProfileData().getAlarms()); - Assert.assertNotNull(deviceProfile.getProfileData().getAlarms().get(0).getClearRule()); - - testAutoGeneratedCodeByProtobuf(deviceProfileUpdateMsg); - - Optional assetUpdateMsgOpt = edgeImitator.findMessageByType(AssetUpdateMsg.class); - Assert.assertTrue(assetUpdateMsgOpt.isPresent()); - AssetUpdateMsg assetUpdateMsg = assetUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); - UUID assetUUID = new UUID(assetUpdateMsg.getIdMSB(), assetUpdateMsg.getIdLSB()); - Asset asset = doGet("/api/asset/" + assetUUID.toString(), Asset.class); - Assert.assertNotNull(asset); - List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertTrue(edgeAssets.contains(asset)); - - testAutoGeneratedCodeByProtobuf(assetUpdateMsg); - - Optional ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); - Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); - RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); - UUID ruleChainUUID = new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB()); - RuleChain ruleChain = doGet("/api/ruleChain/" + ruleChainUUID.toString(), RuleChain.class); - Assert.assertNotNull(ruleChain); - List edgeRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/ruleChains?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertTrue(edgeRuleChains.contains(ruleChain)); - - testAutoGeneratedCodeByProtobuf(ruleChainUpdateMsg); - - log.info("Received data checked"); + testTimeseriesWithFailures(); } private void testDevices() throws Exception { @@ -529,23 +374,20 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { log.info("Testing RuleChains"); // 1 - edgeImitator.expectMessageAmount(1); + edgeImitator.expectMessageAmount(2); RuleChain ruleChain = new RuleChain(); ruleChain.setName("Edge Test Rule Chain"); ruleChain.setType(RuleChainType.EDGE); RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); - createRuleChainMetadata(savedRuleChain); - // sleep 1 seconds to avoid ENTITY_UPDATED_RPC_MESSAGE for the rule chain - // rule chain metadata is going to be stored and updated event pushed to edge notification service - // while service will be processing this event assignment rule chain to edge will be completed if bad timing - Thread.sleep(1000); doPost("/api/edge/" + edge.getId().getId().toString() + "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); + createRuleChainMetadata(savedRuleChain); Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof RuleChainUpdateMsg); - RuleChainUpdateMsg ruleChainUpdateMsg = (RuleChainUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); + Optional ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); + Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); + RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); + Assert.assertTrue(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE.equals(ruleChainUpdateMsg.getMsgType()) || + UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE.equals(ruleChainUpdateMsg.getMsgType())); Assert.assertEquals(ruleChainUpdateMsg.getIdMSB(), savedRuleChain.getUuidId().getMostSignificantBits()); Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), savedRuleChain.getUuidId().getLeastSignificantBits()); Assert.assertEquals(ruleChainUpdateMsg.getName(), savedRuleChain.getName()); @@ -558,9 +400,9 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { doDelete("/api/edge/" + edge.getId().getId().toString() + "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof RuleChainUpdateMsg); - ruleChainUpdateMsg = (RuleChainUpdateMsg) latestMessage; + ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); + Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); + ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); Assert.assertEquals(ruleChainUpdateMsg.getIdMSB(), savedRuleChain.getUuidId().getMostSignificantBits()); Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), savedRuleChain.getUuidId().getLeastSignificantBits()); @@ -574,67 +416,6 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { log.info("RuleChains tested successfully"); } - private void testRuleChainMetadataRequestMsg(RuleChainId ruleChainId) throws Exception { - RuleChainMetadataRequestMsg.Builder ruleChainMetadataRequestMsgBuilder = RuleChainMetadataRequestMsg.newBuilder() - .setRuleChainIdMSB(ruleChainId.getId().getMostSignificantBits()) - .setRuleChainIdLSB(ruleChainId.getId().getLeastSignificantBits()); - testAutoGeneratedCodeByProtobuf(ruleChainMetadataRequestMsgBuilder); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder() - .addRuleChainMetadataRequestMsg(ruleChainMetadataRequestMsgBuilder.build()); - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.expectMessageAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); - RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = (RuleChainMetadataUpdateMsg) latestMessage; - RuleChainId receivedRuleChainId = - new RuleChainId(new UUID(ruleChainMetadataUpdateMsg.getRuleChainIdMSB(), ruleChainMetadataUpdateMsg.getRuleChainIdLSB())); - Assert.assertEquals(ruleChainId, receivedRuleChainId); - } - - private void createRuleChainMetadata(RuleChain ruleChain) throws Exception { - RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); - ruleChainMetaData.setRuleChainId(ruleChain.getId()); - - ObjectMapper mapper = new ObjectMapper(); - - RuleNode ruleNode1 = new RuleNode(); - ruleNode1.setName("name1"); - ruleNode1.setType("type1"); - ruleNode1.setConfiguration(mapper.readTree("\"key1\": \"val1\"")); - - RuleNode ruleNode2 = new RuleNode(); - ruleNode2.setName("name2"); - ruleNode2.setType("type2"); - ruleNode2.setConfiguration(mapper.readTree("\"key2\": \"val2\"")); - - RuleNode ruleNode3 = new RuleNode(); - ruleNode3.setName("name3"); - ruleNode3.setType("type3"); - ruleNode3.setConfiguration(mapper.readTree("\"key3\": \"val3\"")); - - List ruleNodes = new ArrayList<>(); - ruleNodes.add(ruleNode1); - ruleNodes.add(ruleNode2); - ruleNodes.add(ruleNode3); - ruleChainMetaData.setFirstNodeIndex(0); - ruleChainMetaData.setNodes(ruleNodes); - - ruleChainMetaData.addConnectionInfo(0, 1, "success"); - ruleChainMetaData.addConnectionInfo(0, 2, "fail"); - ruleChainMetaData.addConnectionInfo(1, 2, "success"); - - ruleChainMetaData.addRuleChainConnectionInfo(2, edge.getRootRuleChainId(), "success", mapper.createObjectNode()); - - doPost("/api/ruleChain/metadata", ruleChainMetaData, RuleChainMetaData.class); - } - private void testDashboards() throws Exception { log.info("Testing Dashboards"); @@ -1037,12 +818,12 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { log.info("Attributes tested successfully"); } - private void testAttributesDeleteMsg(Device device) throws JsonProcessingException, InterruptedException { - String deleteAttributesData = "{\"scope\":\"SERVER_SCOPE\",\"keys\":[\"key1\",\"key2\"]}"; - JsonNode deleteAttributesEntityData = mapper.readTree(deleteAttributesData); - EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_DELETED, device.getId().getId(), EdgeEventType.DEVICE, deleteAttributesEntityData); + private void testAttributesUpdatedMsg(Device device) throws JsonProcessingException, InterruptedException { + String attributesData = "{\"scope\":\"SERVER_SCOPE\",\"kv\":{\"key1\":\"value1\"}}"; + JsonNode attributesEntityData = mapper.readTree(attributesData); + EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, attributesEntityData); edgeImitator.expectMessageAmount(1); - edgeEventService.saveAsync(edgeEvent); + edgeEventService.saveAsync(edgeEvent1); clusterService.onEdgeEventUpdate(tenantId, edge.getId()); Assert.assertTrue(edgeImitator.waitForMessages()); @@ -1052,15 +833,14 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); + Assert.assertEquals("SERVER_SCOPE", latestEntityDataMsg.getPostAttributeScope()); + Assert.assertTrue(latestEntityDataMsg.hasAttributesUpdatedMsg()); - Assert.assertTrue(latestEntityDataMsg.hasAttributeDeleteMsg()); - - AttributeDeleteMsg attributeDeleteMsg = latestEntityDataMsg.getAttributeDeleteMsg(); - Assert.assertEquals(attributeDeleteMsg.getScope(), deleteAttributesEntityData.get("scope").asText()); - - Assert.assertEquals(2, attributeDeleteMsg.getAttributeNamesCount()); - Assert.assertEquals("key1", attributeDeleteMsg.getAttributeNames(0)); - Assert.assertEquals("key2", attributeDeleteMsg.getAttributeNames(1)); + TransportProtos.PostAttributeMsg attributesUpdatedMsg = latestEntityDataMsg.getAttributesUpdatedMsg(); + Assert.assertEquals(1, attributesUpdatedMsg.getKvCount()); + TransportProtos.KeyValueProto keyValueProto = attributesUpdatedMsg.getKv(0); + Assert.assertEquals("key1", keyValueProto.getKey()); + Assert.assertEquals("value1", keyValueProto.getStringV()); } private void testPostAttributesMsg(Device device) throws JsonProcessingException, InterruptedException { @@ -1088,29 +868,192 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals("value2", keyValueProto.getStringV()); } - private void testAttributesUpdatedMsg(Device device) throws JsonProcessingException, InterruptedException { - String attributesData = "{\"scope\":\"SERVER_SCOPE\",\"kv\":{\"key1\":\"value1\"}}"; - JsonNode attributesEntityData = mapper.readTree(attributesData); - EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, attributesEntityData); + private void testAttributesDeleteMsg(Device device) throws JsonProcessingException, InterruptedException { + String deleteAttributesData = "{\"scope\":\"SERVER_SCOPE\",\"keys\":[\"key1\",\"key2\"]}"; + JsonNode deleteAttributesEntityData = mapper.readTree(deleteAttributesData); + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_DELETED, device.getId().getId(), EdgeEventType.DEVICE, deleteAttributesEntityData); edgeImitator.expectMessageAmount(1); - edgeEventService.saveAsync(edgeEvent1); + edgeEventService.saveAsync(edgeEvent); clusterService.onEdgeEventUpdate(tenantId, edge.getId()); Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof EntityDataProto); - EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; - Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); - Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); - Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); - Assert.assertEquals("SERVER_SCOPE", latestEntityDataMsg.getPostAttributeScope()); - Assert.assertTrue(latestEntityDataMsg.hasAttributesUpdatedMsg()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityDataProto); + EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; + Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); + Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); + Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); + + Assert.assertTrue(latestEntityDataMsg.hasAttributeDeleteMsg()); + + AttributeDeleteMsg attributeDeleteMsg = latestEntityDataMsg.getAttributeDeleteMsg(); + Assert.assertEquals(attributeDeleteMsg.getScope(), deleteAttributesEntityData.get("scope").asText()); + + Assert.assertEquals(2, attributeDeleteMsg.getAttributeNamesCount()); + Assert.assertEquals("key1", attributeDeleteMsg.getAttributeNames(0)); + Assert.assertEquals("key2", attributeDeleteMsg.getAttributeNames(1)); + } + + private Device findDeviceByName(String deviceName) throws Exception { + List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", + new TypeReference>() { + }, new PageLink(100)).getData(); + Optional foundDevice = edgeDevices.stream().filter(d -> d.getName().equals(deviceName)).findAny(); + Assert.assertTrue(foundDevice.isPresent()); + Device device = foundDevice.get(); + Assert.assertEquals(deviceName, device.getName()); + return device; + } + + private Asset findAssetByName(String assetName) throws Exception { + List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", + new TypeReference>() { + }, new PageLink(100)).getData(); + + Assert.assertEquals(1, edgeAssets.size()); + Asset asset = edgeAssets.get(0); + Assert.assertEquals(assetName, asset.getName()); + return asset; + } + + private Device saveDevice(String deviceName, String type) throws Exception { + Device device = new Device(); + device.setName(deviceName); + device.setType(type); + return doPost("/api/device", device, Device.class); + } + + private Asset saveAsset(String assetName) throws Exception { + Asset asset = new Asset(); + asset.setName(assetName); + asset.setType("test"); + return doPost("/api/asset", asset, Asset.class); + } + + private void testReceivedInitialData() throws Exception { + log.info("Checking received data"); + Assert.assertTrue(edgeImitator.waitForMessages()); + + EdgeConfiguration configuration = edgeImitator.getConfiguration(); + Assert.assertNotNull(configuration); + + testAutoGeneratedCodeByProtobuf(configuration); + + Optional deviceUpdateMsgOpt = edgeImitator.findMessageByType(DeviceUpdateMsg.class); + Assert.assertTrue(deviceUpdateMsgOpt.isPresent()); + DeviceUpdateMsg deviceUpdateMsg = deviceUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); + UUID deviceUUID = new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()); + Device device = doGet("/api/device/" + deviceUUID.toString(), Device.class); + Assert.assertNotNull(device); + List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", + new TypeReference>() {}, new PageLink(100)).getData(); + Assert.assertTrue(edgeDevices.contains(device)); + + List deviceProfileUpdateMsgList = edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class); + Assert.assertEquals(3, deviceProfileUpdateMsgList.size()); + Optional deviceProfileUpdateMsgOpt = + deviceProfileUpdateMsgList.stream().filter(dfum -> CUSTOM_DEVICE_PROFILE_NAME.equals(dfum.getName())).findAny(); + Assert.assertTrue(deviceProfileUpdateMsgOpt.isPresent()); + DeviceProfileUpdateMsg deviceProfileUpdateMsg = deviceProfileUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); + UUID deviceProfileUUID = new UUID(deviceProfileUpdateMsg.getIdMSB(), deviceProfileUpdateMsg.getIdLSB()); + DeviceProfile deviceProfile = doGet("/api/deviceProfile/" + deviceProfileUUID.toString(), DeviceProfile.class); + Assert.assertNotNull(deviceProfile); + Assert.assertNotNull(deviceProfile.getProfileData()); + Assert.assertNotNull(deviceProfile.getProfileData().getAlarms()); + Assert.assertNotNull(deviceProfile.getProfileData().getAlarms().get(0).getClearRule()); + + testAutoGeneratedCodeByProtobuf(deviceProfileUpdateMsg); + + Optional assetUpdateMsgOpt = edgeImitator.findMessageByType(AssetUpdateMsg.class); + Assert.assertTrue(assetUpdateMsgOpt.isPresent()); + AssetUpdateMsg assetUpdateMsg = assetUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); + UUID assetUUID = new UUID(assetUpdateMsg.getIdMSB(), assetUpdateMsg.getIdLSB()); + Asset asset = doGet("/api/asset/" + assetUUID.toString(), Asset.class); + Assert.assertNotNull(asset); + List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", + new TypeReference>() {}, new PageLink(100)).getData(); + Assert.assertTrue(edgeAssets.contains(asset)); + + testAutoGeneratedCodeByProtobuf(assetUpdateMsg); + + Optional ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); + Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); + RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); + UUID ruleChainUUID = new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB()); + RuleChain ruleChain = doGet("/api/ruleChain/" + ruleChainUUID.toString(), RuleChain.class); + Assert.assertNotNull(ruleChain); + List edgeRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/ruleChains?", + new TypeReference>() {}, new PageLink(100)).getData(); + Assert.assertTrue(edgeRuleChains.contains(ruleChain)); + + testAutoGeneratedCodeByProtobuf(ruleChainUpdateMsg); + + log.info("Received data checked"); + } + + private void testRuleChainMetadataRequestMsg(RuleChainId ruleChainId) throws Exception { + RuleChainMetadataRequestMsg.Builder ruleChainMetadataRequestMsgBuilder = RuleChainMetadataRequestMsg.newBuilder() + .setRuleChainIdMSB(ruleChainId.getId().getMostSignificantBits()) + .setRuleChainIdLSB(ruleChainId.getId().getLeastSignificantBits()); + testAutoGeneratedCodeByProtobuf(ruleChainMetadataRequestMsgBuilder); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder() + .addRuleChainMetadataRequestMsg(ruleChainMetadataRequestMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); + RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = (RuleChainMetadataUpdateMsg) latestMessage; + RuleChainId receivedRuleChainId = + new RuleChainId(new UUID(ruleChainMetadataUpdateMsg.getRuleChainIdMSB(), ruleChainMetadataUpdateMsg.getRuleChainIdLSB())); + Assert.assertEquals(ruleChainId, receivedRuleChainId); + } + + private void createRuleChainMetadata(RuleChain ruleChain) throws Exception { + RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); + ruleChainMetaData.setRuleChainId(ruleChain.getId()); + + ObjectMapper mapper = new ObjectMapper(); + + RuleNode ruleNode1 = new RuleNode(); + ruleNode1.setName("name1"); + ruleNode1.setType("type1"); + ruleNode1.setConfiguration(mapper.readTree("\"key1\": \"val1\"")); + + RuleNode ruleNode2 = new RuleNode(); + ruleNode2.setName("name2"); + ruleNode2.setType("type2"); + ruleNode2.setConfiguration(mapper.readTree("\"key2\": \"val2\"")); + + RuleNode ruleNode3 = new RuleNode(); + ruleNode3.setName("name3"); + ruleNode3.setType("type3"); + ruleNode3.setConfiguration(mapper.readTree("\"key3\": \"val3\"")); + + List ruleNodes = new ArrayList<>(); + ruleNodes.add(ruleNode1); + ruleNodes.add(ruleNode2); + ruleNodes.add(ruleNode3); + ruleChainMetaData.setFirstNodeIndex(0); + ruleChainMetaData.setNodes(ruleNodes); + + ruleChainMetaData.addConnectionInfo(0, 1, "success"); + ruleChainMetaData.addConnectionInfo(0, 2, "fail"); + ruleChainMetaData.addConnectionInfo(1, 2, "success"); - TransportProtos.PostAttributeMsg attributesUpdatedMsg = latestEntityDataMsg.getAttributesUpdatedMsg(); - Assert.assertEquals(1, attributesUpdatedMsg.getKvCount()); - TransportProtos.KeyValueProto keyValueProto = attributesUpdatedMsg.getKv(0); - Assert.assertEquals("key1", keyValueProto.getKey()); - Assert.assertEquals("value1", keyValueProto.getStringV()); + ruleChainMetaData.addRuleChainConnectionInfo(2, edge.getRootRuleChainId(), "success", mapper.createObjectNode()); + + doPost("/api/ruleChain/metadata", ruleChainMetaData, RuleChainMetaData.class); } private void testSendMessagesToCloud() throws Exception { @@ -1284,46 +1227,6 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(AlarmSeverity.CRITICAL, alarmInfo.getSeverity()); } - private void sendRelation() throws Exception { - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() {}, new PageLink(100)).getData(); - Optional foundDevice1 = edgeDevices.stream().filter(device1 -> device1.getName().equals("Edge Device 1")).findAny(); - Assert.assertTrue(foundDevice1.isPresent()); - Device device1 = foundDevice1.get(); - Optional foundDevice2 = edgeDevices.stream().filter(device2 -> device2.getName().equals("Edge Device 2")).findAny(); - Assert.assertTrue(foundDevice2.isPresent()); - Device device2 = foundDevice2.get(); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - RelationUpdateMsg.Builder relationUpdateMsgBuilder = RelationUpdateMsg.newBuilder(); - relationUpdateMsgBuilder.setType("test"); - relationUpdateMsgBuilder.setTypeGroup(RelationTypeGroup.COMMON.name()); - relationUpdateMsgBuilder.setToIdMSB(device1.getId().getId().getMostSignificantBits()); - relationUpdateMsgBuilder.setToIdLSB(device1.getId().getId().getLeastSignificantBits()); - relationUpdateMsgBuilder.setToEntityType(device1.getId().getEntityType().name()); - relationUpdateMsgBuilder.setFromIdMSB(device2.getId().getId().getMostSignificantBits()); - relationUpdateMsgBuilder.setFromIdLSB(device2.getId().getId().getLeastSignificantBits()); - relationUpdateMsgBuilder.setFromEntityType(device2.getId().getEntityType().name()); - relationUpdateMsgBuilder.setAdditionalInfo("{}"); - testAutoGeneratedCodeByProtobuf(relationUpdateMsgBuilder); - uplinkMsgBuilder.addRelationUpdateMsg(relationUpdateMsgBuilder.build()); - - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - - EntityRelation relation = doGet("/api/relation?" + - "&fromId=" + device2.getId().getId().toString() + - "&fromType=" + device2.getId().getEntityType().name() + - "&relationType=" + "test" + - "&relationTypeGroup=" + RelationTypeGroup.COMMON.name() + - "&toId=" + device1.getId().getId().toString() + - "&toType=" + device1.getId().getEntityType().name(), EntityRelation.class); - Assert.assertNotNull(relation); - } - private void sendTelemetry() throws Exception { List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", new TypeReference>() {}, new PageLink(100)).getData(); @@ -1368,9 +1271,15 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { edgeImitator.sendUplinkMsg(uplinkMsgBuilder2.build()); Assert.assertTrue(edgeImitator.waitForResponses()); - // Wait before device attributes saved to database before requesting them from controller - Thread.sleep(1000); - Map>> timeseries = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/values/timeseries?keys=" + timeseriesKey, new TypeReference<>() {}); + int attempt = 0; + Map>> timeseries; + do { + timeseries = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/values/timeseries?keys=" + timeseriesKey, + new TypeReference<>() {}); + // Wait before device attributes saved to database before requesting them from controller + Thread.sleep(100); + attempt++; + } while (!timeseries.containsKey(timeseriesKey) || attempt < 10); Assert.assertTrue(timeseries.containsKey(timeseriesKey)); Assert.assertEquals(1, timeseries.get(timeseriesKey).size()); Assert.assertEquals(timeseriesValue, timeseries.get(timeseriesKey).get(0).get("value")); @@ -1382,6 +1291,69 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { } + private void sendRelation() throws Exception { + List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", + new TypeReference>() {}, new PageLink(100)).getData(); + Optional foundDevice1 = edgeDevices.stream().filter(device1 -> device1.getName().equals("Edge Device 1")).findAny(); + Assert.assertTrue(foundDevice1.isPresent()); + Device device1 = foundDevice1.get(); + Optional foundDevice2 = edgeDevices.stream().filter(device2 -> device2.getName().equals("Edge Device 2")).findAny(); + Assert.assertTrue(foundDevice2.isPresent()); + Device device2 = foundDevice2.get(); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + RelationUpdateMsg.Builder relationUpdateMsgBuilder = RelationUpdateMsg.newBuilder(); + relationUpdateMsgBuilder.setType("test"); + relationUpdateMsgBuilder.setTypeGroup(RelationTypeGroup.COMMON.name()); + relationUpdateMsgBuilder.setToIdMSB(device1.getId().getId().getMostSignificantBits()); + relationUpdateMsgBuilder.setToIdLSB(device1.getId().getId().getLeastSignificantBits()); + relationUpdateMsgBuilder.setToEntityType(device1.getId().getEntityType().name()); + relationUpdateMsgBuilder.setFromIdMSB(device2.getId().getId().getMostSignificantBits()); + relationUpdateMsgBuilder.setFromIdLSB(device2.getId().getId().getLeastSignificantBits()); + relationUpdateMsgBuilder.setFromEntityType(device2.getId().getEntityType().name()); + relationUpdateMsgBuilder.setAdditionalInfo("{}"); + testAutoGeneratedCodeByProtobuf(relationUpdateMsgBuilder); + uplinkMsgBuilder.addRelationUpdateMsg(relationUpdateMsgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + + EntityRelation relation = doGet("/api/relation?" + + "&fromId=" + device2.getId().getId().toString() + + "&fromType=" + device2.getId().getEntityType().name() + + "&relationType=" + "test" + + "&relationTypeGroup=" + RelationTypeGroup.COMMON.name() + + "&toId=" + device1.getId().getId().toString() + + "&toType=" + device1.getId().getEntityType().name(), EntityRelation.class); + Assert.assertNotNull(relation); + } + + private void sendDeleteDeviceOnEdge() throws Exception { + Device device = findDeviceByName("Edge Device 2"); + UplinkMsg.Builder upLinkMsgBuilder = UplinkMsg.newBuilder(); + DeviceUpdateMsg.Builder deviceDeleteMsgBuilder = DeviceUpdateMsg.newBuilder(); + deviceDeleteMsgBuilder.setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE); + deviceDeleteMsgBuilder.setIdMSB(device.getId().getId().getMostSignificantBits()); + deviceDeleteMsgBuilder.setIdLSB(device.getId().getId().getLeastSignificantBits()); + testAutoGeneratedCodeByProtobuf(deviceDeleteMsgBuilder); + + upLinkMsgBuilder.addDeviceUpdateMsg(deviceDeleteMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(upLinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.sendUplinkMsg(upLinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + device = doGet("/api/device/" + device.getId().getId().toString(), Device.class); + Assert.assertNotNull(device); + List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", + new TypeReference>() { + }, new PageLink(100)).getData(); + Assert.assertFalse(edgeDevices.contains(device)); + } + private void sendRuleChainMetadataRequest() throws Exception { RuleChainId edgeRootRuleChainId = edge.getRootRuleChainId(); @@ -1463,25 +1435,6 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(deviceCredentialsUpdateMsg.getCredentialsId(), deviceCredentials.getCredentialsId()); } - private void sendDeviceCredentialsUpdate() throws Exception { - Device device = findDeviceByName("Edge Device 1"); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - DeviceCredentialsUpdateMsg.Builder deviceCredentialsUpdateMsgBuilder = DeviceCredentialsUpdateMsg.newBuilder(); - deviceCredentialsUpdateMsgBuilder.setDeviceIdMSB(device.getUuidId().getMostSignificantBits()); - deviceCredentialsUpdateMsgBuilder.setDeviceIdLSB(device.getUuidId().getLeastSignificantBits()); - deviceCredentialsUpdateMsgBuilder.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN.name()); - deviceCredentialsUpdateMsgBuilder.setCredentialsId("NEW_TOKEN"); - testAutoGeneratedCodeByProtobuf(deviceCredentialsUpdateMsgBuilder); - uplinkMsgBuilder.addDeviceCredentialsUpdateMsg(deviceCredentialsUpdateMsgBuilder.build()); - - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - } - private void sendDeviceRpcResponse() throws Exception { Device device = findDeviceByName("Edge Device 1"); @@ -1507,6 +1460,25 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertTrue(edgeImitator.waitForResponses()); } + private void sendDeviceCredentialsUpdate() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + DeviceCredentialsUpdateMsg.Builder deviceCredentialsUpdateMsgBuilder = DeviceCredentialsUpdateMsg.newBuilder(); + deviceCredentialsUpdateMsgBuilder.setDeviceIdMSB(device.getUuidId().getMostSignificantBits()); + deviceCredentialsUpdateMsgBuilder.setDeviceIdLSB(device.getUuidId().getLeastSignificantBits()); + deviceCredentialsUpdateMsgBuilder.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN.name()); + deviceCredentialsUpdateMsgBuilder.setCredentialsId("NEW_TOKEN"); + testAutoGeneratedCodeByProtobuf(deviceCredentialsUpdateMsgBuilder); + uplinkMsgBuilder.addDeviceCredentialsUpdateMsg(deviceCredentialsUpdateMsgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + } + private void sendAttributesRequest() throws Exception { Device device = findDeviceByName("Edge Device 1"); sendAttributesRequest(device, DataConstants.SERVER_SCOPE, "{\"key1\":\"value1\"}", "key1", "value1"); @@ -1520,7 +1492,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { attributesData); // Wait before device attributes saved to database before requesting them from edge - Thread.sleep(1000); + // queue used to save attributes to database + Thread.sleep(500); UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); AttributesRequestMsg.Builder attributesRequestMsgBuilder = AttributesRequestMsg.newBuilder(); @@ -1554,43 +1527,75 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(expectedValue, keyValueProto.getStringV()); } - private void sendDeleteDeviceOnEdge() throws Exception { - Device device = findDeviceByName("Edge Device 2"); - UplinkMsg.Builder upLinkMsgBuilder = UplinkMsg.newBuilder(); - DeviceUpdateMsg.Builder deviceDeleteMsgBuilder = DeviceUpdateMsg.newBuilder(); - deviceDeleteMsgBuilder.setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE); - deviceDeleteMsgBuilder.setIdMSB(device.getId().getId().getMostSignificantBits()); - deviceDeleteMsgBuilder.setIdLSB(device.getId().getId().getLeastSignificantBits()); - testAutoGeneratedCodeByProtobuf(deviceDeleteMsgBuilder); + private void testRpcCall() throws Exception { + Device device = findDeviceByName("Edge Device 1"); - upLinkMsgBuilder.addDeviceUpdateMsg(deviceDeleteMsgBuilder.build()); - testAutoGeneratedCodeByProtobuf(upLinkMsgBuilder); + ObjectNode body = mapper.createObjectNode(); + body.put("requestId", new Random().nextInt()); + body.put("requestUUID", Uuids.timeBased().toString()); + body.put("oneway", false); + body.put("expirationTime", System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10)); + body.put("method", "test_method"); + body.put("params", "{\"param1\":\"value1\"}"); - edgeImitator.expectResponsesAmount(1); - edgeImitator.sendUplinkMsg(upLinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - device = doGet("/api/device/" + device.getId().getId().toString(), Device.class); - Assert.assertNotNull(device); - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() { - }, new PageLink(100)).getData(); - Assert.assertFalse(edgeDevices.contains(device)); + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.RPC_CALL, device.getId().getId(), EdgeEventType.DEVICE, body); + edgeImitator.expectMessageAmount(1); + edgeEventService.saveAsync(edgeEvent); + clusterService.onEdgeEventUpdate(tenantId, edge.getId()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceRpcCallMsg); + DeviceRpcCallMsg latestDeviceRpcCallMsg = (DeviceRpcCallMsg) latestMessage; + Assert.assertEquals("test_method", latestDeviceRpcCallMsg.getRequestMsg().getMethod()); } - private void installation() throws Exception { - edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); + private void testTimeseriesWithFailures() throws Exception { + log.info("Testing timeseries with failures"); - DeviceProfile deviceProfile = this.createDeviceProfile(CUSTOM_DEVICE_PROFILE_NAME, null); - extendDeviceProfileData(deviceProfile); - doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); + int numberOfTimeseriesToSend = 1000; - Device savedDevice = saveDevice("Edge Device 1", CUSTOM_DEVICE_PROFILE_NAME); - doPost("/api/edge/" + edge.getId().getId().toString() - + "/device/" + savedDevice.getId().getId().toString(), Device.class); + edgeImitator.setRandomFailuresOnTimeseriesDownlink(true); + // imitator will generate failure in 5% of cases + edgeImitator.setFailureProbability(5.0); - Asset savedAsset = saveAsset("Edge Asset 1"); - doPost("/api/edge/" + edge.getId().getId().toString() - + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); + edgeImitator.expectMessageAmount(numberOfTimeseriesToSend); + Device device = findDeviceByName("Edge Device 1"); + for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { + String timeseriesData = "{\"data\":{\"idx\":" + idx + "},\"ts\":" + System.currentTimeMillis() + "}"; + JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, + device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); + edgeEventService.saveAsync(edgeEvent); + clusterService.onEdgeEventUpdate(tenantId, edge.getId()); + } + + Assert.assertTrue(edgeImitator.waitForMessages(60)); + + List allTelemetryMsgs = edgeImitator.findAllMessagesByType(EntityDataProto.class); + Assert.assertEquals(numberOfTimeseriesToSend, allTelemetryMsgs.size()); + + for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { + Assert.assertTrue(isIdxExistsInTheDownlinkList(idx, allTelemetryMsgs)); + } + + edgeImitator.setRandomFailuresOnTimeseriesDownlink(false); + log.info("Timeseries with failures tested successfully"); + } + + private boolean isIdxExistsInTheDownlinkList(int idx, List allTelemetryMsgs) { + for (EntityDataProto proto : allTelemetryMsgs) { + TransportProtos.PostTelemetryMsg postTelemetryMsg = proto.getPostTelemetryMsg(); + Assert.assertEquals(1, postTelemetryMsg.getTsKvListCount()); + TransportProtos.TsKvListProto tsKvListProto = postTelemetryMsg.getTsKvList(0); + Assert.assertEquals(1, tsKvListProto.getKvCount()); + TransportProtos.KeyValueProto keyValueProto = tsKvListProto.getKv(0); + Assert.assertEquals("idx", keyValueProto.getKey()); + if (keyValueProto.getLongV() == idx) { + return true; + } + } + return false; } private void extendDeviceProfileData(DeviceProfile deviceProfile) { diff --git a/application/src/test/resources/application-test.properties b/application/src/test/resources/application-test.properties index 02d43723ed..40ef8f06c3 100644 --- a/application/src/test/resources/application-test.properties +++ b/application/src/test/resources/application-test.properties @@ -1,4 +1,6 @@ transport.lwm2m.security.key_store=lwm2m/credentials/serverKeyStore.jks transport.lwm2m.security.key_store_password=server edges.enabled=true +edges.storage.no_read_records_sleep=500 +edges.storage.sleep_between_batches=500 transport.lwm2m.bootstrap.security.alias=server \ No newline at end of file From 14b19d428f12d880696c8a880e56fa632982e060 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 3 Jun 2021 21:47:45 +0300 Subject: [PATCH 34/52] Changed edge test method order to be in sync with PE --- .../thingsboard/server/edge/BaseEdgeTest.java | 506 +++++++++--------- 1 file changed, 254 insertions(+), 252 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java index a50c2b4bc1..0e2f94eaf9 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -177,22 +177,6 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { testReceivedInitialData(); } - private void installation() throws Exception { - edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); - - DeviceProfile deviceProfile = this.createDeviceProfile(CUSTOM_DEVICE_PROFILE_NAME, null); - extendDeviceProfileData(deviceProfile); - doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); - - Device savedDevice = saveDevice("Edge Device 1", CUSTOM_DEVICE_PROFILE_NAME); - doPost("/api/edge/" + edge.getId().getId().toString() - + "/device/" + savedDevice.getId().getId().toString(), Device.class); - - Asset savedAsset = saveAsset("Edge Asset 1"); - doPost("/api/edge/" + edge.getId().getId().toString() - + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); - } - @After public void afterTest() throws Exception { try { @@ -229,11 +213,121 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { testAttributes(); - testSendMessagesToCloud(); - testRpcCall(); testTimeseriesWithFailures(); + + testSendMessagesToCloud(); + } + + private void installation() throws Exception { + edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); + + DeviceProfile deviceProfile = this.createDeviceProfile(CUSTOM_DEVICE_PROFILE_NAME, null); + extendDeviceProfileData(deviceProfile); + doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); + + Device savedDevice = saveDevice("Edge Device 1", CUSTOM_DEVICE_PROFILE_NAME); + doPost("/api/edge/" + edge.getId().getId().toString() + + "/device/" + savedDevice.getId().getId().toString(), Device.class); + + Asset savedAsset = saveAsset("Edge Asset 1"); + doPost("/api/edge/" + edge.getId().getId().toString() + + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); + } + + private void extendDeviceProfileData(DeviceProfile deviceProfile) { + DeviceProfileData profileData = deviceProfile.getProfileData(); + List alarms = new ArrayList<>(); + DeviceProfileAlarm deviceProfileAlarm = new DeviceProfileAlarm(); + deviceProfileAlarm.setAlarmType("High Temperature"); + AlarmRule alarmRule = new AlarmRule(); + alarmRule.setAlarmDetails("Alarm Details"); + AlarmCondition alarmCondition = new AlarmCondition(); + alarmCondition.setSpec(new SimpleAlarmConditionSpec()); + List condition = new ArrayList<>(); + AlarmConditionFilter alarmConditionFilter = new AlarmConditionFilter(); + alarmConditionFilter.setKey(new AlarmConditionFilterKey(AlarmConditionKeyType.ATTRIBUTE, "temperature")); + NumericFilterPredicate predicate = new NumericFilterPredicate(); + predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER); + predicate.setValue(new FilterPredicateValue<>(55.0)); + alarmConditionFilter.setPredicate(predicate); + alarmConditionFilter.setValueType(EntityKeyValueType.NUMERIC); + condition.add(alarmConditionFilter); + alarmCondition.setCondition(condition); + alarmRule.setCondition(alarmCondition); + deviceProfileAlarm.setClearRule(alarmRule); + TreeMap createRules = new TreeMap<>(); + createRules.put(AlarmSeverity.CRITICAL, alarmRule); + deviceProfileAlarm.setCreateRules(createRules); + alarms.add(deviceProfileAlarm); + profileData.setAlarms(alarms); + profileData.setProvisionConfiguration(new AllowCreateNewDevicesDeviceProfileProvisionConfiguration("123")); + } + + private void testReceivedInitialData() throws Exception { + log.info("Checking received data"); + Assert.assertTrue(edgeImitator.waitForMessages()); + + EdgeConfiguration configuration = edgeImitator.getConfiguration(); + Assert.assertNotNull(configuration); + + testAutoGeneratedCodeByProtobuf(configuration); + + Optional deviceUpdateMsgOpt = edgeImitator.findMessageByType(DeviceUpdateMsg.class); + Assert.assertTrue(deviceUpdateMsgOpt.isPresent()); + DeviceUpdateMsg deviceUpdateMsg = deviceUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); + UUID deviceUUID = new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()); + Device device = doGet("/api/device/" + deviceUUID.toString(), Device.class); + Assert.assertNotNull(device); + List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", + new TypeReference>() {}, new PageLink(100)).getData(); + Assert.assertTrue(edgeDevices.contains(device)); + + List deviceProfileUpdateMsgList = edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class); + Assert.assertEquals(3, deviceProfileUpdateMsgList.size()); + Optional deviceProfileUpdateMsgOpt = + deviceProfileUpdateMsgList.stream().filter(dfum -> CUSTOM_DEVICE_PROFILE_NAME.equals(dfum.getName())).findAny(); + Assert.assertTrue(deviceProfileUpdateMsgOpt.isPresent()); + DeviceProfileUpdateMsg deviceProfileUpdateMsg = deviceProfileUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); + UUID deviceProfileUUID = new UUID(deviceProfileUpdateMsg.getIdMSB(), deviceProfileUpdateMsg.getIdLSB()); + DeviceProfile deviceProfile = doGet("/api/deviceProfile/" + deviceProfileUUID.toString(), DeviceProfile.class); + Assert.assertNotNull(deviceProfile); + Assert.assertNotNull(deviceProfile.getProfileData()); + Assert.assertNotNull(deviceProfile.getProfileData().getAlarms()); + Assert.assertNotNull(deviceProfile.getProfileData().getAlarms().get(0).getClearRule()); + + testAutoGeneratedCodeByProtobuf(deviceProfileUpdateMsg); + + Optional assetUpdateMsgOpt = edgeImitator.findMessageByType(AssetUpdateMsg.class); + Assert.assertTrue(assetUpdateMsgOpt.isPresent()); + AssetUpdateMsg assetUpdateMsg = assetUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); + UUID assetUUID = new UUID(assetUpdateMsg.getIdMSB(), assetUpdateMsg.getIdLSB()); + Asset asset = doGet("/api/asset/" + assetUUID.toString(), Asset.class); + Assert.assertNotNull(asset); + List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", + new TypeReference>() {}, new PageLink(100)).getData(); + Assert.assertTrue(edgeAssets.contains(asset)); + + testAutoGeneratedCodeByProtobuf(assetUpdateMsg); + + Optional ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); + Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); + RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); + UUID ruleChainUUID = new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB()); + RuleChain ruleChain = doGet("/api/ruleChain/" + ruleChainUUID.toString(), RuleChain.class); + Assert.assertNotNull(ruleChain); + List edgeRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/ruleChains?", + new TypeReference>() {}, new PageLink(100)).getData(); + Assert.assertTrue(edgeRuleChains.contains(ruleChain)); + + testAutoGeneratedCodeByProtobuf(ruleChainUpdateMsg); + + log.info("Received data checked"); } private void testDevices() throws Exception { @@ -416,6 +510,67 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { log.info("RuleChains tested successfully"); } + private void testRuleChainMetadataRequestMsg(RuleChainId ruleChainId) throws Exception { + RuleChainMetadataRequestMsg.Builder ruleChainMetadataRequestMsgBuilder = RuleChainMetadataRequestMsg.newBuilder() + .setRuleChainIdMSB(ruleChainId.getId().getMostSignificantBits()) + .setRuleChainIdLSB(ruleChainId.getId().getLeastSignificantBits()); + testAutoGeneratedCodeByProtobuf(ruleChainMetadataRequestMsgBuilder); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder() + .addRuleChainMetadataRequestMsg(ruleChainMetadataRequestMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); + RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = (RuleChainMetadataUpdateMsg) latestMessage; + RuleChainId receivedRuleChainId = + new RuleChainId(new UUID(ruleChainMetadataUpdateMsg.getRuleChainIdMSB(), ruleChainMetadataUpdateMsg.getRuleChainIdLSB())); + Assert.assertEquals(ruleChainId, receivedRuleChainId); + } + + private void createRuleChainMetadata(RuleChain ruleChain) throws Exception { + RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); + ruleChainMetaData.setRuleChainId(ruleChain.getId()); + + ObjectMapper mapper = new ObjectMapper(); + + RuleNode ruleNode1 = new RuleNode(); + ruleNode1.setName("name1"); + ruleNode1.setType("type1"); + ruleNode1.setConfiguration(mapper.readTree("\"key1\": \"val1\"")); + + RuleNode ruleNode2 = new RuleNode(); + ruleNode2.setName("name2"); + ruleNode2.setType("type2"); + ruleNode2.setConfiguration(mapper.readTree("\"key2\": \"val2\"")); + + RuleNode ruleNode3 = new RuleNode(); + ruleNode3.setName("name3"); + ruleNode3.setType("type3"); + ruleNode3.setConfiguration(mapper.readTree("\"key3\": \"val3\"")); + + List ruleNodes = new ArrayList<>(); + ruleNodes.add(ruleNode1); + ruleNodes.add(ruleNode2); + ruleNodes.add(ruleNode3); + ruleChainMetaData.setFirstNodeIndex(0); + ruleChainMetaData.setNodes(ruleNodes); + + ruleChainMetaData.addConnectionInfo(0, 1, "success"); + ruleChainMetaData.addConnectionInfo(0, 2, "fail"); + ruleChainMetaData.addConnectionInfo(1, 2, "success"); + + ruleChainMetaData.addRuleChainConnectionInfo(2, edge.getRootRuleChainId(), "success", mapper.createObjectNode()); + + doPost("/api/ruleChain/metadata", ruleChainMetaData, RuleChainMetaData.class); + } + private void testDashboards() throws Exception { log.info("Testing Dashboards"); @@ -894,166 +1049,75 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals("key2", attributeDeleteMsg.getAttributeNames(1)); } - private Device findDeviceByName(String deviceName) throws Exception { - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() { - }, new PageLink(100)).getData(); - Optional foundDevice = edgeDevices.stream().filter(d -> d.getName().equals(deviceName)).findAny(); - Assert.assertTrue(foundDevice.isPresent()); - Device device = foundDevice.get(); - Assert.assertEquals(deviceName, device.getName()); - return device; - } - - private Asset findAssetByName(String assetName) throws Exception { - List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", - new TypeReference>() { - }, new PageLink(100)).getData(); - - Assert.assertEquals(1, edgeAssets.size()); - Asset asset = edgeAssets.get(0); - Assert.assertEquals(assetName, asset.getName()); - return asset; - } - - private Device saveDevice(String deviceName, String type) throws Exception { - Device device = new Device(); - device.setName(deviceName); - device.setType(type); - return doPost("/api/device", device, Device.class); - } - - private Asset saveAsset(String assetName) throws Exception { - Asset asset = new Asset(); - asset.setName(assetName); - asset.setType("test"); - return doPost("/api/asset", asset, Asset.class); - } - - private void testReceivedInitialData() throws Exception { - log.info("Checking received data"); - Assert.assertTrue(edgeImitator.waitForMessages()); - - EdgeConfiguration configuration = edgeImitator.getConfiguration(); - Assert.assertNotNull(configuration); - - testAutoGeneratedCodeByProtobuf(configuration); - - Optional deviceUpdateMsgOpt = edgeImitator.findMessageByType(DeviceUpdateMsg.class); - Assert.assertTrue(deviceUpdateMsgOpt.isPresent()); - DeviceUpdateMsg deviceUpdateMsg = deviceUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); - UUID deviceUUID = new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()); - Device device = doGet("/api/device/" + deviceUUID.toString(), Device.class); - Assert.assertNotNull(device); - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertTrue(edgeDevices.contains(device)); - - List deviceProfileUpdateMsgList = edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class); - Assert.assertEquals(3, deviceProfileUpdateMsgList.size()); - Optional deviceProfileUpdateMsgOpt = - deviceProfileUpdateMsgList.stream().filter(dfum -> CUSTOM_DEVICE_PROFILE_NAME.equals(dfum.getName())).findAny(); - Assert.assertTrue(deviceProfileUpdateMsgOpt.isPresent()); - DeviceProfileUpdateMsg deviceProfileUpdateMsg = deviceProfileUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); - UUID deviceProfileUUID = new UUID(deviceProfileUpdateMsg.getIdMSB(), deviceProfileUpdateMsg.getIdLSB()); - DeviceProfile deviceProfile = doGet("/api/deviceProfile/" + deviceProfileUUID.toString(), DeviceProfile.class); - Assert.assertNotNull(deviceProfile); - Assert.assertNotNull(deviceProfile.getProfileData()); - Assert.assertNotNull(deviceProfile.getProfileData().getAlarms()); - Assert.assertNotNull(deviceProfile.getProfileData().getAlarms().get(0).getClearRule()); - - testAutoGeneratedCodeByProtobuf(deviceProfileUpdateMsg); - - Optional assetUpdateMsgOpt = edgeImitator.findMessageByType(AssetUpdateMsg.class); - Assert.assertTrue(assetUpdateMsgOpt.isPresent()); - AssetUpdateMsg assetUpdateMsg = assetUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); - UUID assetUUID = new UUID(assetUpdateMsg.getIdMSB(), assetUpdateMsg.getIdLSB()); - Asset asset = doGet("/api/asset/" + assetUUID.toString(), Asset.class); - Assert.assertNotNull(asset); - List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertTrue(edgeAssets.contains(asset)); - - testAutoGeneratedCodeByProtobuf(assetUpdateMsg); - - Optional ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); - Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); - RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); - UUID ruleChainUUID = new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB()); - RuleChain ruleChain = doGet("/api/ruleChain/" + ruleChainUUID.toString(), RuleChain.class); - Assert.assertNotNull(ruleChain); - List edgeRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/ruleChains?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertTrue(edgeRuleChains.contains(ruleChain)); - - testAutoGeneratedCodeByProtobuf(ruleChainUpdateMsg); - - log.info("Received data checked"); - } - - private void testRuleChainMetadataRequestMsg(RuleChainId ruleChainId) throws Exception { - RuleChainMetadataRequestMsg.Builder ruleChainMetadataRequestMsgBuilder = RuleChainMetadataRequestMsg.newBuilder() - .setRuleChainIdMSB(ruleChainId.getId().getMostSignificantBits()) - .setRuleChainIdLSB(ruleChainId.getId().getLeastSignificantBits()); - testAutoGeneratedCodeByProtobuf(ruleChainMetadataRequestMsgBuilder); + private void testRpcCall() throws Exception { + Device device = findDeviceByName("Edge Device 1"); - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder() - .addRuleChainMetadataRequestMsg(ruleChainMetadataRequestMsgBuilder.build()); - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + ObjectNode body = mapper.createObjectNode(); + body.put("requestId", new Random().nextInt()); + body.put("requestUUID", Uuids.timeBased().toString()); + body.put("oneway", false); + body.put("expirationTime", System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10)); + body.put("method", "test_method"); + body.put("params", "{\"param1\":\"value1\"}"); - edgeImitator.expectResponsesAmount(1); + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.RPC_CALL, device.getId().getId(), EdgeEventType.DEVICE, body); edgeImitator.expectMessageAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); + edgeEventService.saveAsync(edgeEvent); + clusterService.onEdgeEventUpdate(tenantId, edge.getId()); Assert.assertTrue(edgeImitator.waitForMessages()); AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); - RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = (RuleChainMetadataUpdateMsg) latestMessage; - RuleChainId receivedRuleChainId = - new RuleChainId(new UUID(ruleChainMetadataUpdateMsg.getRuleChainIdMSB(), ruleChainMetadataUpdateMsg.getRuleChainIdLSB())); - Assert.assertEquals(ruleChainId, receivedRuleChainId); + Assert.assertTrue(latestMessage instanceof DeviceRpcCallMsg); + DeviceRpcCallMsg latestDeviceRpcCallMsg = (DeviceRpcCallMsg) latestMessage; + Assert.assertEquals("test_method", latestDeviceRpcCallMsg.getRequestMsg().getMethod()); } - private void createRuleChainMetadata(RuleChain ruleChain) throws Exception { - RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); - ruleChainMetaData.setRuleChainId(ruleChain.getId()); + private void testTimeseriesWithFailures() throws Exception { + log.info("Testing timeseries with failures"); - ObjectMapper mapper = new ObjectMapper(); + int numberOfTimeseriesToSend = 1000; - RuleNode ruleNode1 = new RuleNode(); - ruleNode1.setName("name1"); - ruleNode1.setType("type1"); - ruleNode1.setConfiguration(mapper.readTree("\"key1\": \"val1\"")); + edgeImitator.setRandomFailuresOnTimeseriesDownlink(true); + // imitator will generate failure in 5% of cases + edgeImitator.setFailureProbability(5.0); - RuleNode ruleNode2 = new RuleNode(); - ruleNode2.setName("name2"); - ruleNode2.setType("type2"); - ruleNode2.setConfiguration(mapper.readTree("\"key2\": \"val2\"")); + edgeImitator.expectMessageAmount(numberOfTimeseriesToSend); + Device device = findDeviceByName("Edge Device 1"); + for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { + String timeseriesData = "{\"data\":{\"idx\":" + idx + "},\"ts\":" + System.currentTimeMillis() + "}"; + JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, + device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); + edgeEventService.saveAsync(edgeEvent); + clusterService.onEdgeEventUpdate(tenantId, edge.getId()); + } - RuleNode ruleNode3 = new RuleNode(); - ruleNode3.setName("name3"); - ruleNode3.setType("type3"); - ruleNode3.setConfiguration(mapper.readTree("\"key3\": \"val3\"")); + Assert.assertTrue(edgeImitator.waitForMessages(60)); - List ruleNodes = new ArrayList<>(); - ruleNodes.add(ruleNode1); - ruleNodes.add(ruleNode2); - ruleNodes.add(ruleNode3); - ruleChainMetaData.setFirstNodeIndex(0); - ruleChainMetaData.setNodes(ruleNodes); + List allTelemetryMsgs = edgeImitator.findAllMessagesByType(EntityDataProto.class); + Assert.assertEquals(numberOfTimeseriesToSend, allTelemetryMsgs.size()); - ruleChainMetaData.addConnectionInfo(0, 1, "success"); - ruleChainMetaData.addConnectionInfo(0, 2, "fail"); - ruleChainMetaData.addConnectionInfo(1, 2, "success"); + for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { + Assert.assertTrue(isIdxExistsInTheDownlinkList(idx, allTelemetryMsgs)); + } - ruleChainMetaData.addRuleChainConnectionInfo(2, edge.getRootRuleChainId(), "success", mapper.createObjectNode()); + edgeImitator.setRandomFailuresOnTimeseriesDownlink(false); + log.info("Timeseries with failures tested successfully"); + } - doPost("/api/ruleChain/metadata", ruleChainMetaData, RuleChainMetaData.class); + private boolean isIdxExistsInTheDownlinkList(int idx, List allTelemetryMsgs) { + for (EntityDataProto proto : allTelemetryMsgs) { + TransportProtos.PostTelemetryMsg postTelemetryMsg = proto.getPostTelemetryMsg(); + Assert.assertEquals(1, postTelemetryMsg.getTsKvListCount()); + TransportProtos.TsKvListProto tsKvListProto = postTelemetryMsg.getTsKvList(0); + Assert.assertEquals(1, tsKvListProto.getKvCount()); + TransportProtos.KeyValueProto keyValueProto = tsKvListProto.getKv(0); + Assert.assertEquals("idx", keyValueProto.getKey()); + if (keyValueProto.getLongV() == idx) { + return true; + } + } + return false; } private void testSendMessagesToCloud() throws Exception { @@ -1527,104 +1591,42 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(expectedValue, keyValueProto.getStringV()); } - private void testRpcCall() throws Exception { - Device device = findDeviceByName("Edge Device 1"); - - ObjectNode body = mapper.createObjectNode(); - body.put("requestId", new Random().nextInt()); - body.put("requestUUID", Uuids.timeBased().toString()); - body.put("oneway", false); - body.put("expirationTime", System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10)); - body.put("method", "test_method"); - body.put("params", "{\"param1\":\"value1\"}"); - - EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.RPC_CALL, device.getId().getId(), EdgeEventType.DEVICE, body); - edgeImitator.expectMessageAmount(1); - edgeEventService.saveAsync(edgeEvent); - clusterService.onEdgeEventUpdate(tenantId, edge.getId()); - Assert.assertTrue(edgeImitator.waitForMessages()); + // Utility methods - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceRpcCallMsg); - DeviceRpcCallMsg latestDeviceRpcCallMsg = (DeviceRpcCallMsg) latestMessage; - Assert.assertEquals("test_method", latestDeviceRpcCallMsg.getRequestMsg().getMethod()); + private Device findDeviceByName(String deviceName) throws Exception { + List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", + new TypeReference>() { + }, new PageLink(100)).getData(); + Optional foundDevice = edgeDevices.stream().filter(d -> d.getName().equals(deviceName)).findAny(); + Assert.assertTrue(foundDevice.isPresent()); + Device device = foundDevice.get(); + Assert.assertEquals(deviceName, device.getName()); + return device; } - private void testTimeseriesWithFailures() throws Exception { - log.info("Testing timeseries with failures"); - - int numberOfTimeseriesToSend = 1000; - - edgeImitator.setRandomFailuresOnTimeseriesDownlink(true); - // imitator will generate failure in 5% of cases - edgeImitator.setFailureProbability(5.0); - - edgeImitator.expectMessageAmount(numberOfTimeseriesToSend); - Device device = findDeviceByName("Edge Device 1"); - for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { - String timeseriesData = "{\"data\":{\"idx\":" + idx + "},\"ts\":" + System.currentTimeMillis() + "}"; - JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); - EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, - device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); - edgeEventService.saveAsync(edgeEvent); - clusterService.onEdgeEventUpdate(tenantId, edge.getId()); - } - - Assert.assertTrue(edgeImitator.waitForMessages(60)); - - List allTelemetryMsgs = edgeImitator.findAllMessagesByType(EntityDataProto.class); - Assert.assertEquals(numberOfTimeseriesToSend, allTelemetryMsgs.size()); - - for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { - Assert.assertTrue(isIdxExistsInTheDownlinkList(idx, allTelemetryMsgs)); - } + private Asset findAssetByName(String assetName) throws Exception { + List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", + new TypeReference>() { + }, new PageLink(100)).getData(); - edgeImitator.setRandomFailuresOnTimeseriesDownlink(false); - log.info("Timeseries with failures tested successfully"); + Assert.assertEquals(1, edgeAssets.size()); + Asset asset = edgeAssets.get(0); + Assert.assertEquals(assetName, asset.getName()); + return asset; } - private boolean isIdxExistsInTheDownlinkList(int idx, List allTelemetryMsgs) { - for (EntityDataProto proto : allTelemetryMsgs) { - TransportProtos.PostTelemetryMsg postTelemetryMsg = proto.getPostTelemetryMsg(); - Assert.assertEquals(1, postTelemetryMsg.getTsKvListCount()); - TransportProtos.TsKvListProto tsKvListProto = postTelemetryMsg.getTsKvList(0); - Assert.assertEquals(1, tsKvListProto.getKvCount()); - TransportProtos.KeyValueProto keyValueProto = tsKvListProto.getKv(0); - Assert.assertEquals("idx", keyValueProto.getKey()); - if (keyValueProto.getLongV() == idx) { - return true; - } - } - return false; + private Device saveDevice(String deviceName, String type) throws Exception { + Device device = new Device(); + device.setName(deviceName); + device.setType(type); + return doPost("/api/device", device, Device.class); } - private void extendDeviceProfileData(DeviceProfile deviceProfile) { - DeviceProfileData profileData = deviceProfile.getProfileData(); - List alarms = new ArrayList<>(); - DeviceProfileAlarm deviceProfileAlarm = new DeviceProfileAlarm(); - deviceProfileAlarm.setAlarmType("High Temperature"); - AlarmRule alarmRule = new AlarmRule(); - alarmRule.setAlarmDetails("Alarm Details"); - AlarmCondition alarmCondition = new AlarmCondition(); - alarmCondition.setSpec(new SimpleAlarmConditionSpec()); - List condition = new ArrayList<>(); - AlarmConditionFilter alarmConditionFilter = new AlarmConditionFilter(); - alarmConditionFilter.setKey(new AlarmConditionFilterKey(AlarmConditionKeyType.ATTRIBUTE, "temperature")); - NumericFilterPredicate predicate = new NumericFilterPredicate(); - predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER); - predicate.setValue(new FilterPredicateValue<>(55.0)); - alarmConditionFilter.setPredicate(predicate); - alarmConditionFilter.setValueType(EntityKeyValueType.NUMERIC); - condition.add(alarmConditionFilter); - alarmCondition.setCondition(condition); - alarmRule.setCondition(alarmCondition); - deviceProfileAlarm.setClearRule(alarmRule); - TreeMap createRules = new TreeMap<>(); - createRules.put(AlarmSeverity.CRITICAL, alarmRule); - deviceProfileAlarm.setCreateRules(createRules); - alarms.add(deviceProfileAlarm); - profileData.setAlarms(alarms); - profileData.setProvisionConfiguration(new AllowCreateNewDevicesDeviceProfileProvisionConfiguration("123")); + private Asset saveAsset(String assetName) throws Exception { + Asset asset = new Asset(); + asset.setName(assetName); + asset.setType("test"); + return doPost("/api/asset", asset, Asset.class); } private EdgeEvent constructEdgeEvent(TenantId tenantId, EdgeId edgeId, EdgeEventActionType edgeEventAction, UUID entityId, EdgeEventType edgeEventType, JsonNode entityBody) { From 77c080f82b60e44a68a4f9da3814c86aac797944 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 4 Jun 2021 18:25:02 +0300 Subject: [PATCH 35/52] Device created on the edge will use that same ID on the cloud --- .../rule_chains/edge_root_rule_chain.json | 167 ------------------ .../service/edge/rpc/EdgeGrpcSession.java | 5 +- .../rpc/processor/DeviceEdgeProcessor.java | 46 ++++- .../oauth2/AbstractOAuth2ClientMapper.java | 4 +- .../thingsboard/server/edge/BaseEdgeTest.java | 25 ++- .../server/edge/imitator/EdgeImitator.java | 6 +- .../server/dao/device/DeviceService.java | 2 + .../server/dao/device/DeviceServiceImpl.java | 24 ++- 8 files changed, 84 insertions(+), 195 deletions(-) delete mode 100644 application/src/main/data/json/demo/edge_management/rule_chains/edge_root_rule_chain.json diff --git a/application/src/main/data/json/demo/edge_management/rule_chains/edge_root_rule_chain.json b/application/src/main/data/json/demo/edge_management/rule_chains/edge_root_rule_chain.json deleted file mode 100644 index a065279cce..0000000000 --- a/application/src/main/data/json/demo/edge_management/rule_chains/edge_root_rule_chain.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "ruleChain": { - "additionalInfo": null, - "name": "Edge Root Rule Chain", - "type": "EDGE", - "firstRuleNodeId": null, - "root": true, - "debugMode": false, - "configuration": null - }, - "metadata": { - "firstNodeIndex": 0, - "nodes": [ - { - "additionalInfo": { - "description": "Process incoming messages from devices with the alarm rules defined in the device profile. Dispatch all incoming messages with \"Success\" relation type.", - "layoutX": 187, - "layoutY": 468 - }, - "type": "org.thingsboard.rule.engine.profile.TbDeviceProfileNode", - "name": "Device Profile Node", - "debugMode": false, - "configuration": { - "persistAlarmRulesState": false, - "fetchAlarmRulesStateOnStart": false - } - }, - { - "additionalInfo": { - "layoutX": 823, - "layoutY": 157 - }, - "type": "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode", - "name": "Save Timeseries", - "debugMode": false, - "configuration": { - "defaultTTL": 0 - } - }, - { - "additionalInfo": { - "layoutX": 824, - "layoutY": 52 - }, - "type": "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode", - "name": "Save Client Attributes", - "debugMode": false, - "configuration": { - "scope": "CLIENT_SCOPE" - } - }, - { - "additionalInfo": { - "layoutX": 347, - "layoutY": 149 - }, - "type": "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode", - "name": "Message Type Switch", - "debugMode": false, - "configuration": { - "version": 0 - } - }, - { - "additionalInfo": { - "layoutX": 825, - "layoutY": 266 - }, - "type": "org.thingsboard.rule.engine.action.TbLogNode", - "name": "Log RPC from Device", - "debugMode": false, - "configuration": { - "jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);" - } - }, - { - "additionalInfo": { - "layoutX": 824, - "layoutY": 378 - }, - "type": "org.thingsboard.rule.engine.action.TbLogNode", - "name": "Log Other", - "debugMode": false, - "configuration": { - "jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);" - } - }, - { - "additionalInfo": { - "layoutX": 824, - "layoutY": 466 - }, - "type": "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode", - "name": "RPC Call Request", - "debugMode": false, - "configuration": { - "timeoutInSeconds": 60 - } - }, - { - "additionalInfo": { - "layoutX": 1129, - "layoutY": 52 - }, - "type": "org.thingsboard.rule.engine.edge.TbMsgPushToCloudNode", - "name": "Push to cloud", - "debugMode": false, - "configuration": { - "scope": "SERVER_SCOPE" - } - } - ], - "connections": [ - { - "fromIndex": 0, - "toIndex": 3, - "type": "Success" - }, - { - "fromIndex": 1, - "toIndex": 7, - "type": "Success" - }, - { - "fromIndex": 2, - "toIndex": 7, - "type": "Success" - }, - { - "fromIndex": 3, - "toIndex": 6, - "type": "RPC Request to Device" - }, - { - "fromIndex": 3, - "toIndex": 5, - "type": "Other" - }, - { - "fromIndex": 3, - "toIndex": 2, - "type": "Post attributes" - }, - { - "fromIndex": 3, - "toIndex": 1, - "type": "Post telemetry" - }, - { - "fromIndex": 3, - "toIndex": 4, - "type": "RPC Request from Device" - }, - { - "fromIndex": 3, - "toIndex": 7, - "type": "Attributes Updated" - }, - { - "fromIndex": 4, - "toIndex": 7, - "type": "Success" - } - ], - "ruleChainConnections": null - } -} \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 15f591694a..66e6acca34 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -87,6 +87,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -114,7 +115,7 @@ public final class EdgeGrpcSession implements Closeable { private final Consumer sessionCloseListener; private final ObjectMapper mapper; - private final Map pendingMsgsMap = new HashMap<>(); + private final Map pendingMsgsMap = new LinkedHashMap<>(); private EdgeContextComponent ctx; private Edge edge; @@ -347,7 +348,7 @@ public final class EdgeGrpcSession implements Closeable { do { log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, pendingMsgsMap.values().size()); latch = new CountDownLatch(pendingMsgsMap.values().size()); - Collection copy = new ArrayList<>(pendingMsgsMap.values()); + List copy = new ArrayList<>(pendingMsgsMap.values()); for (DownlinkMsg downlinkMsg : copy) { sendDownlinkMsg(ResponseMsg.newBuilder() .setDownlinkMsg(downlinkMsg) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java index 013e50482b..eb569db885 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.service.edge.rpc.processor; +import com.datastax.oss.driver.api.core.uuid.Uuids; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; @@ -92,7 +94,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { pageLink = pageLink.nextPageLink(); } } - Device newDevice; + if (update) { log.info("[{}] Device with name '{}' already exists on the cloud, and related to this edge [{}]. " + "deviceUpdateMsg [{}], Updating device", tenantId, deviceName, edge.getId(), deviceUpdateMsg); @@ -101,16 +103,28 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { log.info("[{}] Device with name '{}' already exists on the cloud, but not related to this edge [{}]. deviceUpdateMsg [{}]." + "Creating a new device with random prefix and relate to this edge", tenantId, deviceName, edge.getId(), deviceUpdateMsg); String newDeviceName = deviceUpdateMsg.getName() + "_" + RandomStringUtils.randomAlphabetic(15); - newDevice = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName); + Device newDevice = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName); ObjectNode body = mapper.createObjectNode(); body.put("conflictName", deviceName); - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, newDevice.getId(), body); + ListenableFuture future = + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, newDevice.getId(), body); + Futures.addCallback(future, new FutureCallback<>() { + @Override + public void onSuccess(EdgeEvent edgeEvent) { + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, newDevice.getId(), null); + } + + @Override + public void onFailure(Throwable t) { + log.error("[{}] Failed to save ENTITY_MERGE_REQUEST edge event [{}][{}]", tenantId, deviceUpdateMsg, edge.getId(), t); + } + }, dbCallbackExecutorService); } } while (pageData != null && pageData.hasNext()); } else { log.info("[{}] Creating new device and replacing device entity on the edge [{}]", tenantId, deviceUpdateMsg); device = createDevice(tenantId, edge, deviceUpdateMsg, deviceUpdateMsg.getName()); - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, device.getId(), null); + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, device.getId(), null); } break; case ENTITY_UPDATED_RPC_MESSAGE: @@ -179,8 +193,16 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { try { deviceCreationLock.lock(); log.debug("[{}] Creating device entity [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); - device = new Device(); - device.setTenantId(edge.getTenantId()); + DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); + device = deviceService.findDeviceById(tenantId, deviceId); + boolean created = false; + if (device == null) { + device = new Device(); + device.setTenantId(tenantId); + device.setId(deviceId); + device.setCreatedTime(Uuids.unixTimestamp(deviceId.getId())); + created = true; + } // make device private, if edge is public device.setCustomerId(getCustomerId(edge)); device.setName(deviceName); @@ -192,9 +214,17 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { new UUID(deviceUpdateMsg.getDeviceProfileIdMSB(), deviceUpdateMsg.getDeviceProfileIdLSB())); device.setDeviceProfileId(deviceProfileId); } - device = deviceService.saveDevice(device); + Device savedDevice = deviceService.saveDevice(device, false); + if (created) { + DeviceCredentials deviceCredentials = new DeviceCredentials(); + deviceCredentials.setDeviceId(new DeviceId(savedDevice.getUuidId())); + deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); + deviceCredentials.setCredentialsId(org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric(20)); + deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials); + + deviceStateService.onDeviceAdded(savedDevice); + } createRelationFromEdge(tenantId, edge.getId(), device.getId()); - deviceStateService.onDeviceAdded(device); pushDeviceCreatedEventToRuleEngine(tenantId, edge, device); deviceService.assignDeviceToEdge(edge.getTenantId(), device.getId(), edge.getId()); } finally { diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java index 4f38cf7a23..17f76127f6 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java @@ -177,9 +177,7 @@ public abstract class AbstractOAuth2ClientMapper { tenant.setTitle(tenantName); tenant = tenantService.saveTenant(tenant); installScripts.createDefaultRuleChains(tenant.getId()); - if (edgesEnabled) { - installScripts.createDefaultEdgeRuleChains(tenant.getId()); - } + installScripts.createDefaultEdgeRuleChains(tenant.getId()); tenantProfileCache.evict(tenant.getId()); tbClusterService.onTenantChange(tenant, null); tbClusterService.onEntityStateChange(tenant.getId(), tenant.getId(), diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java index 0e2f94eaf9..788a66acc0 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -1161,11 +1161,12 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertTrue(edgeImitator.waitForMessages()); AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); - DeviceUpdateMsg latestDeviceUpdateMsg = (DeviceUpdateMsg) latestMessage; - Assert.assertEquals("Edge Device 2", latestDeviceUpdateMsg.getName()); + Assert.assertTrue(latestMessage instanceof DeviceCredentialsRequestMsg); + DeviceCredentialsRequestMsg latestDeviceCredentialsRequestMsg = (DeviceCredentialsRequestMsg) latestMessage; + Assert.assertEquals(uuid.getMostSignificantBits(), latestDeviceCredentialsRequestMsg.getDeviceIdMSB()); + Assert.assertEquals(uuid.getLeastSignificantBits(), latestDeviceCredentialsRequestMsg.getDeviceIdLSB()); - UUID newDeviceId = new UUID(latestDeviceUpdateMsg.getIdMSB(), latestDeviceUpdateMsg.getIdLSB()); + UUID newDeviceId = new UUID(latestDeviceCredentialsRequestMsg.getDeviceIdMSB(), latestDeviceCredentialsRequestMsg.getDeviceIdLSB()); Device device = doGet("/api/device/" + newDeviceId, Device.class); Assert.assertNotNull(device); @@ -1189,7 +1190,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); edgeImitator.expectResponsesAmount(1); - edgeImitator.expectMessageAmount(1); + edgeImitator.expectMessageAmount(2); testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); @@ -1197,7 +1198,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertTrue(edgeImitator.waitForResponses()); Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + AbstractMessage latestMessage = edgeImitator.getMessageFromTail(2); Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); DeviceUpdateMsg latestDeviceUpdateMsg = (DeviceUpdateMsg) latestMessage; Assert.assertNotEquals(deviceOnCloudName, latestDeviceUpdateMsg.getName()); @@ -1210,6 +1211,18 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Device device = doGet("/api/device/" + newDeviceId, Device.class); Assert.assertNotNull(device); Assert.assertNotEquals(deviceOnCloudName, device.getName()); + + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceCredentialsRequestMsg); + DeviceCredentialsRequestMsg latestDeviceCredentialsRequestMsg = (DeviceCredentialsRequestMsg) latestMessage; + Assert.assertEquals(uuid.getMostSignificantBits(), latestDeviceCredentialsRequestMsg.getDeviceIdMSB()); + Assert.assertEquals(uuid.getLeastSignificantBits(), latestDeviceCredentialsRequestMsg.getDeviceIdLSB()); + + newDeviceId = new UUID(latestDeviceCredentialsRequestMsg.getDeviceIdMSB(), latestDeviceCredentialsRequestMsg.getDeviceIdLSB()); + + device = doGet("/api/device/" + newDeviceId, Device.class); + Assert.assertNotNull(device); + Assert.assertNotEquals(deviceOnCloudName, device.getName()); } private void sendRelationRequest() throws Exception { diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index 4988f7d1cf..64d702501a 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -334,7 +334,11 @@ public class EdgeImitator { } public AbstractMessage getLatestMessage() { - return downlinkMsgs.get(downlinkMsgs.size() - 1); + return getMessageFromTail(1); + } + + public AbstractMessage getMessageFromTail(int offset) { + return downlinkMsgs.get(downlinkMsgs.size() - offset); } public void ignoreType(Class type) { diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java index 761211f32c..162959fa5a 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java @@ -46,6 +46,8 @@ public interface DeviceService { Device findDeviceByTenantIdAndName(TenantId tenantId, String name); + Device saveDevice(Device device, boolean doValidate); + Device saveDevice(Device device); Device saveDeviceWithAccessToken(Device device, String accessToken); diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index 34aa462a6d..1081ae4c05 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -181,13 +181,19 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @CacheEvict(cacheNames = DEVICE_CACHE, key = "{#device.tenantId, #device.name}") @Override public Device saveDeviceWithAccessToken(Device device, String accessToken) { - return doSaveDevice(device, accessToken); + return doSaveDevice(device, accessToken, true); + } + + @CacheEvict(cacheNames = DEVICE_CACHE, key = "{#device.tenantId, #device.name}") + @Override + public Device saveDevice(Device device, boolean doValidate) { + return doSaveDevice(device, null, doValidate); } @CacheEvict(cacheNames = DEVICE_CACHE, key = "{#device.tenantId, #device.name}") @Override public Device saveDevice(Device device) { - return doSaveDevice(device, null); + return doSaveDevice(device, null, true); } @CacheEvict(cacheNames = DEVICE_CACHE, key = "{#device.tenantId, #device.name}") @@ -197,7 +203,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe Device deviceWithName = this.findDeviceByTenantIdAndName(device.getTenantId(), device.getName()); device = deviceWithName == null ? device : deviceWithName.updateDevice(device); } - Device savedDevice = this.saveDeviceWithoutCredentials(device); + Device savedDevice = this.saveDeviceWithoutCredentials(device, true); deviceCredentials.setDeviceId(savedDevice.getId()); if (device.getId() == null) { deviceCredentialsService.createDeviceCredentials(savedDevice.getTenantId(), deviceCredentials); @@ -212,8 +218,8 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe return savedDevice; } - private Device doSaveDevice(Device device, String accessToken) { - Device savedDevice = this.saveDeviceWithoutCredentials(device); + private Device doSaveDevice(Device device, String accessToken, boolean doValidate) { + Device savedDevice = this.saveDeviceWithoutCredentials(device, doValidate); if (device.getId() == null) { DeviceCredentials deviceCredentials = new DeviceCredentials(); deviceCredentials.setDeviceId(new DeviceId(savedDevice.getUuidId())); @@ -224,9 +230,11 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe return savedDevice; } - private Device saveDeviceWithoutCredentials(Device device) { + private Device saveDeviceWithoutCredentials(Device device, boolean doValidate) { log.trace("Executing saveDevice [{}]", device); - deviceValidator.validate(device, Device::getTenantId); + if (doValidate) { + deviceValidator.validate(device, Device::getTenantId); + } try { DeviceProfile deviceProfile; if (device.getDeviceProfileId() == null) { @@ -542,7 +550,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe device.setTenantId(tenantId); device.setCustomerId(null); - return doSaveDevice(device, null); + return doSaveDevice(device, null, true); } @Override From d30ac7d2050c17b434b6d6a66c3b1ec742ef6344 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Mon, 14 Jun 2021 17:32:14 +0300 Subject: [PATCH 36/52] Added v1 to edge package for future versioning capability --- .../service/edge/rpc/EdgeGrpcService.java | 6 +- .../service/edge/rpc/EdgeGrpcSession.java | 56 +++++++++---------- .../AdminSettingsMsgConstructor.java | 2 +- .../rpc/constructor/AlarmMsgConstructor.java | 4 +- .../rpc/constructor/AssetMsgConstructor.java | 4 +- .../constructor/CustomerMsgConstructor.java | 4 +- .../constructor/DashboardMsgConstructor.java | 4 +- .../rpc/constructor/DeviceMsgConstructor.java | 10 ++-- .../DeviceProfileMsgConstructor.java | 4 +- .../constructor/EntityDataMsgConstructor.java | 4 +- .../constructor/EntityViewMsgConstructor.java | 6 +- .../constructor/RelationMsgConstructor.java | 4 +- .../constructor/RuleChainMsgConstructor.java | 12 ++-- .../rpc/constructor/UserMsgConstructor.java | 6 +- .../constructor/WidgetTypeMsgConstructor.java | 4 +- .../WidgetsBundleMsgConstructor.java | 4 +- .../processor/AdminSettingsEdgeProcessor.java | 4 +- .../rpc/processor/AlarmEdgeProcessor.java | 6 +- .../rpc/processor/AssetEdgeProcessor.java | 6 +- .../rpc/processor/CustomerEdgeProcessor.java | 6 +- .../rpc/processor/DashboardEdgeProcessor.java | 6 +- .../rpc/processor/DeviceEdgeProcessor.java | 10 ++-- .../processor/DeviceProfileEdgeProcessor.java | 6 +- .../rpc/processor/EntityEdgeProcessor.java | 8 +-- .../processor/EntityViewEdgeProcessor.java | 6 +- .../rpc/processor/RelationEdgeProcessor.java | 6 +- .../rpc/processor/RuleChainEdgeProcessor.java | 8 +-- .../rpc/processor/TelemetryEdgeProcessor.java | 6 +- .../edge/rpc/processor/UserEdgeProcessor.java | 6 +- .../processor/WidgetBundleEdgeProcessor.java | 6 +- .../processor/WidgetTypeEdgeProcessor.java | 6 +- .../rpc/sync/DefaultEdgeRequestsService.java | 16 +++--- .../edge/rpc/sync/EdgeRequestsService.java | 16 +++--- .../controller/BaseEdgeControllerTest.java | 12 ++-- .../thingsboard/server/edge/BaseEdgeTest.java | 56 +++++++++---------- .../server/edge/imitator/EdgeImitator.java | 46 +++++++-------- .../thingsboard/edge/rpc/EdgeGrpcClient.java | 26 ++++----- .../thingsboard/edge/rpc/EdgeRpcClient.java | 10 ++-- common/edge-api/src/main/proto/edge.proto | 2 +- 39 files changed, 207 insertions(+), 207 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 09df0f4a4a..23e12f7e4e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -34,9 +34,9 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.BooleanDataEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; -import org.thingsboard.server.gen.edge.EdgeRpcServiceGrpc; -import org.thingsboard.server.gen.edge.RequestMsg; -import org.thingsboard.server.gen.edge.ResponseMsg; +import org.thingsboard.server.gen.edge.v1.EdgeRpcServiceGrpc; +import org.thingsboard.server.gen.edge.v1.RequestMsg; +import org.thingsboard.server.gen.edge.v1.ResponseMsg; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.edge.EdgeContextComponent; import org.thingsboard.server.service.state.DefaultDeviceStateService; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 66e6acca34..5badbd1a25 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -40,34 +40,34 @@ import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.gen.edge.AlarmUpdateMsg; -import org.thingsboard.server.gen.edge.AttributesRequestMsg; -import org.thingsboard.server.gen.edge.ConnectRequestMsg; -import org.thingsboard.server.gen.edge.ConnectResponseCode; -import org.thingsboard.server.gen.edge.ConnectResponseMsg; -import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; -import org.thingsboard.server.gen.edge.DeviceProfileDevicesRequestMsg; -import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; -import org.thingsboard.server.gen.edge.DeviceUpdateMsg; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.DownlinkResponseMsg; -import org.thingsboard.server.gen.edge.EdgeConfiguration; -import org.thingsboard.server.gen.edge.EdgeUpdateMsg; -import org.thingsboard.server.gen.edge.EntityDataProto; -import org.thingsboard.server.gen.edge.EntityViewsRequestMsg; -import org.thingsboard.server.gen.edge.RelationRequestMsg; -import org.thingsboard.server.gen.edge.RelationUpdateMsg; -import org.thingsboard.server.gen.edge.RequestMsg; -import org.thingsboard.server.gen.edge.RequestMsgType; -import org.thingsboard.server.gen.edge.ResponseMsg; -import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg; -import org.thingsboard.server.gen.edge.SyncCompletedMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; -import org.thingsboard.server.gen.edge.UplinkMsg; -import org.thingsboard.server.gen.edge.UplinkResponseMsg; -import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.WidgetBundleTypesRequestMsg; +import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; +import org.thingsboard.server.gen.edge.v1.AttributesRequestMsg; +import org.thingsboard.server.gen.edge.v1.ConnectRequestMsg; +import org.thingsboard.server.gen.edge.v1.ConnectResponseCode; +import org.thingsboard.server.gen.edge.v1.ConnectResponseMsg; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceProfileDevicesRequestMsg; +import org.thingsboard.server.gen.edge.v1.DeviceRpcCallMsg; +import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkResponseMsg; +import org.thingsboard.server.gen.edge.v1.EdgeConfiguration; +import org.thingsboard.server.gen.edge.v1.EdgeUpdateMsg; +import org.thingsboard.server.gen.edge.v1.EntityDataProto; +import org.thingsboard.server.gen.edge.v1.EntityViewsRequestMsg; +import org.thingsboard.server.gen.edge.v1.RelationRequestMsg; +import org.thingsboard.server.gen.edge.v1.RelationUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RequestMsg; +import org.thingsboard.server.gen.edge.v1.RequestMsgType; +import org.thingsboard.server.gen.edge.v1.ResponseMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataRequestMsg; +import org.thingsboard.server.gen.edge.v1.SyncCompletedMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.UplinkMsg; +import org.thingsboard.server.gen.edge.v1.UplinkResponseMsg; +import org.thingsboard.server.gen.edge.v1.UserCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.v1.WidgetBundleTypesRequestMsg; import org.thingsboard.server.service.edge.EdgeContextComponent; import org.thingsboard.server.service.edge.rpc.fetch.AdminSettingsEdgeEventFetcher; import org.thingsboard.server.service.edge.rpc.fetch.AssetsEdgeEventFetcher; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AdminSettingsMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AdminSettingsMsgConstructor.java index 891b42f815..b05fe7f4c2 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AdminSettingsMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AdminSettingsMsgConstructor.java @@ -18,7 +18,7 @@ package org.thingsboard.server.service.edge.rpc.constructor; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.gen.edge.AdminSettingsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.AdminSettingsUpdateMsg; import org.thingsboard.server.queue.util.TbCoreComponent; @Component diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AlarmMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AlarmMsgConstructor.java index 9d471b76ef..c1fc9f0585 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AlarmMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AlarmMsgConstructor.java @@ -26,8 +26,8 @@ import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.gen.edge.AlarmUpdateMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; @Component diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java index f78956b4f1..a835660dae 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java @@ -20,8 +20,8 @@ import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.gen.edge.AssetUpdateMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; @Component diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/CustomerMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/CustomerMsgConstructor.java index 5c0ec9ff4b..c5161a674b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/CustomerMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/CustomerMsgConstructor.java @@ -19,8 +19,8 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.gen.edge.CustomerUpdateMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; @Component diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DashboardMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DashboardMsgConstructor.java index a550d52395..f3f8573aa2 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DashboardMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DashboardMsgConstructor.java @@ -20,8 +20,8 @@ import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.gen.edge.DashboardUpdateMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; @Component diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceMsgConstructor.java index df7bfc9e1a..a28e80d80a 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceMsgConstructor.java @@ -23,11 +23,11 @@ import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.security.DeviceCredentials; -import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; -import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; -import org.thingsboard.server.gen.edge.DeviceUpdateMsg; -import org.thingsboard.server.gen.edge.RpcRequestMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceRpcCallMsg; +import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RpcRequestMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.UUID; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceProfileMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceProfileMsgConstructor.java index b5ec2cd396..a4ab0167a2 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceProfileMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceProfileMsgConstructor.java @@ -21,8 +21,8 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; -import org.thingsboard.server.gen.edge.DeviceProfileUpdateMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; @Component diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java index 1546572531..e4f79bbdf5 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java @@ -25,8 +25,8 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.transport.adaptor.JsonConverter; -import org.thingsboard.server.gen.edge.AttributeDeleteMsg; -import org.thingsboard.server.gen.edge.EntityDataProto; +import org.thingsboard.server.gen.edge.v1.AttributeDeleteMsg; +import org.thingsboard.server.gen.edge.v1.EntityDataProto; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityViewMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityViewMsgConstructor.java index 0f1e3d9e49..6b6447e1e7 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityViewMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityViewMsgConstructor.java @@ -20,9 +20,9 @@ import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.gen.edge.EdgeEntityType; -import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.EdgeEntityType; +import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; @Component diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RelationMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RelationMsgConstructor.java index c805085b6b..b4763e3f78 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RelationMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RelationMsgConstructor.java @@ -18,8 +18,8 @@ package org.thingsboard.server.service.edge.rpc.constructor; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.gen.edge.RelationUpdateMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.RelationUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; @Component diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RuleChainMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RuleChainMsgConstructor.java index c1bd3d816b..8438057a73 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RuleChainMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RuleChainMsgConstructor.java @@ -26,12 +26,12 @@ import org.thingsboard.server.common.data.rule.RuleChainConnectionInfo; import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.gen.edge.NodeConnectionInfoProto; -import org.thingsboard.server.gen.edge.RuleChainConnectionInfoProto; -import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg; -import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; -import org.thingsboard.server.gen.edge.RuleNodeProto; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.NodeConnectionInfoProto; +import org.thingsboard.server.gen.edge.v1.RuleChainConnectionInfoProto; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RuleNodeProto; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.ArrayList; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/UserMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/UserMsgConstructor.java index f69ede9210..af422cc8ab 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/UserMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/UserMsgConstructor.java @@ -21,9 +21,9 @@ import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.gen.edge.UpdateMsgType; -import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; -import org.thingsboard.server.gen.edge.UserUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; import org.thingsboard.server.queue.util.TbCoreComponent; @Component diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetTypeMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetTypeMsgConstructor.java index 672beeda75..6d8799f8fe 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetTypeMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetTypeMsgConstructor.java @@ -20,8 +20,8 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.gen.edge.UpdateMsgType; -import org.thingsboard.server.gen.edge.WidgetTypeUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; import org.thingsboard.server.queue.util.TbCoreComponent; @Component diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetsBundleMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetsBundleMsgConstructor.java index fba21ed1ca..7412fffcae 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetsBundleMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetsBundleMsgConstructor.java @@ -20,8 +20,8 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.id.TenantId; 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; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg; import org.thingsboard.server.queue.util.TbCoreComponent; import java.nio.charset.StandardCharsets; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java index 9eda3e3f81..2ee03d7a99 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java @@ -20,8 +20,8 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.EdgeEvent; -import org.thingsboard.server.gen.edge.AdminSettingsUpdateMsg; -import org.thingsboard.server.gen.edge.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.AdminSettingsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java index 9113c39ff0..32c38ce258 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java @@ -36,9 +36,9 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.gen.edge.AlarmUpdateMsg; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java index bd108e04e6..30dc80f84f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java @@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.CustomerId; -import org.thingsboard.server.gen.edge.AssetUpdateMsg; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java index d8c1c00c2e..64fae47261 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java @@ -29,9 +29,9 @@ import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.gen.edge.CustomerUpdateMsg; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java index 585298af03..dc331b45ca 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java @@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; -import org.thingsboard.server.gen.edge.DashboardUpdateMsg; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java index eb569db885..6091304e3d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java @@ -52,11 +52,11 @@ import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; -import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; -import org.thingsboard.server.gen.edge.DeviceUpdateMsg; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceRpcCallMsg; +import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.TbQueueCallback; import org.thingsboard.server.queue.TbQueueMsgMetadata; import org.thingsboard.server.queue.util.TbCoreComponent; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java index a9bc4841df..f965781f7f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java @@ -22,9 +22,9 @@ import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.DeviceProfileId; -import org.thingsboard.server.gen.edge.DeviceProfileUpdateMsg; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java index b4a591e4cc..045c7c740c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java @@ -38,10 +38,10 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainConnectionInfo; -import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.DeviceUpdateMsg; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java index 77eebccb8d..b7239b2ba8 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java @@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityViewId; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java index 94b1c97968..f647f46671 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java @@ -41,9 +41,9 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.RelationTypeGroup; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.RelationUpdateMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.RelationUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java index 6988c13892..6853570548 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java @@ -24,10 +24,10 @@ import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainMetaData; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg; -import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java index 008b20951c..ad1c4f8779 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java @@ -55,9 +55,9 @@ import org.thingsboard.server.common.msg.queue.ServiceQueue; import org.thingsboard.server.common.msg.session.SessionMsgType; import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.common.transport.util.JsonUtils; -import org.thingsboard.server.gen.edge.AttributeDeleteMsg; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.EntityDataProto; +import org.thingsboard.server.gen.edge.v1.AttributeDeleteMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.EntityDataProto; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.TbQueueCallback; import org.thingsboard.server.queue.TbQueueMsgMetadata; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java index 175b601905..e42c83eeb2 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java @@ -25,9 +25,9 @@ import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.security.UserCredentials; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; -import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java index bc8f92b45b..99f1dd0323 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java @@ -22,9 +22,9 @@ import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.widget.WidgetsBundle; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; -import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java index dcf2c447bb..a3b7172bfc 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java @@ -22,9 +22,9 @@ import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.widget.WidgetType; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; -import org.thingsboard.server.gen.edge.WidgetTypeUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java index bad62b0945..a1b686cd1a 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java @@ -63,14 +63,14 @@ import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.widget.WidgetTypeService; import org.thingsboard.server.dao.widget.WidgetsBundleService; -import org.thingsboard.server.gen.edge.AttributesRequestMsg; -import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.DeviceProfileDevicesRequestMsg; -import org.thingsboard.server.gen.edge.EntityViewsRequestMsg; -import org.thingsboard.server.gen.edge.RelationRequestMsg; -import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg; -import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.WidgetBundleTypesRequestMsg; +import org.thingsboard.server.gen.edge.v1.AttributesRequestMsg; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.v1.DeviceProfileDevicesRequestMsg; +import org.thingsboard.server.gen.edge.v1.EntityViewsRequestMsg; +import org.thingsboard.server.gen.edge.v1.RelationRequestMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataRequestMsg; +import org.thingsboard.server.gen.edge.v1.UserCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.v1.WidgetBundleTypesRequestMsg; import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.queue.TbClusterService; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/EdgeRequestsService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/EdgeRequestsService.java index 6e8caf6383..294332a664 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/EdgeRequestsService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/EdgeRequestsService.java @@ -18,14 +18,14 @@ package org.thingsboard.server.service.edge.rpc.sync; import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.gen.edge.AttributesRequestMsg; -import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.DeviceProfileDevicesRequestMsg; -import org.thingsboard.server.gen.edge.EntityViewsRequestMsg; -import org.thingsboard.server.gen.edge.RelationRequestMsg; -import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg; -import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.WidgetBundleTypesRequestMsg; +import org.thingsboard.server.gen.edge.v1.AttributesRequestMsg; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.v1.DeviceProfileDevicesRequestMsg; +import org.thingsboard.server.gen.edge.v1.EntityViewsRequestMsg; +import org.thingsboard.server.gen.edge.v1.RelationRequestMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataRequestMsg; +import org.thingsboard.server.gen.edge.v1.UserCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.v1.WidgetBundleTypesRequestMsg; public interface EdgeRequestsService { diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java index f18fd6c506..0d1f6b590d 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java @@ -37,12 +37,12 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.edge.imitator.EdgeImitator; -import org.thingsboard.server.gen.edge.AssetUpdateMsg; -import org.thingsboard.server.gen.edge.DeviceProfileUpdateMsg; -import org.thingsboard.server.gen.edge.DeviceUpdateMsg; -import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; -import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; -import org.thingsboard.server.gen.edge.UserUpdateMsg; +import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; import java.util.ArrayList; import java.util.Collections; diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java index 788a66acc0..becdfabb32 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -85,34 +85,34 @@ import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.controller.AbstractControllerTest; import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.edge.imitator.EdgeImitator; -import org.thingsboard.server.gen.edge.AlarmUpdateMsg; -import org.thingsboard.server.gen.edge.AssetUpdateMsg; -import org.thingsboard.server.gen.edge.AttributeDeleteMsg; -import org.thingsboard.server.gen.edge.AttributesRequestMsg; -import org.thingsboard.server.gen.edge.CustomerUpdateMsg; -import org.thingsboard.server.gen.edge.DashboardUpdateMsg; -import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; -import org.thingsboard.server.gen.edge.DeviceProfileUpdateMsg; -import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; -import org.thingsboard.server.gen.edge.DeviceUpdateMsg; -import org.thingsboard.server.gen.edge.EdgeConfiguration; -import org.thingsboard.server.gen.edge.EntityDataProto; -import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; -import org.thingsboard.server.gen.edge.EntityViewsRequestMsg; -import org.thingsboard.server.gen.edge.RelationRequestMsg; -import org.thingsboard.server.gen.edge.RelationUpdateMsg; -import org.thingsboard.server.gen.edge.RpcResponseMsg; -import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg; -import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg; -import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; -import org.thingsboard.server.gen.edge.UpdateMsgType; -import org.thingsboard.server.gen.edge.UplinkMsg; -import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; -import org.thingsboard.server.gen.edge.UserUpdateMsg; -import org.thingsboard.server.gen.edge.WidgetTypeUpdateMsg; -import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; +import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; +import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; +import org.thingsboard.server.gen.edge.v1.AttributeDeleteMsg; +import org.thingsboard.server.gen.edge.v1.AttributesRequestMsg; +import org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceRpcCallMsg; +import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; +import org.thingsboard.server.gen.edge.v1.EdgeConfiguration; +import org.thingsboard.server.gen.edge.v1.EntityDataProto; +import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg; +import org.thingsboard.server.gen.edge.v1.EntityViewsRequestMsg; +import org.thingsboard.server.gen.edge.v1.RelationRequestMsg; +import org.thingsboard.server.gen.edge.v1.RelationUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RpcResponseMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataRequestMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.UplinkMsg; +import org.thingsboard.server.gen.edge.v1.UserCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; +import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; +import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.service.queue.TbClusterService; diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index 64d702501a..e0361f4004 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -26,29 +26,29 @@ import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.Nullable; import org.thingsboard.edge.rpc.EdgeGrpcClient; import org.thingsboard.edge.rpc.EdgeRpcClient; -import org.thingsboard.server.gen.edge.AlarmUpdateMsg; -import org.thingsboard.server.gen.edge.AssetUpdateMsg; -import org.thingsboard.server.gen.edge.CustomerUpdateMsg; -import org.thingsboard.server.gen.edge.DashboardUpdateMsg; -import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; -import org.thingsboard.server.gen.edge.DeviceProfileUpdateMsg; -import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; -import org.thingsboard.server.gen.edge.DeviceUpdateMsg; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.DownlinkResponseMsg; -import org.thingsboard.server.gen.edge.EdgeConfiguration; -import org.thingsboard.server.gen.edge.EntityDataProto; -import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; -import org.thingsboard.server.gen.edge.RelationUpdateMsg; -import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg; -import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; -import org.thingsboard.server.gen.edge.UplinkMsg; -import org.thingsboard.server.gen.edge.UplinkResponseMsg; -import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; -import org.thingsboard.server.gen.edge.UserUpdateMsg; -import org.thingsboard.server.gen.edge.WidgetTypeUpdateMsg; -import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; +import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; +import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; +import org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceRpcCallMsg; +import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkResponseMsg; +import org.thingsboard.server.gen.edge.v1.EdgeConfiguration; +import org.thingsboard.server.gen.edge.v1.EntityDataProto; +import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RelationUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UplinkMsg; +import org.thingsboard.server.gen.edge.v1.UplinkResponseMsg; +import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; +import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; +import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg; import java.lang.reflect.Field; import java.util.ArrayList; diff --git a/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java b/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java index aeb4c38ee4..089fbe670b 100644 --- a/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java +++ b/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java @@ -24,19 +24,19 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.thingsboard.edge.exception.EdgeConnectionException; -import org.thingsboard.server.gen.edge.ConnectRequestMsg; -import org.thingsboard.server.gen.edge.ConnectResponseCode; -import org.thingsboard.server.gen.edge.ConnectResponseMsg; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.DownlinkResponseMsg; -import org.thingsboard.server.gen.edge.EdgeConfiguration; -import org.thingsboard.server.gen.edge.EdgeRpcServiceGrpc; -import org.thingsboard.server.gen.edge.RequestMsg; -import org.thingsboard.server.gen.edge.RequestMsgType; -import org.thingsboard.server.gen.edge.ResponseMsg; -import org.thingsboard.server.gen.edge.SyncRequestMsg; -import org.thingsboard.server.gen.edge.UplinkMsg; -import org.thingsboard.server.gen.edge.UplinkResponseMsg; +import org.thingsboard.server.gen.edge.v1.ConnectRequestMsg; +import org.thingsboard.server.gen.edge.v1.ConnectResponseCode; +import org.thingsboard.server.gen.edge.v1.ConnectResponseMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkResponseMsg; +import org.thingsboard.server.gen.edge.v1.EdgeConfiguration; +import org.thingsboard.server.gen.edge.v1.EdgeRpcServiceGrpc; +import org.thingsboard.server.gen.edge.v1.RequestMsg; +import org.thingsboard.server.gen.edge.v1.RequestMsgType; +import org.thingsboard.server.gen.edge.v1.ResponseMsg; +import org.thingsboard.server.gen.edge.v1.SyncRequestMsg; +import org.thingsboard.server.gen.edge.v1.UplinkMsg; +import org.thingsboard.server.gen.edge.v1.UplinkResponseMsg; import javax.net.ssl.SSLException; import java.io.File; diff --git a/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeRpcClient.java b/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeRpcClient.java index 83ff20828b..e9a6a1158d 100644 --- a/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeRpcClient.java +++ b/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeRpcClient.java @@ -15,11 +15,11 @@ */ package org.thingsboard.edge.rpc; -import org.thingsboard.server.gen.edge.DownlinkMsg; -import org.thingsboard.server.gen.edge.DownlinkResponseMsg; -import org.thingsboard.server.gen.edge.EdgeConfiguration; -import org.thingsboard.server.gen.edge.UplinkMsg; -import org.thingsboard.server.gen.edge.UplinkResponseMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkMsg; +import org.thingsboard.server.gen.edge.v1.DownlinkResponseMsg; +import org.thingsboard.server.gen.edge.v1.EdgeConfiguration; +import org.thingsboard.server.gen.edge.v1.UplinkMsg; +import org.thingsboard.server.gen.edge.v1.UplinkResponseMsg; import java.util.function.Consumer; diff --git a/common/edge-api/src/main/proto/edge.proto b/common/edge-api/src/main/proto/edge.proto index ea6b47defb..52f1c76f61 100644 --- a/common/edge-api/src/main/proto/edge.proto +++ b/common/edge-api/src/main/proto/edge.proto @@ -15,7 +15,7 @@ */ syntax = "proto3"; -option java_package = "org.thingsboard.server.gen.edge"; +option java_package = "org.thingsboard.server.gen.edge.v1"; option java_multiple_files = true; option java_outer_classname = "EdgeProtos"; From 94bc3e2d1b82e8295545e86024c840e7b05092b0 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Mon, 14 Jun 2021 18:20:14 +0300 Subject: [PATCH 37/52] Changed method usage - single set instead of collection --- .../edge/rpc/processor/AdminSettingsEdgeProcessor.java | 6 ++---- .../service/edge/rpc/processor/AlarmEdgeProcessor.java | 3 +-- .../service/edge/rpc/processor/AssetEdgeProcessor.java | 6 ++---- .../edge/rpc/processor/CustomerEdgeProcessor.java | 5 ++--- .../edge/rpc/processor/DashboardEdgeProcessor.java | 4 ++-- .../service/edge/rpc/processor/DeviceEdgeProcessor.java | 9 ++++----- .../edge/rpc/processor/DeviceProfileEdgeProcessor.java | 6 ++---- .../service/edge/rpc/processor/EntityEdgeProcessor.java | 7 +++---- .../edge/rpc/processor/EntityViewEdgeProcessor.java | 6 ++---- .../edge/rpc/processor/RelationEdgeProcessor.java | 5 ++--- .../edge/rpc/processor/RuleChainEdgeProcessor.java | 8 +++----- .../edge/rpc/processor/TelemetryEdgeProcessor.java | 3 +-- .../service/edge/rpc/processor/UserEdgeProcessor.java | 8 +++----- .../edge/rpc/processor/WidgetBundleEdgeProcessor.java | 6 ++---- .../edge/rpc/processor/WidgetTypeEdgeProcessor.java | 6 ++---- 15 files changed, 33 insertions(+), 55 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java index 2ee03d7a99..79413b724d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AdminSettingsEdgeProcessor.java @@ -24,8 +24,6 @@ import org.thingsboard.server.gen.edge.v1.AdminSettingsUpdateMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.queue.util.TbCoreComponent; -import java.util.Collections; - @Component @Slf4j @TbCoreComponent @@ -33,10 +31,10 @@ public class AdminSettingsEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processAdminSettingsToEdge(EdgeEvent edgeEvent) { AdminSettings adminSettings = mapper.convertValue(edgeEvent.getBody(), AdminSettings.class); - AdminSettingsUpdateMsg t = adminSettingsMsgConstructor.constructAdminSettingsUpdateMsg(adminSettings); + AdminSettingsUpdateMsg adminSettingsUpdateMsg = adminSettingsMsgConstructor.constructAdminSettingsUpdateMsg(adminSettings); return DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllAdminSettingsUpdateMsg(Collections.singletonList(t)) + .addAdminSettingsUpdateMsg(adminSettingsUpdateMsg) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java index 32c38ce258..c2e5dc2e3e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java @@ -42,7 +42,6 @@ import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; -import java.util.Collections; import java.util.UUID; @Component @@ -122,7 +121,7 @@ public class AlarmEdgeProcessor extends BaseEdgeProcessor { if (alarm != null) { downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllAlarmUpdateMsg(Collections.singletonList(alarmMsgConstructor.constructAlarmUpdatedMsg(edge.getTenantId(), msgType, alarm))) + .addAlarmUpdateMsg(alarmMsgConstructor.constructAlarmUpdatedMsg(edge.getTenantId(), msgType, alarm)) .build(); } } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java index 30dc80f84f..38b467d8ac 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AssetEdgeProcessor.java @@ -29,8 +29,6 @@ import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; -import java.util.Collections; - @Component @Slf4j @TbCoreComponent @@ -52,7 +50,7 @@ public class AssetEdgeProcessor extends BaseEdgeProcessor { assetMsgConstructor.constructAssetUpdatedMsg(msgType, asset, customerId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllAssetUpdateMsg(Collections.singletonList(assetUpdateMsg)) + .addAssetUpdateMsg(assetUpdateMsg) .build(); } break; @@ -62,7 +60,7 @@ public class AssetEdgeProcessor extends BaseEdgeProcessor { assetMsgConstructor.constructAssetDeleteMsg(assetId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllAssetUpdateMsg(Collections.singletonList(assetUpdateMsg)) + .addAssetUpdateMsg(assetUpdateMsg) .build(); break; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java index 64fae47261..0aeb485ff1 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java @@ -35,7 +35,6 @@ import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; -import java.util.Collections; import java.util.UUID; @Component @@ -55,7 +54,7 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor { customerMsgConstructor.constructCustomerUpdatedMsg(msgType, customer); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllCustomerUpdateMsg(Collections.singletonList(customerUpdateMsg)) + .addCustomerUpdateMsg(customerUpdateMsg) .build(); } break; @@ -64,7 +63,7 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor { customerMsgConstructor.constructCustomerDeleteMsg(customerId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllCustomerUpdateMsg(Collections.singletonList(customerUpdateMsg)) + .addCustomerUpdateMsg(customerUpdateMsg) .build(); break; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java index dc331b45ca..84aba5792c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DashboardEdgeProcessor.java @@ -55,7 +55,7 @@ public class DashboardEdgeProcessor extends BaseEdgeProcessor { dashboardMsgConstructor.constructDashboardUpdatedMsg(msgType, dashboard, customerId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllDashboardUpdateMsg(Collections.singletonList(dashboardUpdateMsg)) + .addDashboardUpdateMsg(dashboardUpdateMsg) .build(); } break; @@ -65,7 +65,7 @@ public class DashboardEdgeProcessor extends BaseEdgeProcessor { dashboardMsgConstructor.constructDashboardDeleteMsg(dashboardId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllDashboardUpdateMsg(Collections.singletonList(dashboardUpdateMsg)) + .addDashboardUpdateMsg(dashboardUpdateMsg) .build(); break; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java index 6091304e3d..ccf0552daa 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java @@ -63,7 +63,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; -import java.util.Collections; import java.util.UUID; import java.util.concurrent.locks.ReentrantLock; @@ -340,7 +339,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { deviceMsgConstructor.constructDeviceUpdatedMsg(msgType, device, customerId, null); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg)) + .addDeviceUpdateMsg(deviceUpdateMsg) .build(); } break; @@ -350,7 +349,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { deviceMsgConstructor.constructDeviceDeleteMsg(deviceId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg)) + .addDeviceUpdateMsg(deviceUpdateMsg) .build(); break; case CREDENTIALS_UPDATED: @@ -360,7 +359,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { deviceMsgConstructor.constructDeviceCredentialsUpdatedMsg(deviceCredentials); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllDeviceCredentialsUpdateMsg(Collections.singletonList(deviceCredentialsUpdateMsg)) + .addDeviceCredentialsUpdateMsg(deviceCredentialsUpdateMsg) .build(); } break; @@ -374,7 +373,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { deviceMsgConstructor.constructDeviceRpcCallMsg(edgeEvent.getEntityId(), edgeEvent.getBody()); return DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllDeviceRpcCallMsg(Collections.singletonList(deviceRpcCallMsg)) + .addDeviceRpcCallMsg(deviceRpcCallMsg) .build(); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java index f965781f7f..5d4316e23a 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProfileEdgeProcessor.java @@ -27,8 +27,6 @@ import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; -import java.util.Collections; - @Component @Slf4j @TbCoreComponent @@ -46,7 +44,7 @@ public class DeviceProfileEdgeProcessor extends BaseEdgeProcessor { deviceProfileMsgConstructor.constructDeviceProfileUpdatedMsg(msgType, deviceProfile); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllDeviceProfileUpdateMsg(Collections.singletonList(deviceProfileUpdateMsg)) + .addDeviceProfileUpdateMsg(deviceProfileUpdateMsg) .build(); } break; @@ -55,7 +53,7 @@ public class DeviceProfileEdgeProcessor extends BaseEdgeProcessor { deviceProfileMsgConstructor.constructDeviceProfileDeleteMsg(deviceProfileId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllDeviceProfileUpdateMsg(Collections.singletonList(deviceProfileUpdateMsg)) + .addDeviceProfileUpdateMsg(deviceProfileUpdateMsg) .build(); break; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java index 045c7c740c..8214ae9e5e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java @@ -45,7 +45,6 @@ import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; -import java.util.Collections; import java.util.List; import java.util.UUID; @@ -64,11 +63,11 @@ public class EntityEdgeProcessor extends BaseEdgeProcessor { if(edgeEvent.getBody() != null) { conflictName = edgeEvent.getBody().get("conflictName").asText(); } - DeviceUpdateMsg d = deviceMsgConstructor + DeviceUpdateMsg deviceUpdateMsg = deviceMsgConstructor .constructDeviceUpdatedMsg(UpdateMsgType.ENTITY_MERGE_RPC_MESSAGE, device, customerId, conflictName); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllDeviceUpdateMsg(Collections.singletonList(d)) + .addDeviceUpdateMsg(deviceUpdateMsg) .build(); } return downlinkMsg; @@ -84,7 +83,7 @@ public class EntityEdgeProcessor extends BaseEdgeProcessor { .build(); DownlinkMsg.Builder builder = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllDeviceCredentialsRequestMsg(Collections.singletonList(deviceCredentialsRequestMsg)); + .addDeviceCredentialsRequestMsg(deviceCredentialsRequestMsg); downlinkMsg = builder.build(); } return downlinkMsg; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java index b7239b2ba8..33123a0d0f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityViewEdgeProcessor.java @@ -29,8 +29,6 @@ import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg; import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; -import java.util.Collections; - @Component @Slf4j @TbCoreComponent @@ -52,7 +50,7 @@ public class EntityViewEdgeProcessor extends BaseEdgeProcessor { entityViewMsgConstructor.constructEntityViewUpdatedMsg(msgType, entityView, customerId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllEntityViewUpdateMsg(Collections.singletonList(entityViewUpdateMsg)) + .addEntityViewUpdateMsg(entityViewUpdateMsg) .build(); } break; @@ -62,7 +60,7 @@ public class EntityViewEdgeProcessor extends BaseEdgeProcessor { entityViewMsgConstructor.constructEntityViewDeleteMsg(entityViewId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllEntityViewUpdateMsg(Collections.singletonList(entityViewUpdateMsg)) + .addEntityViewUpdateMsg(entityViewUpdateMsg) .build(); break; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java index f647f46671..6318356a47 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java @@ -48,7 +48,6 @@ import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -118,10 +117,10 @@ public class RelationEdgeProcessor extends BaseEdgeProcessor { public DownlinkMsg processRelationToEdge(EdgeEvent edgeEvent, UpdateMsgType msgType) { EntityRelation entityRelation = mapper.convertValue(edgeEvent.getBody(), EntityRelation.class); - RelationUpdateMsg r = relationMsgConstructor.constructRelationUpdatedMsg(msgType, entityRelation); + RelationUpdateMsg relationUpdateMsg = relationMsgConstructor.constructRelationUpdatedMsg(msgType, entityRelation); return DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllRelationUpdateMsg(Collections.singletonList(r)) + .addRelationUpdateMsg(relationUpdateMsg) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java index 6853570548..5ead8c5623 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RuleChainEdgeProcessor.java @@ -30,8 +30,6 @@ import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg; import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.queue.util.TbCoreComponent; -import java.util.Collections; - @Component @Slf4j @TbCoreComponent @@ -50,7 +48,7 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor { ruleChainMsgConstructor.constructRuleChainUpdatedMsg(edge.getRootRuleChainId(), msgType, ruleChain); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllRuleChainUpdateMsg(Collections.singletonList(ruleChainUpdateMsg)) + .addRuleChainUpdateMsg(ruleChainUpdateMsg) .build(); } break; @@ -58,7 +56,7 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor { case UNASSIGNED_FROM_EDGE: downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllRuleChainUpdateMsg(Collections.singletonList(ruleChainMsgConstructor.constructRuleChainDeleteMsg(ruleChainId))) + .addRuleChainUpdateMsg(ruleChainMsgConstructor.constructRuleChainDeleteMsg(ruleChainId)) .build(); break; } @@ -76,7 +74,7 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor { if (ruleChainMetadataUpdateMsg != null) { downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllRuleChainMetadataUpdateMsg(Collections.singletonList(ruleChainMetadataUpdateMsg)) + .addRuleChainMetadataUpdateMsg(ruleChainMetadataUpdateMsg) .build(); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java index ad1c4f8779..7aea556544 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryEdgeProcessor.java @@ -65,7 +65,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import javax.annotation.Nullable; import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -323,7 +322,7 @@ public class TelemetryEdgeProcessor extends BaseEdgeProcessor { EntityDataProto entityDataProto = entityDataMsgConstructor.constructEntityDataMsg(entityId, actionType, entityData); return DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllEntityData(Collections.singletonList(entityDataProto)) + .addEntityData(entityDataProto) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java index e42c83eeb2..0c1135ab09 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/UserEdgeProcessor.java @@ -30,8 +30,6 @@ import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; import org.thingsboard.server.queue.util.TbCoreComponent; -import java.util.Collections; - @Component @Slf4j @TbCoreComponent @@ -48,14 +46,14 @@ public class UserEdgeProcessor extends BaseEdgeProcessor { CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(user, edge); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllUserUpdateMsg(Collections.singletonList(userMsgConstructor.constructUserUpdatedMsg(msgType, user, customerId))) + .addUserUpdateMsg(userMsgConstructor.constructUserUpdatedMsg(msgType, user, customerId)) .build(); } break; case DELETED: downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllUserUpdateMsg(Collections.singletonList(userMsgConstructor.constructUserDeleteMsg(userId))) + .addUserUpdateMsg(userMsgConstructor.constructUserDeleteMsg(userId)) .build(); break; case CREDENTIALS_UPDATED: @@ -65,7 +63,7 @@ public class UserEdgeProcessor extends BaseEdgeProcessor { userMsgConstructor.constructUserCredentialsUpdatedMsg(userCredentialsByUserId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllUserCredentialsUpdateMsg(Collections.singletonList(userCredentialsUpdateMsg)) + .addUserCredentialsUpdateMsg(userCredentialsUpdateMsg) .build(); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java index 99f1dd0323..2dbcc65ec3 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetBundleEdgeProcessor.java @@ -27,8 +27,6 @@ import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg; import org.thingsboard.server.queue.util.TbCoreComponent; -import java.util.Collections; - @Component @Slf4j @TbCoreComponent @@ -46,7 +44,7 @@ public class WidgetBundleEdgeProcessor extends BaseEdgeProcessor { widgetsBundleMsgConstructor.constructWidgetsBundleUpdateMsg(msgType, widgetsBundle); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllWidgetsBundleUpdateMsg(Collections.singletonList(widgetsBundleUpdateMsg)) + .addWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg) .build(); } break; @@ -55,7 +53,7 @@ public class WidgetBundleEdgeProcessor extends BaseEdgeProcessor { widgetsBundleMsgConstructor.constructWidgetsBundleDeleteMsg(widgetsBundleId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllWidgetsBundleUpdateMsg(Collections.singletonList(widgetsBundleUpdateMsg)) + .addWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg) .build(); break; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java index a3b7172bfc..de4e0e9a06 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/WidgetTypeEdgeProcessor.java @@ -27,8 +27,6 @@ import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; import org.thingsboard.server.queue.util.TbCoreComponent; -import java.util.Collections; - @Component @Slf4j @TbCoreComponent @@ -46,7 +44,7 @@ public class WidgetTypeEdgeProcessor extends BaseEdgeProcessor { widgetTypeMsgConstructor.constructWidgetTypeUpdateMsg(msgType, widgetType); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllWidgetTypeUpdateMsg(Collections.singletonList(widgetTypeUpdateMsg)) + .addWidgetTypeUpdateMsg(widgetTypeUpdateMsg) .build(); } break; @@ -55,7 +53,7 @@ public class WidgetTypeEdgeProcessor extends BaseEdgeProcessor { widgetTypeMsgConstructor.constructWidgetTypeDeleteMsg(widgetTypeId); downlinkMsg = DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .addAllWidgetTypeUpdateMsg(Collections.singletonList(widgetTypeUpdateMsg)) + .addWidgetTypeUpdateMsg(widgetTypeUpdateMsg) .build(); break; } From 2f82feee28c504aace41d79c44a7af845f35e0bb Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 22 Jun 2021 19:27:15 +0300 Subject: [PATCH 38/52] Added checks for null values. Error msg can not be null when setting to grpc response --- .../thingsboard/server/service/edge/rpc/EdgeGrpcSession.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 5badbd1a25..82aeab69ef 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -249,9 +249,10 @@ public final class EdgeGrpcSession implements Closeable { @Override public void onFailure(Throwable t) { + String errorMsg = t.getMessage() != null ? t.getMessage() : ""; UplinkResponseMsg uplinkResponseMsg = UplinkResponseMsg.newBuilder() .setUplinkMsgId(uplinkMsg.getUplinkMsgId()) - .setSuccess(false).setErrorMsg(t.getMessage()).build(); + .setSuccess(false).setErrorMsg(errorMsg).build(); sendDownlinkMsg(ResponseMsg.newBuilder() .setUplinkResponseMsg(uplinkResponseMsg) .build()); From 20a230fdacc5151ba51464af748e851bdf229588 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 23 Jun 2021 10:41:03 +0300 Subject: [PATCH 39/52] Fixed error text msg --- .../thingsboard/server/service/install/InstallScripts.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java index bf71f94847..d5a4365963 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java +++ b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java @@ -228,14 +228,14 @@ public class InstallScripts { } } - public void loadDemoRuleChains(TenantId tenantId) throws Exception { + public void loadDemoRuleChains(TenantId tenantId) { try { createDefaultRuleChains(tenantId); createDefaultRuleChain(tenantId, "Thermostat"); createDefaultEdgeRuleChains(tenantId); } catch (Exception e) { - log.error("Unable to load dashboard from json", e); - throw new RuntimeException("Unable to load dashboard from json", e); + log.error("Unable to load rule chain from json", e); + throw new RuntimeException("Unable to load rule chain from json", e); } } From c85aea31a0a8c00cc5a834d4d5c780861da3de14 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 23 Jun 2021 17:27:06 +0300 Subject: [PATCH 40/52] Added possibility to disable validation for save edge function --- .../server/controller/EdgeController.java | 2 +- .../edge/DefaultEdgeNotificationService.java | 2 +- .../server/dao/edge/EdgeService.java | 2 +- .../server/dao/edge/EdgeServiceImpl.java | 10 ++-- .../dao/service/BaseDashboardServiceTest.java | 2 +- .../dao/service/BaseEdgeServiceTest.java | 48 +++++++++---------- .../dao/service/BaseEntityServiceTest.java | 4 +- .../dao/service/BaseRuleChainServiceTest.java | 2 +- 8 files changed, 37 insertions(+), 35 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java index c71f1a7a74..501febaead 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java @@ -127,7 +127,7 @@ public class EdgeController extends BaseController { accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, operation, edge.getId(), edge); - Edge savedEdge = checkNotNull(edgeService.saveEdge(edge)); + Edge savedEdge = checkNotNull(edgeService.saveEdge(edge, true)); if (created) { ruleChainService.assignRuleChainToEdge(tenantId, edgeTemplateRootRuleChain.getId(), savedEdge.getId()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java index aae6ac17ab..c861207f2d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java @@ -100,7 +100,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { @Override public Edge setEdgeRootRuleChain(TenantId tenantId, Edge edge, RuleChainId ruleChainId) throws IOException { edge.setRootRuleChainId(ruleChainId); - Edge savedEdge = edgeService.saveEdge(edge); + Edge savedEdge = edgeService.saveEdge(edge, true); saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, EdgeEventActionType.UPDATED, ruleChainId, null); return savedEdge; } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java index 93e1a0c51f..f9d09a43ae 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java @@ -44,7 +44,7 @@ public interface EdgeService { Optional findEdgeByRoutingKey(TenantId tenantId, String routingKey); - Edge saveEdge(Edge edge); + Edge saveEdge(Edge edge, boolean doValidate); Edge assignEdgeToCustomer(TenantId tenantId, EdgeId edgeId, CustomerId customerId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index 3e828424d9..59291bc320 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -180,9 +180,11 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @CacheEvict(cacheNames = EDGE_CACHE, key = "{#edge.tenantId, #edge.name}") @Override - public Edge saveEdge(Edge edge) { + public Edge saveEdge(Edge edge, boolean doValidate) { log.trace("Executing saveEdge [{}]", edge); - edgeValidator.validate(edge, Edge::getTenantId); + if (doValidate) { + edgeValidator.validate(edge, Edge::getTenantId); + } try { return edgeDao.save(edge.getTenantId(), edge); } catch (Exception t) { @@ -201,7 +203,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic log.trace("[{}] Executing assignEdgeToCustomer [{}][{}]", tenantId, edgeId, customerId); Edge edge = findEdgeById(tenantId, edgeId); edge.setCustomerId(customerId); - return saveEdge(edge); + return saveEdge(edge, true); } @Override @@ -209,7 +211,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic log.trace("[{}] Executing unassignEdgeFromCustomer [{}]", tenantId, edgeId); Edge edge = findEdgeById(tenantId, edgeId); edge.setCustomerId(null); - return saveEdge(edge); + return saveEdge(edge, true); } @Override diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseDashboardServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseDashboardServiceTest.java index 98b1110ddc..c59f4fcc4b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseDashboardServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseDashboardServiceTest.java @@ -360,7 +360,7 @@ public abstract class BaseDashboardServiceTest extends AbstractServiceTest { edge.setRoutingKey(RandomStringUtils.randomAlphanumeric(20)); edge.setEdgeLicenseKey(RandomStringUtils.randomAlphanumeric(20)); edge.setCloudEndpoint("http://localhost:8080"); - edge = edgeService.saveEdge(edge); + edge = edgeService.saveEdge(edge, true); try { dashboardService.assignDashboardToEdge(tenantId, dashboard.getId(), edge.getId()); } finally { diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeServiceTest.java index 1d8b6b6cb0..631fcff8da 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeServiceTest.java @@ -60,7 +60,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { @Test public void testSaveEdge() { Edge edge = constructEdge("My edge", "default"); - Edge savedEdge = edgeService.saveEdge(edge); + Edge savedEdge = edgeService.saveEdge(edge, true); Assert.assertNotNull(savedEdge); Assert.assertNotNull(savedEdge.getId()); @@ -72,7 +72,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { savedEdge.setName("My new edge"); - edgeService.saveEdge(savedEdge); + edgeService.saveEdge(savedEdge, true); Edge foundEdge = edgeService.findEdgeById(tenantId, savedEdge.getId()); Assert.assertEquals(foundEdge.getName(), savedEdge.getName()); @@ -84,7 +84,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { Edge edge = new Edge(); edge.setType("default"); edge.setTenantId(tenantId); - edgeService.saveEdge(edge); + edgeService.saveEdge(edge, true); } @Test(expected = DataValidationException.class) @@ -92,7 +92,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { Edge edge = new Edge(); edge.setName("My edge"); edge.setType("default"); - edgeService.saveEdge(edge); + edgeService.saveEdge(edge, true); } @Test(expected = DataValidationException.class) @@ -101,13 +101,13 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { edge.setName("My edge"); edge.setType("default"); edge.setTenantId(new TenantId(Uuids.timeBased())); - edgeService.saveEdge(edge); + edgeService.saveEdge(edge, true); } @Test(expected = DataValidationException.class) public void testAssignEdgeToNonExistentCustomer() { Edge edge = constructEdge("My edge", "default"); - edge = edgeService.saveEdge(edge); + edge = edgeService.saveEdge(edge, true); try { edgeService.assignEdgeToCustomer(tenantId, edge.getId(), new CustomerId(Uuids.timeBased())); } finally { @@ -118,7 +118,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { @Test(expected = DataValidationException.class) public void testAssignEdgeToCustomerFromDifferentTenant() { Edge edge = constructEdge("My edge", "default"); - edge = edgeService.saveEdge(edge); + edge = edgeService.saveEdge(edge, true); Tenant tenant = new Tenant(); tenant.setTitle("Test different tenant"); tenant = tenantService.saveTenant(tenant); @@ -137,7 +137,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { @Test public void testFindEdgeById() { Edge edge = constructEdge("My edge", "default"); - Edge savedEdge = edgeService.saveEdge(edge); + Edge savedEdge = edgeService.saveEdge(edge, true); Edge foundEdge = edgeService.findEdgeById(tenantId, savedEdge.getId()); Assert.assertNotNull(foundEdge); Assert.assertEquals(savedEdge, foundEdge); @@ -150,15 +150,15 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { try { for (int i = 0; i < 3; i++) { Edge edge = constructEdge("My edge B" + i, "typeB"); - edges.add(edgeService.saveEdge(edge)); + edges.add(edgeService.saveEdge(edge, true)); } for (int i = 0; i < 7; i++) { Edge edge = constructEdge("My edge C" + i, "typeC"); - edges.add(edgeService.saveEdge(edge)); + edges.add(edgeService.saveEdge(edge, true)); } for (int i = 0; i < 9; i++) { Edge edge = constructEdge("My edge A" + i, "typeA"); - edges.add(edgeService.saveEdge(edge)); + edges.add(edgeService.saveEdge(edge, true)); } List edgeTypes = edgeService.findEdgeTypesByTenantId(tenantId).get(); Assert.assertNotNull(edgeTypes); @@ -176,7 +176,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { @Test public void testDeleteEdge() { Edge edge = constructEdge("My edge", "default"); - Edge savedEdge = edgeService.saveEdge(edge); + Edge savedEdge = edgeService.saveEdge(edge, true); Edge foundEdge = edgeService.findEdgeById(tenantId, savedEdge.getId()); Assert.assertNotNull(foundEdge); edgeService.deleteEdge(tenantId, savedEdge.getId()); @@ -195,7 +195,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { List edges = new ArrayList<>(); for (int i = 0; i < 178; i++) { Edge edge = constructEdge(tenantId, "Edge " + i, "default"); - edges.add(edgeService.saveEdge(edge)); + edges.add(edgeService.saveEdge(edge, true)); } List loadedEdges = new ArrayList<>(); @@ -233,7 +233,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { String name = title1 + suffix; name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); Edge edge = constructEdge(name, "default"); - edgesTitle1.add(edgeService.saveEdge(edge)); + edgesTitle1.add(edgeService.saveEdge(edge, true)); } String title2 = "Edge title 2"; List edgesTitle2 = new ArrayList<>(); @@ -242,7 +242,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { String name = title2 + suffix; name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); Edge edge = constructEdge(name, "default"); - edgesTitle2.add(edgeService.saveEdge(edge)); + edgesTitle2.add(edgeService.saveEdge(edge, true)); } List loadedEdgesTitle1 = new ArrayList<>(); @@ -305,7 +305,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { String name = title1 + suffix; name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); Edge edge = constructEdge(name, type1); - edgesType1.add(edgeService.saveEdge(edge)); + edgesType1.add(edgeService.saveEdge(edge, true)); } String title2 = "Edge title 2"; String type2 = "typeB"; @@ -315,7 +315,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { String name = title2 + suffix; name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); Edge edge = constructEdge(name, type2); - edgesType2.add(edgeService.saveEdge(edge)); + edgesType2.add(edgeService.saveEdge(edge, true)); } List loadedEdgesType1 = new ArrayList<>(); @@ -385,7 +385,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { List edges = new ArrayList<>(); for (int i = 0; i < 278; i++) { Edge edge = constructEdge(tenantId, "Edge" + i, "default"); - edge = edgeService.saveEdge(edge); + edge = edgeService.saveEdge(edge, true); edges.add(edgeService.assignEdgeToCustomer(tenantId, edge.getId(), customerId)); } @@ -431,7 +431,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { String name = title1 + suffix; name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); Edge edge = constructEdge(name, "default"); - edge = edgeService.saveEdge(edge); + edge = edgeService.saveEdge(edge, true); edgesTitle1.add(edgeService.assignEdgeToCustomer(tenantId, edge.getId(), customerId)); } String title2 = "Edge title 2"; @@ -441,7 +441,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { String name = title2 + suffix; name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); Edge edge = constructEdge(name, "default"); - edge = edgeService.saveEdge(edge); + edge = edgeService.saveEdge(edge, true); edgesTitle2.add(edgeService.assignEdgeToCustomer(tenantId, edge.getId(), customerId)); } @@ -513,7 +513,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { String name = title1 + suffix; name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); Edge edge = constructEdge(name, type1); - edge = edgeService.saveEdge(edge); + edge = edgeService.saveEdge(edge, true); edgesType1.add(edgeService.assignEdgeToCustomer(tenantId, edge.getId(), customerId)); } String title2 = "Edge title 2"; @@ -524,7 +524,7 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { String name = title2 + suffix; name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase(); Edge edge = constructEdge(name, type2); - edge = edgeService.saveEdge(edge); + edge = edgeService.saveEdge(edge, true); edgesType2.add(edgeService.assignEdgeToCustomer(tenantId, edge.getId(), customerId)); } @@ -589,12 +589,12 @@ public abstract class BaseEdgeServiceTest extends AbstractServiceTest { String edgeNameAfterRename = RandomStringUtils.randomAlphanumeric(15); Edge edge = constructEdge(tenantId, edgeNameBeforeRename, "default"); - edgeService.saveEdge(edge); + edgeService.saveEdge(edge, true); Edge savedEdge = edgeService.findEdgeByTenantIdAndName(tenantId, edgeNameBeforeRename); savedEdge.setName(edgeNameAfterRename); - edgeService.saveEdge(savedEdge); + edgeService.saveEdge(savedEdge, true); Edge renamedEdge = edgeService.findEdgeByTenantIdAndName(tenantId, edgeNameBeforeRename); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceTest.java index e16fc3dac7..831d92965b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceTest.java @@ -224,7 +224,7 @@ public abstract class BaseEntityServiceTest extends AbstractServiceTest { List edges = new ArrayList<>(); for (int i = 0; i < 97; i++) { Edge edge = createEdge(i, "default"); - edges.add(edgeService.saveEdge(edge)); + edges.add(edgeService.saveEdge(edge, true)); } EdgeTypeFilter filter = new EdgeTypeFilter(); @@ -262,7 +262,7 @@ public abstract class BaseEntityServiceTest extends AbstractServiceTest { public void testCountHierarchicalEntitiesByEdgeSearchQuery() throws InterruptedException { for (int i = 0; i < 5; i++) { Edge edge = createEdge(i, "type" + i); - edge = edgeService.saveEdge(edge); + edge = edgeService.saveEdge(edge, true); //TO make sure devices have different created time Thread.sleep(1); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java index f0e1f687be..109814d330 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java @@ -495,7 +495,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest { @Test public void testFindEdgeRuleChainsByTenantIdAndName() { Edge edge = constructEdge(tenantId, "My edge", "default"); - Edge savedEdge = edgeService.saveEdge(edge); + Edge savedEdge = edgeService.saveEdge(edge, true); String name1 = "Edge RuleChain name 1"; List ruleChainsName1 = new ArrayList<>(); From f2b8886c9b827fb71e686248be358d5038148d8c Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 24 Jun 2021 18:49:37 +0300 Subject: [PATCH 41/52] Sync completed flag correctly updated --- .../thingsboard/server/service/edge/rpc/EdgeGrpcSession.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 82aeab69ef..be6ea7e97d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -158,8 +158,9 @@ public final class EdgeGrpcSession implements Closeable { if (connected && requestMsg.getMsgType().equals(RequestMsgType.SYNC_REQUEST_RPC_MESSAGE)) { if (requestMsg.getSyncRequestMsg().getSyncRequired()) { startSyncProcess(edge.getTenantId(), edge.getId()); + } else { + syncCompleted = true; } - syncCompleted = true; } if (connected) { if (requestMsg.getMsgType().equals(RequestMsgType.UPLINK_RPC_MESSAGE) && requestMsg.hasUplinkMsg()) { @@ -228,6 +229,8 @@ public final class EdgeGrpcSession implements Closeable { .setSyncCompletedMsg(SyncCompletedMsg.newBuilder().build()) .build(); sendDownlinkMsgsPack(Collections.singletonList(syncCompleteDownlinkMsg)); + + syncCompleted = true; } catch (Exception e) { log.error("[{}][{}] Exception during sync process", edge.getTenantId(), edge.getId(), e); } From cd41ea664e46f0cc01b52985ffead6e196022782 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Mon, 5 Jul 2021 14:36:24 +0300 Subject: [PATCH 42/52] Added possibility to set max inbound rpc message size --- .../thingsboard/server/service/edge/rpc/EdgeGrpcService.java | 3 +++ application/src/main/resources/thingsboard.yml | 1 + 2 files changed, 4 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 23e12f7e4e..343764a1c1 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -81,6 +81,8 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i private boolean persistToTelemetry; @Value("${edges.rpc.client_max_keep_alive_time_sec}") private int clientMaxKeepAliveTimeSec; + @Value("${edges.rpc.max_inbound_message_size:4194304}") + private int maxInboundMessageSize; @Value("${edges.scheduler_pool_size}") private int schedulerPoolSize; @@ -102,6 +104,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i log.info("Initializing Edge RPC service!"); NettyServerBuilder builder = NettyServerBuilder.forPort(rpcPort) .permitKeepAliveTime(clientMaxKeepAliveTimeSec, TimeUnit.SECONDS) + .maxInboundMessageSize(maxInboundMessageSize) .addService(this); if (sslEnabled) { try { diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 69258a644f..44c68ce5cc 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -705,6 +705,7 @@ edges: enabled: "${EDGES_RPC_SSL_ENABLED:false}" cert: "${EDGES_RPC_SSL_CERT:certChainFile.pem}" private_key: "${EDGES_RPC_SSL_PRIVATE_KEY:privateKeyFile.pem}" + max_inbound_message_size: "${INTEGRATIONS_RPC_MAX_INBOUND_MESSAGE_SIZE:4194304}" storage: max_read_records_count: "${EDGES_STORAGE_MAX_READ_RECORDS_COUNT:50}" no_read_records_sleep: "${EDGES_NO_READ_RECORDS_SLEEP:1000}" From bc3edc8dfe6bf16cb3fd2a9bfb5aee659babbd6c Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Mon, 5 Jul 2021 14:37:21 +0300 Subject: [PATCH 43/52] Added possibility to set max inbound rpc message size --- application/src/main/resources/thingsboard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 44c68ce5cc..a5a5be1f8d 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -705,7 +705,7 @@ edges: enabled: "${EDGES_RPC_SSL_ENABLED:false}" cert: "${EDGES_RPC_SSL_CERT:certChainFile.pem}" private_key: "${EDGES_RPC_SSL_PRIVATE_KEY:privateKeyFile.pem}" - max_inbound_message_size: "${INTEGRATIONS_RPC_MAX_INBOUND_MESSAGE_SIZE:4194304}" + max_inbound_message_size: "${EDGES_RPC_MAX_INBOUND_MESSAGE_SIZE:4194304}" storage: max_read_records_count: "${EDGES_STORAGE_MAX_READ_RECORDS_COUNT:50}" no_read_records_sleep: "${EDGES_NO_READ_RECORDS_SLEEP:1000}" From 62c9630e34ba476af4958e88111c524f770f52e3 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 8 Jul 2021 11:13:55 +0300 Subject: [PATCH 44/52] Use generics to remove duplication for event fetcher. Use page data iterable --- .../server/controller/BaseController.java | 30 ++++----- .../controller/RuleChainController.java | 17 ++---- .../service/edge/EdgeContextComponent.java | 30 +-------- .../service/edge/rpc/EdgeGrpcSession.java | 1 + .../fetch/AdminSettingsEdgeEventFetcher.java | 12 +++- .../rpc/fetch/AssetsEdgeEventFetcher.java | 24 +++----- .../fetch/BasePageableEdgeEventFetcher.java | 40 +++++++++++- .../rpc/fetch/BaseUsersEdgeEventFetcher.java | 24 +++----- .../BaseWidgetsBundlesEdgeEventFetcher.java | 24 +++----- .../fetch/CustomerUsersEdgeEventFetcher.java | 3 + .../rpc/fetch/DashboardsEdgeEventFetcher.java | 24 +++----- .../fetch/DeviceProfilesEdgeEventFetcher.java | 24 +++----- .../rpc/fetch/RuleChainsEdgeEventFetcher.java | 26 +++----- .../TenantWidgetsBundlesEdgeEventFetcher.java | 4 +- .../data/page/BasePageDataIterable.java | 58 ++++++++++++++++++ .../common/data/page/PageDataIterable.java | 61 ++----------------- .../data/page/PageDataIterableByTenant.java | 39 ++++++++++++ .../PageDataIterableByTenantIdEntityId.java | 43 +++++++++++++ 18 files changed, 274 insertions(+), 210 deletions(-) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/page/BasePageDataIterable.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenant.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenantIdEntityId.java diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 2f74c47c9e..267cfe75e3 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -37,10 +37,10 @@ import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityViewInfo; -import org.thingsboard.server.common.data.OtaPackage; -import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasTenantId; +import org.thingsboard.server.common.data.OtaPackage; +import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; import org.thingsboard.server.common.data.Tenant; @@ -70,7 +70,6 @@ import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.RpcId; -import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TbResourceId; @@ -79,7 +78,7 @@ import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.id.WidgetsBundleId; -import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageDataIterableByTenantIdEntityId; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.SortOrder; import org.thingsboard.server.common.data.page.TimePageLink; @@ -105,10 +104,10 @@ import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.IncorrectParameterException; -import org.thingsboard.server.dao.ota.OtaPackageService; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService; import org.thingsboard.server.dao.oauth2.OAuth2Service; +import org.thingsboard.server.dao.ota.OtaPackageService; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.rpc.RpcService; import org.thingsboard.server.dao.rule.RuleChainService; @@ -125,11 +124,10 @@ import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.action.RuleEngineEntityActionService; import org.thingsboard.server.service.component.ComponentDiscoveryService; -import org.thingsboard.server.service.edge.rpc.EdgeRpcService; -import org.thingsboard.server.service.ota.OtaPackageStateService; import org.thingsboard.server.service.edge.EdgeNotificationService; -import org.thingsboard.server.service.edge.rpc.EdgeGrpcService; +import org.thingsboard.server.service.edge.rpc.EdgeRpcService; import org.thingsboard.server.service.lwm2m.LwM2MServerSecurityInfoRepository; +import org.thingsboard.server.service.ota.OtaPackageStateService; import org.thingsboard.server.service.profile.TbDeviceProfileCache; import org.thingsboard.server.service.queue.TbClusterService; import org.thingsboard.server.service.resource.TbResourceService; @@ -923,18 +921,12 @@ public abstract class BaseController { if (EntityType.EDGE.equals(entityId.getEntityType())) { return Collections.singletonList(new EdgeId(entityId.getId())); } + PageDataIterableByTenantIdEntityId relatedEdgeIdsIterator = + new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE); List result = new ArrayList<>(); - PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); - PageData pageData; - do { - pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId, pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - result.addAll(pageData.getData()); - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); + for(EdgeId edgeId : relatedEdgeIdsIterator) { + result.add(edgeId); + } return result; } diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index aa3f7ccbc0..3786caaa33 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -50,6 +50,7 @@ import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageDataIterableByTenant; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.rule.DefaultRuleChainCreateRequest; @@ -645,17 +646,11 @@ public class RuleChainController extends BaseController { try { TenantId tenantId = getCurrentUser().getTenantId(); List result = new ArrayList<>(); - PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); - PageData pageData; - do { - pageData = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId, pageLink); - if (pageData.getData().size() > 0) { - result.addAll(pageData.getData()); - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData.hasNext()); + PageDataIterableByTenant autoAssignRuleChainsIterator = + new PageDataIterableByTenant<>(ruleChainService::findAutoAssignToEdgeRuleChainsByTenantId, tenantId, DEFAULT_PAGE_SIZE); + for (RuleChain ruleChain : autoAssignRuleChainsIterator) { + result.add(ruleChain); + } return checkNotNull(result); } catch (Exception e) { throw handleException(e); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java b/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java index 72b5831a4d..d0bba65837 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java @@ -16,7 +16,6 @@ package org.thingsboard.server.service.edge; import lombok.Data; -import lombok.Getter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @@ -53,117 +52,90 @@ import org.thingsboard.server.service.executors.DbCallbackExecutorService; @Component @TbCoreComponent @Data +@Lazy public class EdgeContextComponent { - @Lazy @Autowired private EdgeService edgeService; - @Lazy @Autowired private EdgeEventService edgeEventService; - @Lazy @Autowired private AdminSettingsService adminSettingsService; - @Lazy @Autowired private AssetService assetService; - @Lazy @Autowired private DeviceProfileService deviceProfileService; - @Lazy @Autowired private AttributesService attributesService; - @Lazy @Autowired private DashboardService dashboardService; - @Lazy @Autowired private RuleChainService ruleChainService; - @Lazy @Autowired private UserService userService; - @Lazy @Autowired private WidgetsBundleService widgetsBundleService; - @Lazy @Autowired private EdgeRequestsService edgeRequestsService; - @Lazy @Autowired private AlarmEdgeProcessor alarmProcessor; - @Lazy @Autowired private DeviceProfileEdgeProcessor deviceProfileProcessor; - @Lazy @Autowired private DeviceEdgeProcessor deviceProcessor; - @Lazy @Autowired private EntityEdgeProcessor entityProcessor; - @Lazy @Autowired private AssetEdgeProcessor assetProcessor; - @Lazy @Autowired private EntityViewEdgeProcessor entityViewProcessor; - @Lazy @Autowired private UserEdgeProcessor userProcessor; - @Lazy @Autowired private RelationEdgeProcessor relationProcessor; - @Lazy @Autowired private TelemetryEdgeProcessor telemetryProcessor; - @Lazy @Autowired private DashboardEdgeProcessor dashboardProcessor; - @Lazy @Autowired private RuleChainEdgeProcessor ruleChainProcessor; - @Lazy @Autowired private CustomerEdgeProcessor customerProcessor; - @Lazy @Autowired private WidgetBundleEdgeProcessor widgetBundleProcessor; - @Lazy @Autowired private WidgetTypeEdgeProcessor widgetTypeProcessor; - @Lazy @Autowired private AdminSettingsEdgeProcessor adminSettingsProcessor; - @Lazy @Autowired private EdgeEventStorageSettings edgeEventStorageSettings; @Autowired - @Getter private DbCallbackExecutorService dbCallbackExecutor; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index be6ea7e97d..357b40e8df 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -316,6 +316,7 @@ public final class EdgeGrpcSession implements Closeable { if (ifOffset != null) { Long newStartTs = Uuids.unixTimestamp(ifOffset); updateQueueStartTs(newStartTs); + log.debug("[{}] queue offset was updated [{}][{}]", this.sessionId, ifOffset, newStartTs); } } log.trace("[{}] processHandleMessages finished", this.sessionId); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java index 94dd836dcd..96feb6fa92 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -17,6 +17,7 @@ package org.thingsboard.server.service.edge.rpc.fetch; import com.datastax.oss.driver.api.core.uuid.Uuids; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -47,10 +48,17 @@ import java.util.regex.Pattern; @AllArgsConstructor @Slf4j -public class AdminSettingsEdgeEventFetcher extends BasePageableEdgeEventFetcher { +public class AdminSettingsEdgeEventFetcher implements EdgeEventFetcher { + + private static final ObjectMapper mapper = new ObjectMapper(); private final AdminSettingsService adminSettingsService; + @Override + public PageLink getPageLink(int pageSize) { + return new PageLink(pageSize); + } + @Override public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) throws Exception { List result = new ArrayList<>(); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java index e2fcd40624..2e999d7906 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java @@ -28,26 +28,20 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; -import java.util.ArrayList; -import java.util.List; - @AllArgsConstructor @Slf4j -public class AssetsEdgeEventFetcher extends BasePageableEdgeEventFetcher { +public class AssetsEdgeEventFetcher extends BasePageableEdgeEventFetcher { private final AssetService assetService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { - log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); - PageData pageData = assetService.findAssetsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); - List result = new ArrayList<>(); - if (!pageData.getData().isEmpty()) { - for (Asset asset : pageData.getData()) { - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ASSET, - EdgeEventActionType.ADDED, asset.getId(), null)); - } - } - return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + PageData fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) { + return assetService.findAssetsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); + } + + @Override + EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, Asset asset) { + return EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ASSET, + EdgeEventActionType.ADDED, asset.getId(), null); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java index 409e044864..eb8592dae5 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java @@ -16,14 +16,50 @@ package org.thingsboard.server.service.edge.rpc.fetch; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.BaseData; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.EventId; +import org.thingsboard.server.common.data.id.HasId; +import org.thingsboard.server.common.data.id.HasUUID; +import org.thingsboard.server.common.data.id.IdBased; +import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.id.UUIDBased; +import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; -public abstract class BasePageableEdgeEventFetcher implements EdgeEventFetcher { +import java.util.ArrayList; +import java.util.List; - protected static final ObjectMapper mapper = new ObjectMapper(); +@Slf4j +public abstract class BasePageableEdgeEventFetcher implements EdgeEventFetcher { @Override public PageLink getPageLink(int pageSize) { return new PageLink(pageSize); } + + @Override + public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { + log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); + PageData pageData = fetchPageData(tenantId, edge, pageLink); + List result = new ArrayList<>(); + if (!pageData.getData().isEmpty()) { + for (T entity : pageData.getData()) { + result.add(constructEdgeEvent(tenantId, edge, entity)); + } + } + return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + } + + abstract PageData fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink); + + abstract EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, T entity); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java index fc5f5a49fe..63869a1181 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java @@ -28,27 +28,21 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; -import java.util.ArrayList; -import java.util.List; - @Slf4j @AllArgsConstructor -public abstract class BaseUsersEdgeEventFetcher extends BasePageableEdgeEventFetcher { +public abstract class BaseUsersEdgeEventFetcher extends BasePageableEdgeEventFetcher { protected final UserService userService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { - log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); - PageData pageData = findUsers(tenantId, pageLink); - List result = new ArrayList<>(); - if (!pageData.getData().isEmpty()) { - for (User user : pageData.getData()) { - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER, - EdgeEventActionType.ADDED, user.getId(), null)); - } - } - return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + PageData fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) { + return findUsers(tenantId, pageLink); + } + + @Override + EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, User user) { + return EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER, + EdgeEventActionType.ADDED, user.getId(), null); } protected abstract PageData findUsers(TenantId tenantId, PageLink pageLink); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java index 166e78eafa..34306b6429 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java @@ -28,27 +28,21 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.dao.widget.WidgetsBundleService; import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; -import java.util.ArrayList; -import java.util.List; - @Slf4j @AllArgsConstructor -public abstract class BaseWidgetsBundlesEdgeEventFetcher extends BasePageableEdgeEventFetcher { +public abstract class BaseWidgetsBundlesEdgeEventFetcher extends BasePageableEdgeEventFetcher { protected final WidgetsBundleService widgetsBundleService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { - log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); - PageData pageData = findWidgetsBundles(tenantId, pageLink); - List result = new ArrayList<>(); - if (!pageData.getData().isEmpty()) { - for (WidgetsBundle widgetsBundle : pageData.getData()) { - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGETS_BUNDLE, - EdgeEventActionType.ADDED, widgetsBundle.getId(), null)); - } - } - return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + PageData fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) { + return findWidgetsBundles(tenantId, pageLink); + } + + @Override + EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, WidgetsBundle widgetsBundle) { + return EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGETS_BUNDLE, + EdgeEventActionType.ADDED, widgetsBundle.getId(), null); } protected abstract PageData findWidgetsBundles(TenantId tenantId, PageLink pageLink); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java index 32c3f8fe7a..66b0b632fd 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java @@ -16,6 +16,8 @@ package org.thingsboard.server.service.edge.rpc.fetch; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -35,4 +37,5 @@ public class CustomerUsersEdgeEventFetcher extends BaseUsersEdgeEventFetcher { protected PageData findUsers(TenantId tenantId, PageLink pageLink) { return userService.findCustomerUsers(tenantId, customerId, pageLink); } + } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java index 703ad9f83e..e8da2d3cb4 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java @@ -28,26 +28,20 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; -import java.util.ArrayList; -import java.util.List; - @AllArgsConstructor @Slf4j -public class DashboardsEdgeEventFetcher extends BasePageableEdgeEventFetcher { +public class DashboardsEdgeEventFetcher extends BasePageableEdgeEventFetcher { private final DashboardService dashboardService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { - log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); - PageData pageData = dashboardService.findDashboardsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); - List result = new ArrayList<>(); - if (!pageData.getData().isEmpty()) { - for (DashboardInfo dashboardInfo : pageData.getData()) { - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DASHBOARD, - EdgeEventActionType.ADDED, dashboardInfo.getId(), null)); - } - } - return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + PageData fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) { + return dashboardService.findDashboardsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); + } + + @Override + EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, DashboardInfo dashboardInfo) { + return EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DASHBOARD, + EdgeEventActionType.ADDED, dashboardInfo.getId(), null); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java index cfb2df290e..531c7b9201 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java @@ -28,26 +28,20 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; -import java.util.ArrayList; -import java.util.List; - @AllArgsConstructor @Slf4j -public class DeviceProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher { +public class DeviceProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher { private final DeviceProfileService deviceProfileService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { - log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); - PageData pageData = deviceProfileService.findDeviceProfiles(tenantId, pageLink); - List result = new ArrayList<>(); - if (!pageData.getData().isEmpty()) { - for (DeviceProfile deviceProfile : pageData.getData()) { - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE_PROFILE, - EdgeEventActionType.ADDED, deviceProfile.getId(), null)); - } - } - return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + PageData fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) { + return deviceProfileService.findDeviceProfiles(tenantId, pageLink); + } + + @Override + EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, DeviceProfile deviceProfile) { + return EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE_PROFILE, + EdgeEventActionType.ADDED, deviceProfile.getId(), null); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java index 1bb609d769..872f67f62d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -28,26 +28,20 @@ import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; -import java.util.ArrayList; -import java.util.List; - @Slf4j @AllArgsConstructor -public class RuleChainsEdgeEventFetcher extends BasePageableEdgeEventFetcher { +public class RuleChainsEdgeEventFetcher extends BasePageableEdgeEventFetcher { private final RuleChainService ruleChainService; @Override - public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { - log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId()); - PageData pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); - List result = new ArrayList<>(); - if (!pageData.getData().isEmpty()) { - for (RuleChain ruleChain : pageData.getData()) { - result.add(EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, - EdgeEventActionType.ADDED, ruleChain.getId(), null)); - } - } - return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext()); + PageData fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) { + return ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); + } + + @Override + EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, RuleChain ruleChain) { + return EdgeEventUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, + EdgeEventActionType.ADDED, ruleChain.getId(), null); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java index a1fafd858a..ae3356ee2b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java @@ -16,6 +16,8 @@ package org.thingsboard.server.service.edge.rpc.fetch; import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -23,7 +25,7 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.dao.widget.WidgetsBundleService; @Slf4j -public class TenantWidgetsBundlesEdgeEventFetcher extends BaseWidgetsBundlesEdgeEventFetcher implements EdgeEventFetcher { +public class TenantWidgetsBundlesEdgeEventFetcher extends BaseWidgetsBundlesEdgeEventFetcher { public TenantWidgetsBundlesEdgeEventFetcher(WidgetsBundleService widgetsBundleService) { super(widgetsBundleService); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/BasePageDataIterable.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/BasePageDataIterable.java new file mode 100644 index 0000000000..c67893cee3 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/BasePageDataIterable.java @@ -0,0 +1,58 @@ +package org.thingsboard.server.common.data.page; + +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +public abstract class BasePageDataIterable implements Iterable, Iterator { + + private final int fetchSize; + + private List currentItems; + private int currentIdx; + private boolean hasNextPack; + private PageLink nextPackLink; + private boolean initialized; + + public BasePageDataIterable(int fetchSize) { + super(); + this.fetchSize = fetchSize; + } + + @Override + public Iterator iterator() { + return this; + } + + @Override + public boolean hasNext() { + if (!initialized) { + fetch(new PageLink(fetchSize)); + initialized = true; + } + if (currentIdx == currentItems.size()) { + if (hasNextPack) { + fetch(nextPackLink); + } + } + return currentIdx < currentItems.size(); + } + + @Override + public T next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return currentItems.get(currentIdx++); + } + + private void fetch(PageLink link) { + PageData pageData = fetchPageData(link); + currentIdx = 0; + currentItems = pageData.getData(); + hasNextPack = pageData.hasNext(); + nextPackLink = link.nextPageLink(); + } + + abstract PageData fetchPageData(PageLink link); +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java index 809b6b8dc6..70bfa1ea42 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -15,70 +15,21 @@ */ package org.thingsboard.server.common.data.page; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - -import org.thingsboard.server.common.data.BaseData; -import org.thingsboard.server.common.data.SearchTextBased; -import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.UUIDBased; - -public class PageDataIterable implements Iterable, Iterator { +public class PageDataIterable extends BasePageDataIterable { private final FetchFunction function; - private final int fetchSize; - - private List currentItems; - private int currentIdx; - private boolean hasNextPack; - private PageLink nextPackLink; - private boolean initialized; public PageDataIterable(FetchFunction function, int fetchSize) { - super(); + super(fetchSize); this.function = function; - this.fetchSize = fetchSize; } @Override - public Iterator iterator() { - return this; + PageData fetchPageData(PageLink link) { + return function.fetch(link); } - @Override - public boolean hasNext() { - if(!initialized){ - fetch(new PageLink(fetchSize)); - initialized = true; - } - if(currentIdx == currentItems.size()){ - if(hasNextPack){ - fetch(nextPackLink); - } - } - return currentIdx < currentItems.size(); - } - - private void fetch(PageLink link) { - PageData pageData = function.fetch(link); - currentIdx = 0; - currentItems = pageData.getData(); - hasNextPack = pageData.hasNext(); - nextPackLink = link.nextPageLink(); - } - - @Override - public T next() { - if(!hasNext()){ - throw new NoSuchElementException(); - } - return currentItems.get(currentIdx++); - } - - public static interface FetchFunction { - + public interface FetchFunction { PageData fetch(PageLink link); - } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenant.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenant.java new file mode 100644 index 0000000000..0bb5096089 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenant.java @@ -0,0 +1,39 @@ +/** + * Copyright © 2016-2021 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.common.data.page; + +import org.thingsboard.server.common.data.id.TenantId; + +public class PageDataIterableByTenant extends BasePageDataIterable { + + private final FetchFunction function; + private final TenantId tenantId; + + public PageDataIterableByTenant(FetchFunction function, TenantId tenantId, int fetchSize) { + super(fetchSize); + this.function = function; + this.tenantId = tenantId; + } + + @Override + PageData fetchPageData(PageLink link) { + return function.fetch(tenantId, link); + } + + public interface FetchFunction { + PageData fetch(TenantId tenantId, PageLink link); + } +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenantIdEntityId.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenantIdEntityId.java new file mode 100644 index 0000000000..4480137b32 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenantIdEntityId.java @@ -0,0 +1,43 @@ +/** + * Copyright © 2016-2021 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.common.data.page; + +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; + +public class PageDataIterableByTenantIdEntityId extends BasePageDataIterable { + + private final FetchFunction function; + private final TenantId tenantId; + private final EntityId entityId; + + public PageDataIterableByTenantIdEntityId(FetchFunction function, TenantId tenantId, EntityId entityId, int fetchSize) { + super(fetchSize); + this.function = function; + this.tenantId = tenantId; + this.entityId = entityId; + + } + + @Override + PageData fetchPageData(PageLink link) { + return function.fetch(tenantId, entityId, link); + } + + public interface FetchFunction { + PageData fetch(TenantId tenantId, EntityId entityId, PageLink link); + } +} From 11a7fc68e38ff7fe651d241d99a1b4d1c6ecd20b Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 8 Jul 2021 11:14:45 +0300 Subject: [PATCH 45/52] License header fix --- .../rpc/fetch/AdminSettingsEdgeEventFetcher.java | 2 +- .../rpc/fetch/RuleChainsEdgeEventFetcher.java | 2 +- .../common/data/page/BasePageDataIterable.java | 15 +++++++++++++++ .../server/common/data/page/PageDataIterable.java | 2 +- .../data/page/PageDataIterableByTenant.java | 2 +- .../page/PageDataIterableByTenantIdEntityId.java | 2 +- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java index 96feb6fa92..c59d6c5001 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java @@ -5,7 +5,7 @@ * 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 + * 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, diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java index 872f67f62d..115fa3c1e0 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java @@ -5,7 +5,7 @@ * 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 + * 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, diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/BasePageDataIterable.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/BasePageDataIterable.java index c67893cee3..4bc490e073 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/page/BasePageDataIterable.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/BasePageDataIterable.java @@ -1,3 +1,18 @@ +/** + * Copyright © 2016-2021 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.common.data.page; import java.util.Iterator; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java index 70bfa1ea42..60445e04c8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java @@ -5,7 +5,7 @@ * 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 + * 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, diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenant.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenant.java index 0bb5096089..f9368933d7 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenant.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenant.java @@ -5,7 +5,7 @@ * 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 + * 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, diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenantIdEntityId.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenantIdEntityId.java index 4480137b32..6849ba4a2f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenantIdEntityId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterableByTenantIdEntityId.java @@ -5,7 +5,7 @@ * 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 + * 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, From 331915451384ccf0b11957bde35d4728c33123f3 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 8 Jul 2021 11:53:17 +0300 Subject: [PATCH 46/52] Code review fixes - moved out .lock from try block --- .../server/service/edge/rpc/EdgeGrpcSession.java | 4 ++-- .../service/edge/rpc/processor/DeviceEdgeProcessor.java | 2 +- .../service/script/AbstractNashornJsInvokeService.java | 2 +- .../org/thingsboard/server/edge/imitator/EdgeImitator.java | 6 +++--- .../main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java | 6 +++--- .../server/dao/device/DeviceProfileServiceImpl.java | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 357b40e8df..aca42db0b4 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -280,8 +280,8 @@ public final class EdgeGrpcSession implements Closeable { private void sendDownlinkMsg(ResponseMsg downlinkMsg) { log.trace("[{}] Sending downlink msg [{}]", this.sessionId, downlinkMsg); if (isConnected()) { + downlinkMsgLock.lock(); try { - downlinkMsgLock.lock(); outputStream.onNext(downlinkMsg); } catch (Exception e) { log.error("[{}] Failed to send downlink message [{}]", this.sessionId, downlinkMsg, e); @@ -345,8 +345,8 @@ public final class EdgeGrpcSession implements Closeable { } private boolean sendDownlinkMsgsPack(List downlinkMsgsPack) throws InterruptedException { + downlinkMsgsPackLock.lock(); try { - downlinkMsgsPackLock.lock(); boolean success; pendingMsgsMap.clear(); downlinkMsgsPack.forEach(msg -> pendingMsgsMap.put(msg.getDownlinkMsgId(), msg)); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java index ccf0552daa..3e2c740acc 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java @@ -189,8 +189,8 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { private Device createDevice(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg, String deviceName) { Device device; + deviceCreationLock.lock(); try { - deviceCreationLock.lock(); log.debug("[{}] Creating device entity [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); device = deviceService.findDeviceById(tenantId, deviceId); diff --git a/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java b/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java index 15a3cf1c15..20b8d7979d 100644 --- a/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java +++ b/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java @@ -124,8 +124,8 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer protected ListenableFuture doEval(UUID scriptId, String functionName, String jsScript) { jsPushedMsgs.incrementAndGet(); ListenableFuture result = jsExecutor.executeAsync(() -> { + evalLock.lock(); try { - evalLock.lock(); try { if (useJsSandbox()) { sandbox.eval(jsScript); diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index e0361f4004..af486ae0f4 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -275,8 +275,8 @@ public class EdgeImitator { private ListenableFuture saveDownlinkMsg(AbstractMessage message) { if (!ignoredTypes.contains(message.getClass())) { + lock.lock(); try { - lock.lock(); downlinkMsgs.add(message); } finally { lock.unlock(); @@ -312,8 +312,8 @@ public class EdgeImitator { @SuppressWarnings("unchecked") public Optional findMessageByType(Class tClass) { Optional result; + lock.lock(); try { - lock.lock(); result = (Optional) downlinkMsgs.stream().filter(downlinkMsg -> downlinkMsg.getClass().isAssignableFrom(tClass)).findAny(); } finally { lock.unlock(); @@ -324,8 +324,8 @@ public class EdgeImitator { @SuppressWarnings("unchecked") public List findAllMessagesByType(Class tClass) { List result; + lock.lock(); try { - lock.lock(); result = (List) downlinkMsgs.stream().filter(downlinkMsg -> downlinkMsg.getClass().isAssignableFrom(tClass)).collect(Collectors.toList()); } finally { lock.unlock(); diff --git a/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java b/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java index f80845fa48..4c74fdc2f9 100644 --- a/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java +++ b/common/edge-api/src/main/java/org/thingsboard/edge/rpc/EdgeGrpcClient.java @@ -185,8 +185,8 @@ public class EdgeGrpcClient implements EdgeRpcClient { @Override public void sendUplinkMsg(UplinkMsg msg) { + uplinkMsgLock.lock(); try { - uplinkMsgLock.lock(); this.inputStream.onNext(RequestMsg.newBuilder() .setMsgType(RequestMsgType.UPLINK_RPC_MESSAGE) .setUplinkMsg(msg) @@ -198,8 +198,8 @@ public class EdgeGrpcClient implements EdgeRpcClient { @Override public void sendSyncRequestMsg(boolean syncRequired) { + uplinkMsgLock.lock(); try { - uplinkMsgLock.lock(); SyncRequestMsg syncRequestMsg = SyncRequestMsg.newBuilder().setSyncRequired(syncRequired).build(); this.inputStream.onNext(RequestMsg.newBuilder() .setMsgType(RequestMsgType.SYNC_REQUEST_RPC_MESSAGE) @@ -212,8 +212,8 @@ public class EdgeGrpcClient implements EdgeRpcClient { @Override public void sendDownlinkResponseMsg(DownlinkResponseMsg downlinkResponseMsg) { + uplinkMsgLock.lock(); try { - uplinkMsgLock.lock(); this.inputStream.onNext(RequestMsg.newBuilder() .setMsgType(RequestMsgType.UPLINK_RPC_MESSAGE) .setDownlinkResponseMsg(downlinkResponseMsg) diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java index 7ec1e662af..ff09a99ca8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java @@ -248,8 +248,8 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D log.trace("Executing findOrCreateDefaultDeviceProfile"); DeviceProfile deviceProfile = findDeviceProfileByName(tenantId, name); if (deviceProfile == null) { + findOrCreateLock.lock(); try { - findOrCreateLock.lock(); deviceProfile = findDeviceProfileByName(tenantId, name); if (deviceProfile == null) { deviceProfile = this.doCreateDefaultDeviceProfile(tenantId, name, name.equals("default")); From f4d0aea5996dcf8c0592f109b228624847e44a14 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 8 Jul 2021 13:32:45 +0300 Subject: [PATCH 47/52] Added lock for new events updates --- .../service/edge/rpc/EdgeGrpcService.java | 56 +++++++++++++++---- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 11948742bd..cdb649037b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -50,6 +50,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -59,6 +60,8 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; @Service @Slf4j @@ -67,7 +70,8 @@ import java.util.concurrent.TimeUnit; public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase implements EdgeRpcService { private final ConcurrentMap sessions = new ConcurrentHashMap<>(); - private final ConcurrentMap sessionNewEvents = new ConcurrentHashMap<>(); + private final ConcurrentMap sessionNewEventsLocks = new ConcurrentHashMap<>(); + private final Map sessionNewEvents = new HashMap<>(); private final ConcurrentMap> sessionEdgeEventChecks = new ConcurrentHashMap<>(); private static final ObjectMapper mapper = new ObjectMapper(); @@ -176,7 +180,13 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i log.info("[{}] Closing and removing session for edge [{}]", tenantId, edgeId); session.close(); sessions.remove(edgeId); - sessionNewEvents.remove(edgeId); + Lock lock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); + lock.lock(); + try { + sessionNewEvents.remove(edgeId); + } finally { + lock.unlock(); + } cancelScheduleEdgeEventsCheck(edgeId); } } @@ -184,16 +194,28 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i @Override public void onEdgeEvent(TenantId tenantId, EdgeId edgeId) { log.trace("[{}] onEdgeEvent [{}]", tenantId, edgeId.getId()); - if (Boolean.FALSE.equals(sessionNewEvents.get(edgeId))) { - log.trace("[{}] set session new events flag to true [{}]", tenantId, edgeId.getId()); - sessionNewEvents.put(edgeId, true); + Lock lock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); + lock.lock(); + try { + if (Boolean.FALSE.equals(sessionNewEvents.get(edgeId))) { + log.trace("[{}] set session new events flag to true [{}]", tenantId, edgeId.getId()); + sessionNewEvents.put(edgeId, true); + } + } finally { + lock.unlock(); } } private void onEdgeConnect(EdgeId edgeId, EdgeGrpcSession edgeGrpcSession) { log.info("[{}] edge [{}] connected successfully.", edgeGrpcSession.getSessionId(), edgeId); sessions.put(edgeId, edgeGrpcSession); - sessionNewEvents.put(edgeId, true); + Lock lock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); + lock.lock(); + try { + sessionNewEvents.put(edgeId, true); + } finally { + lock.unlock(); + } save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, true); save(edgeId, DefaultDeviceStateService.LAST_CONNECT_TIME, System.currentTimeMillis()); cancelScheduleEdgeEventsCheck(edgeId); @@ -217,10 +239,16 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i if (sessions.containsKey(edgeId)) { ScheduledFuture schedule = scheduler.schedule(() -> { try { - if (Boolean.TRUE.equals(sessionNewEvents.get(edgeId))) { - log.trace("[{}] Set session new events flag to false", edgeId.getId()); - sessionNewEvents.put(edgeId, false); - session.processEdgeEvents(); + Lock lock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); + lock.lock(); + try { + if (Boolean.TRUE.equals(sessionNewEvents.get(edgeId))) { + log.trace("[{}] Set session new events flag to false", edgeId.getId()); + sessionNewEvents.put(edgeId, false); + session.processEdgeEvents(); + } + } finally { + lock.unlock(); } } catch (Exception e) { log.warn("[{}] Failed to process edge events for edge [{}]!", tenantId, session.getEdge().getId().getId(), e); @@ -249,7 +277,13 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i private void onEdgeDisconnect(EdgeId edgeId) { log.info("[{}] edge disconnected!", edgeId); sessions.remove(edgeId); - sessionNewEvents.remove(edgeId); + Lock lock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); + lock.lock(); + try { + sessionNewEvents.remove(edgeId); + } finally { + lock.unlock(); + } save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, false); save(edgeId, DefaultDeviceStateService.LAST_DISCONNECT_TIME, System.currentTimeMillis()); cancelScheduleEdgeEventsCheck(edgeId); From 47311663cdae4cac80c9d5a94a70a9dbd026ff75 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 8 Jul 2021 20:01:55 +0300 Subject: [PATCH 48/52] Code review changes - implemented grpc sending in async manner --- .../service/edge/EdgeContextComponent.java | 4 + .../service/edge/rpc/EdgeGrpcService.java | 60 ++-- .../service/edge/rpc/EdgeGrpcSession.java | 280 +++++++++++------- .../service/edge/rpc/EdgeSyncCursor.java | 74 +++++ .../fetch/AdminSettingsEdgeEventFetcher.java | 2 +- .../rpc/fetch/CustomerEdgeEventFetcher.java | 49 +++ .../GrpcCallbackExecutorService.java | 33 +++ .../src/main/resources/thingsboard.yml | 4 +- 8 files changed, 377 insertions(+), 129 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerEdgeEventFetcher.java create mode 100644 application/src/main/java/org/thingsboard/server/service/executors/GrpcCallbackExecutorService.java diff --git a/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java b/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java index d0bba65837..de9d2d142a 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java @@ -48,6 +48,7 @@ import org.thingsboard.server.service.edge.rpc.processor.WidgetBundleEdgeProcess import org.thingsboard.server.service.edge.rpc.processor.WidgetTypeEdgeProcessor; import org.thingsboard.server.service.edge.rpc.sync.EdgeRequestsService; import org.thingsboard.server.service.executors.DbCallbackExecutorService; +import org.thingsboard.server.service.executors.GrpcCallbackExecutorService; @Component @TbCoreComponent @@ -138,4 +139,7 @@ public class EdgeContextComponent { @Autowired private DbCallbackExecutorService dbCallbackExecutor; + + @Autowired + private GrpcCallbackExecutorService grpcCallbackExecutorService; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index cdb649037b..37d3c42c8a 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -16,8 +16,8 @@ package org.thingsboard.server.service.edge.rpc; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.io.Resources; import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; import io.grpc.Server; import io.grpc.netty.NettyServerBuilder; import io.grpc.stub.StreamObserver; @@ -46,7 +46,6 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; import javax.annotation.Nullable; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Collections; @@ -93,6 +92,9 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i @Value("${edges.scheduler_pool_size}") private int schedulerPoolSize; + @Value("${edges.send_scheduler_pool_size}") + private int sendSchedulerPoolSize; + @Autowired private EdgeContextComponent ctx; @@ -105,6 +107,8 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i private ExecutorService syncExecutorService; + private ScheduledExecutorService sendScheduler; + @PostConstruct public void init() { log.info("Initializing Edge RPC service!"); @@ -131,6 +135,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i throw new RuntimeException("Failed to start Edge RPC server!"); } this.scheduler = Executors.newScheduledThreadPool(schedulerPoolSize, ThingsBoardThreadFactory.forName("edge-scheduler")); + this.sendScheduler = Executors.newScheduledThreadPool(sendSchedulerPoolSize, ThingsBoardThreadFactory.forName("edge-send-scheduler")); this.syncExecutorService = Executors.newFixedThreadPool( Runtime.getRuntime().availableProcessors(), ThingsBoardThreadFactory.forName("edge-sync")); log.info("Edge RPC service initialized!"); @@ -152,6 +157,9 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i if (scheduler != null) { scheduler.shutdownNow(); } + if (sendScheduler != null) { + sendScheduler.shutdownNow(); + } if (syncExecutorService != null) { syncExecutorService.shutdownNow(); } @@ -159,7 +167,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i @Override public StreamObserver handleMsgs(StreamObserver outputStream) { - return new EdgeGrpcSession(ctx, outputStream, this::onEdgeConnect, this::onEdgeDisconnect, mapper, syncExecutorService).getInputStream(); + return new EdgeGrpcSession(ctx, outputStream, this::onEdgeConnect, this::onEdgeDisconnect, mapper, syncExecutorService, sendScheduler).getInputStream(); } @Override @@ -180,12 +188,12 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i log.info("[{}] Closing and removing session for edge [{}]", tenantId, edgeId); session.close(); sessions.remove(edgeId); - Lock lock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); - lock.lock(); + final Lock newEventLock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); + newEventLock.lock(); try { sessionNewEvents.remove(edgeId); } finally { - lock.unlock(); + newEventLock.unlock(); } cancelScheduleEdgeEventsCheck(edgeId); } @@ -194,27 +202,27 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i @Override public void onEdgeEvent(TenantId tenantId, EdgeId edgeId) { log.trace("[{}] onEdgeEvent [{}]", tenantId, edgeId.getId()); - Lock lock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); - lock.lock(); + final Lock newEventLock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); + newEventLock.lock(); try { if (Boolean.FALSE.equals(sessionNewEvents.get(edgeId))) { log.trace("[{}] set session new events flag to true [{}]", tenantId, edgeId.getId()); sessionNewEvents.put(edgeId, true); } } finally { - lock.unlock(); + newEventLock.unlock(); } } private void onEdgeConnect(EdgeId edgeId, EdgeGrpcSession edgeGrpcSession) { log.info("[{}] edge [{}] connected successfully.", edgeGrpcSession.getSessionId(), edgeId); sessions.put(edgeId, edgeGrpcSession); - Lock lock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); - lock.lock(); + final Lock newEventLock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); + newEventLock.lock(); try { sessionNewEvents.put(edgeId, true); } finally { - lock.unlock(); + newEventLock.unlock(); } save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, true); save(edgeId, DefaultDeviceStateService.LAST_CONNECT_TIME, System.currentTimeMillis()); @@ -239,21 +247,33 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i if (sessions.containsKey(edgeId)) { ScheduledFuture schedule = scheduler.schedule(() -> { try { - Lock lock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); - lock.lock(); + final Lock newEventLock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); + newEventLock.lock(); try { if (Boolean.TRUE.equals(sessionNewEvents.get(edgeId))) { log.trace("[{}] Set session new events flag to false", edgeId.getId()); sessionNewEvents.put(edgeId, false); - session.processEdgeEvents(); + Futures.addCallback(session.processEdgeEvents(), new FutureCallback<>() { + @Override + public void onSuccess(Void result) { + scheduleEdgeEventsCheck(session); + } + + @Override + public void onFailure(Throwable t) { + log.warn("[{}] Failed to process edge events for edge [{}]!", tenantId, session.getEdge().getId().getId(), t); + scheduleEdgeEventsCheck(session); + } + }, ctx.getGrpcCallbackExecutorService()); + } else { + scheduleEdgeEventsCheck(session); } } finally { - lock.unlock(); + newEventLock.unlock(); } } catch (Exception e) { log.warn("[{}] Failed to process edge events for edge [{}]!", tenantId, session.getEdge().getId().getId(), e); } - scheduleEdgeEventsCheck(session); }, ctx.getEdgeEventStorageSettings().getNoRecordsSleepInterval(), TimeUnit.MILLISECONDS); sessionEdgeEventChecks.put(edgeId, schedule); log.trace("[{}] Check edge event scheduled for edge [{}]", tenantId, edgeId.getId()); @@ -277,12 +297,12 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i private void onEdgeDisconnect(EdgeId edgeId) { log.info("[{}] edge disconnected!", edgeId); sessions.remove(edgeId); - Lock lock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); - lock.lock(); + final Lock newEventLock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); + newEventLock.lock(); try { sessionNewEvents.remove(edgeId); } finally { - lock.unlock(); + newEventLock.unlock(); } save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, false); save(edgeId, DefaultDeviceStateService.LAST_DISCONNECT_TIME, System.currentTimeMillis()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index aca42db0b4..f16df05af8 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.SettableFuture; import io.grpc.stub.StreamObserver; import lombok.Data; import lombok.extern.slf4j.Slf4j; @@ -31,9 +31,7 @@ import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; -import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.EdgeId; -import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; @@ -69,32 +67,21 @@ import org.thingsboard.server.gen.edge.v1.UplinkResponseMsg; import org.thingsboard.server.gen.edge.v1.UserCredentialsRequestMsg; import org.thingsboard.server.gen.edge.v1.WidgetBundleTypesRequestMsg; import org.thingsboard.server.service.edge.EdgeContextComponent; -import org.thingsboard.server.service.edge.rpc.fetch.AdminSettingsEdgeEventFetcher; -import org.thingsboard.server.service.edge.rpc.fetch.AssetsEdgeEventFetcher; -import org.thingsboard.server.service.edge.rpc.fetch.CustomerUsersEdgeEventFetcher; -import org.thingsboard.server.service.edge.rpc.fetch.DashboardsEdgeEventFetcher; -import org.thingsboard.server.service.edge.rpc.fetch.DeviceProfilesEdgeEventFetcher; import org.thingsboard.server.service.edge.rpc.fetch.EdgeEventFetcher; import org.thingsboard.server.service.edge.rpc.fetch.GeneralEdgeEventFetcher; -import org.thingsboard.server.service.edge.rpc.fetch.RuleChainsEdgeEventFetcher; -import org.thingsboard.server.service.edge.rpc.fetch.SystemWidgetsBundlesEdgeEventFetcher; -import org.thingsboard.server.service.edge.rpc.fetch.TenantAdminUsersEdgeEventFetcher; -import org.thingsboard.server.service.edge.rpc.fetch.TenantWidgetsBundlesEdgeEventFetcher; import java.io.Closeable; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import java.util.function.BiConsumer; @@ -116,6 +103,8 @@ public final class EdgeGrpcSession implements Closeable { private final ObjectMapper mapper; private final Map pendingMsgsMap = new LinkedHashMap<>(); + private SettableFuture pendingFuture; + private ScheduledFuture sendSchedule; private EdgeContextComponent ctx; private Edge edge; @@ -126,10 +115,10 @@ public final class EdgeGrpcSession implements Closeable { private ExecutorService syncExecutorService; - private CountDownLatch latch; + private ScheduledExecutorService sendScheduler; EdgeGrpcSession(EdgeContextComponent ctx, StreamObserver outputStream, BiConsumer sessionOpenListener, - Consumer sessionCloseListener, ObjectMapper mapper, ExecutorService syncExecutorService) { + Consumer sessionCloseListener, ObjectMapper mapper, ExecutorService syncExecutorService, ScheduledExecutorService sendScheduler) { this.sessionId = UUID.randomUUID(); this.ctx = ctx; this.outputStream = outputStream; @@ -137,6 +126,7 @@ public final class EdgeGrpcSession implements Closeable { this.sessionCloseListener = sessionCloseListener; this.mapper = mapper; this.syncExecutorService = syncExecutorService; + this.sendScheduler = sendScheduler; initInputStream(); } @@ -155,19 +145,21 @@ public final class EdgeGrpcSession implements Closeable { connected = true; } } - if (connected && requestMsg.getMsgType().equals(RequestMsgType.SYNC_REQUEST_RPC_MESSAGE)) { - if (requestMsg.getSyncRequestMsg().getSyncRequired()) { - startSyncProcess(edge.getTenantId(), edge.getId()); - } else { - syncCompleted = true; - } - } if (connected) { - if (requestMsg.getMsgType().equals(RequestMsgType.UPLINK_RPC_MESSAGE) && requestMsg.hasUplinkMsg()) { - onUplinkMsg(requestMsg.getUplinkMsg()); + if (requestMsg.getMsgType().equals(RequestMsgType.SYNC_REQUEST_RPC_MESSAGE)) { + if (requestMsg.hasSyncRequestMsg() && requestMsg.getSyncRequestMsg().getSyncRequired()) { + startSyncProcess(edge.getTenantId(), edge.getId()); + } else { + syncCompleted = true; + } } - if (requestMsg.getMsgType().equals(RequestMsgType.UPLINK_RPC_MESSAGE) && requestMsg.hasDownlinkResponseMsg()) { - onDownlinkResponse(requestMsg.getDownlinkResponseMsg()); + if (requestMsg.getMsgType().equals(RequestMsgType.UPLINK_RPC_MESSAGE)) { + if (requestMsg.hasUplinkMsg()) { + onUplinkMsg(requestMsg.getUplinkMsg()); + } + if (requestMsg.hasDownlinkResponseMsg()) { + onDownlinkResponse(requestMsg.getDownlinkResponseMsg()); + } } } } @@ -204,39 +196,47 @@ public final class EdgeGrpcSession implements Closeable { syncCompleted = false; syncExecutorService.submit(() -> { try { - startProcessingEdgeEvents(new SystemWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService())); - startProcessingEdgeEvents(new TenantWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService())); - startProcessingEdgeEvents(new DeviceProfilesEdgeEventFetcher(ctx.getDeviceProfileService())); - startProcessingEdgeEvents(new RuleChainsEdgeEventFetcher(ctx.getRuleChainService())); - - startProcessingEdgeEvents(new TenantAdminUsersEdgeEventFetcher(ctx.getUserService())); - if (edge.getCustomerId() != null && !EntityId.NULL_UUID.equals(edge.getCustomerId().getId())) { - EdgeEvent customerEdgeEvent = EdgeEventUtils.constructEdgeEvent(edge.getTenantId(), edge.getId(), - EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, edge.getCustomerId(), null); - DownlinkMsg customerDownlinkMsg = convertToDownlinkMsg(customerEdgeEvent); - sendDownlinkMsgsPack(Collections.singletonList(customerDownlinkMsg)); - - startProcessingEdgeEvents(new CustomerUsersEdgeEventFetcher(ctx.getUserService(), edge.getCustomerId())); - } - - startProcessingEdgeEvents(new AdminSettingsEdgeEventFetcher(ctx.getAdminSettingsService())); - - startProcessingEdgeEvents(new AssetsEdgeEventFetcher(ctx.getAssetService())); - startProcessingEdgeEvents(new DashboardsEdgeEventFetcher(ctx.getDashboardService())); - - DownlinkMsg syncCompleteDownlinkMsg = DownlinkMsg.newBuilder() - .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) - .setSyncCompletedMsg(SyncCompletedMsg.newBuilder().build()) - .build(); - sendDownlinkMsgsPack(Collections.singletonList(syncCompleteDownlinkMsg)); - - syncCompleted = true; + doSync(new EdgeSyncCursor(ctx, edge)); } catch (Exception e) { log.error("[{}][{}] Exception during sync process", edge.getTenantId(), edge.getId(), e); } }); } + private void doSync(EdgeSyncCursor cursor) { + if (cursor.hasNext()) { + log.info("[{}][{}] starting sync process, cursor current idx = {}", edge.getTenantId(), edge.getId(), cursor.getCurrentIdx()); + ListenableFuture uuidListenableFuture = startProcessingEdgeEvents(cursor.getNext()); + Futures.addCallback(uuidListenableFuture, new FutureCallback<>() { + @Override + public void onSuccess(@Nullable UUID result) { + doSync(cursor); + } + + @Override + public void onFailure(Throwable t) { + log.error("[{}][{}] Exception during sync process", edge.getTenantId(), edge.getId(), t); + } + }, ctx.getGrpcCallbackExecutorService()); + } else { + DownlinkMsg syncCompleteDownlinkMsg = DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) + .setSyncCompletedMsg(SyncCompletedMsg.newBuilder().build()) + .build(); + Futures.addCallback(sendDownlinkMsgsPack(Collections.singletonList(syncCompleteDownlinkMsg)), new FutureCallback() { + @Override + public void onSuccess(Void result) { + syncCompleted = true; + } + + @Override + public void onFailure(Throwable t) { + log.error("[{}][{}] Exception during sending sync complete", edge.getTenantId(), edge.getId(), t); + } + }, ctx.getGrpcCallbackExecutorService()); + } + } + private void onUplinkMsg(UplinkMsg uplinkMsg) { ListenableFuture> future = processUplinkMsg(uplinkMsg); Futures.addCallback(future, new FutureCallback<>() { @@ -260,7 +260,7 @@ public final class EdgeGrpcSession implements Closeable { .setUplinkResponseMsg(uplinkResponseMsg) .build()); } - }, MoreExecutors.directExecutor()); + }, ctx.getGrpcCallbackExecutorService()); } private void onDownlinkResponse(DownlinkResponseMsg msg) { @@ -271,7 +271,13 @@ public final class EdgeGrpcSession implements Closeable { } else { log.error("[{}] Msg processing failed! Error msg: {}", edge.getRoutingKey(), msg.getErrorMsg()); } - latch.countDown(); + if (pendingMsgsMap.size() == 0) { + log.debug("[{}] Pending msgs map is empty. Stopping current iteration {}", edge.getRoutingKey(), msg); + if (sendSchedule != null) { + sendSchedule.cancel(false); + } + pendingFuture.set(null); + } } catch (Exception e) { log.error("[{}] Can't process downlink response message [{}]", this.sessionId, msg, e); } @@ -305,76 +311,136 @@ public final class EdgeGrpcSession implements Closeable { sendDownlinkMsg(edgeConfigMsg); } - void processEdgeEvents() throws Exception { - log.trace("[{}] processHandleMessages started", this.sessionId); + ListenableFuture processEdgeEvents() throws Exception { + SettableFuture result = SettableFuture.create(); + log.trace("[{}] starting processing edge events", this.sessionId); if (isConnected() && isSyncCompleted()) { Long queueStartTs = getQueueStartTs().get(); GeneralEdgeEventFetcher fetcher = new GeneralEdgeEventFetcher( queueStartTs, ctx.getEdgeEventService()); - UUID ifOffset = startProcessingEdgeEvents(fetcher); - if (ifOffset != null) { - Long newStartTs = Uuids.unixTimestamp(ifOffset); - updateQueueStartTs(newStartTs); - log.debug("[{}] queue offset was updated [{}][{}]", this.sessionId, ifOffset, newStartTs); - } + ListenableFuture ifOffsetFuture = startProcessingEdgeEvents(fetcher); + Futures.addCallback(ifOffsetFuture, new FutureCallback<>() { + @Override + public void onSuccess(@Nullable UUID ifOffset) { + if (ifOffset != null) { + Long newStartTs = Uuids.unixTimestamp(ifOffset); + ListenableFuture> updateFuture = updateQueueStartTs(newStartTs); + Futures.addCallback(updateFuture, new FutureCallback<>() { + @Override + public void onSuccess(@Nullable List list) { + log.debug("[{}] queue offset was updated [{}][{}]", sessionId, ifOffset, newStartTs); + result.set(null); + } + + @Override + public void onFailure(Throwable t) { + log.error("[{}] Failed to update queue offset [{}]", sessionId, ifOffset, t); + result.setException(t); + } + }, ctx.getGrpcCallbackExecutorService()); + } else { + log.trace("[{}] ifOffset is null. Skipping iteration without db update", sessionId); + result.set(null); + } + } + + @Override + public void onFailure(Throwable t) { + log.error("[{}] Failed to process events", sessionId, t); + result.setException(t); + } + }, ctx.getGrpcCallbackExecutorService()); + } else { + log.trace("[{}] edge is not connected or sync is not completed. Skipping iteration", sessionId); + result.set(null); } - log.trace("[{}] processHandleMessages finished", this.sessionId); + return result; } - private UUID startProcessingEdgeEvents(EdgeEventFetcher fetcher) throws Exception { + private ListenableFuture startProcessingEdgeEvents(EdgeEventFetcher fetcher) { + SettableFuture result = SettableFuture.create(); PageLink pageLink = fetcher.getPageLink(ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount()); - PageData pageData; - UUID ifOffset = null; - boolean success; - do { - pageData = fetcher.fetchEdgeEvents(edge.getTenantId(), edge, pageLink); + processEdgeEvents(fetcher, pageLink, result); + return result; + } + + private void processEdgeEvents(EdgeEventFetcher fetcher, PageLink pageLink, SettableFuture result) { + try { + PageData pageData = fetcher.fetchEdgeEvents(edge.getTenantId(), edge, pageLink); if (isConnected() && !pageData.getData().isEmpty()) { log.trace("[{}] [{}] event(s) are going to be processed.", this.sessionId, pageData.getData().size()); List downlinkMsgsPack = convertToDownlinkMsgsPack(pageData.getData()); - success = sendDownlinkMsgsPack(downlinkMsgsPack); - ifOffset = pageData.getData().get(pageData.getData().size() - 1).getUuidId(); - if (success) { - pageLink = pageLink.nextPageLink(); - } + Futures.addCallback(sendDownlinkMsgsPack(downlinkMsgsPack), new FutureCallback() { + @Override + public void onSuccess(@Nullable Void tmp) { + if (isConnected() && pageData.hasNext()) { + processEdgeEvents(fetcher, pageLink.nextPageLink(), result); + } else { + UUID ifOffset = pageData.getData().get(pageData.getData().size() - 1).getUuidId(); + result.set(ifOffset); + } + } + + @Override + public void onFailure(Throwable t) { + log.error("[{}] Failed to send downlink msgs pack", sessionId, t); + result.setException(t); + } + }, ctx.getGrpcCallbackExecutorService()); } else { log.trace("[{}] no event(s) found. Stop processing edge events", this.sessionId); + result.set(null); } - } while (isConnected() && pageData.hasNext()); - return ifOffset; + } catch (Exception e) { + log.error("[{}] Failed to fetch edge events", this.sessionId, e); + result.setException(e); + } } - private boolean sendDownlinkMsgsPack(List downlinkMsgsPack) throws InterruptedException { + private ListenableFuture sendDownlinkMsgsPack(List downlinkMsgsPack) { + SettableFuture result = SettableFuture.create(); downlinkMsgsPackLock.lock(); try { - boolean success; pendingMsgsMap.clear(); downlinkMsgsPack.forEach(msg -> pendingMsgsMap.put(msg.getDownlinkMsgId(), msg)); - do { - log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, pendingMsgsMap.values().size()); - latch = new CountDownLatch(pendingMsgsMap.values().size()); - List copy = new ArrayList<>(pendingMsgsMap.values()); - for (DownlinkMsg downlinkMsg : copy) { - sendDownlinkMsg(ResponseMsg.newBuilder() - .setDownlinkMsg(downlinkMsg) - .build()); - } - success = latch.await(10, TimeUnit.SECONDS); - if (!success || pendingMsgsMap.values().size() > 0) { - log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, pendingMsgsMap.values()); - } - if (isConnected() && (!success || pendingMsgsMap.values().size() > 0)) { - try { - Thread.sleep(ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches()); - } catch (InterruptedException e) { - log.error("[{}] Error during sleep between batches", this.sessionId, e); - } - } - } while (isConnected() && (!success || pendingMsgsMap.values().size() > 0)); - return success; + scheduleDownlinkMsgsPackSend(true, result); } finally { downlinkMsgsPackLock.unlock(); } + return result; + } + + private void scheduleDownlinkMsgsPackSend(boolean firstRun, SettableFuture futureResult) { + pendingFuture = futureResult; + Runnable runnable = () -> { + try { + if (isConnected() && pendingMsgsMap.values().size() > 0) { + if (!firstRun) { + log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, pendingMsgsMap.values()); + } + log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, pendingMsgsMap.values().size()); + List copy = new ArrayList<>(pendingMsgsMap.values()); + for (DownlinkMsg downlinkMsg : copy) { + sendDownlinkMsg(ResponseMsg.newBuilder() + .setDownlinkMsg(downlinkMsg) + .build()); + } + scheduleDownlinkMsgsPackSend(false, futureResult); + } else { + futureResult.set(null); + } + } catch (Exception e) { + futureResult.setException(e); + } + }; + + if (firstRun) { + syncExecutorService.submit(runnable); + } else { + sendSchedule = sendScheduler.schedule(runnable, ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches(), TimeUnit.MILLISECONDS); + } + } private DownlinkMsg convertToDownlinkMsg(EdgeEvent edgeEvent) { @@ -439,14 +505,14 @@ public final class EdgeGrpcSession implements Closeable { } else { return 0L; } - }, ctx.getDbCallbackExecutor()); + }, ctx.getGrpcCallbackExecutorService()); } - private void updateQueueStartTs(Long newStartTs) { + private ListenableFuture> updateQueueStartTs(Long newStartTs) { log.trace("[{}] updating QueueStartTs [{}][{}]", this.sessionId, edge.getId(), newStartTs); newStartTs = ++newStartTs; // increments ts by 1 - next edge event search starts from current offset + 1 List attributes = Collections.singletonList(new BaseAttributeKvEntry(new LongDataEntry(QUEUE_START_TS_ATTR_KEY, newStartTs), System.currentTimeMillis())); - ctx.getAttributesService().save(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, attributes); + return ctx.getAttributesService().save(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, attributes); } private DownlinkMsg processEntityMessage(EdgeEvent edgeEvent, EdgeEventActionType action) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java new file mode 100644 index 0000000000..85ef95ee12 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java @@ -0,0 +1,74 @@ +/** + * Copyright © 2016-2021 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; + +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.service.edge.EdgeContextComponent; +import org.thingsboard.server.service.edge.rpc.fetch.AdminSettingsEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.AssetsEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.CustomerEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.CustomerUsersEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.DashboardsEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.DeviceProfilesEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.EdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.RuleChainsEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.SystemWidgetsBundlesEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.TenantAdminUsersEdgeEventFetcher; +import org.thingsboard.server.service.edge.rpc.fetch.TenantWidgetsBundlesEdgeEventFetcher; + +import java.util.LinkedList; +import java.util.List; + +public class EdgeSyncCursor { + + List fetchers = new LinkedList<>(); + + int currentIdx = 0; + + public EdgeSyncCursor(EdgeContextComponent ctx, Edge edge) { + fetchers.add(new SystemWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService())); + fetchers.add(new TenantWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService())); + fetchers.add(new DeviceProfilesEdgeEventFetcher(ctx.getDeviceProfileService())); + fetchers.add(new RuleChainsEdgeEventFetcher(ctx.getRuleChainService())); + fetchers.add(new TenantAdminUsersEdgeEventFetcher(ctx.getUserService())); + if (edge.getCustomerId() != null && !EntityId.NULL_UUID.equals(edge.getCustomerId().getId())) { + fetchers.add(new CustomerEdgeEventFetcher()); + fetchers.add(new CustomerUsersEdgeEventFetcher(ctx.getUserService(), edge.getCustomerId())); + } + fetchers.add(new AdminSettingsEdgeEventFetcher(ctx.getAdminSettingsService())); + fetchers.add(new AssetsEdgeEventFetcher(ctx.getAssetService())); + fetchers.add(new DashboardsEdgeEventFetcher(ctx.getDashboardService())); + } + + public boolean hasNext() { + return fetchers.size() > currentIdx; + } + + public EdgeEventFetcher getNext() { + if (hasNext()) { + EdgeEventFetcher edgeEventFetcher = fetchers.get(currentIdx); + currentIdx++; + return edgeEventFetcher; + } else { + throw new IndexOutOfBoundsException(); + } + } + + public int getCurrentIdx() { + return currentIdx; + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java index c59d6c5001..0035fd1334 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java @@ -56,7 +56,7 @@ public class AdminSettingsEdgeEventFetcher implements EdgeEventFetcher { @Override public PageLink getPageLink(int pageSize) { - return new PageLink(pageSize); + return null; } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerEdgeEventFetcher.java new file mode 100644 index 0000000000..abdde978f4 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerEdgeEventFetcher.java @@ -0,0 +1,49 @@ +/** + * Copyright © 2016-2021 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.fetch; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; + +import java.util.ArrayList; +import java.util.List; + +@AllArgsConstructor +@Slf4j +public class CustomerEdgeEventFetcher implements EdgeEventFetcher { + + @Override + public PageLink getPageLink(int pageSize) { + return null; + } + + @Override + public PageData fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { + List result = new ArrayList<>(); + result.add(EdgeEventUtils.constructEdgeEvent(edge.getTenantId(), edge.getId(), + EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, edge.getCustomerId(), null)); + // @voba - returns PageData object to be in sync with other fetchers + return new PageData<>(result, 1, result.size(), false); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/executors/GrpcCallbackExecutorService.java b/application/src/main/java/org/thingsboard/server/service/executors/GrpcCallbackExecutorService.java new file mode 100644 index 0000000000..2de1c21974 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/executors/GrpcCallbackExecutorService.java @@ -0,0 +1,33 @@ +/** + * Copyright © 2016-2021 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.executors; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.thingsboard.common.util.AbstractListeningExecutor; + +@Component +public class GrpcCallbackExecutorService extends AbstractListeningExecutor { + + @Value("${edges.grpc_callback_thread_pool_size}") + private int grpcCallbackExecutorThreadPoolSize; + + @Override + protected int getThreadPollSize() { + return grpcCallbackExecutorThreadPoolSize; + } + +} diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 9444002bf7..89adef5456 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -707,7 +707,9 @@ edges: max_read_records_count: "${EDGES_STORAGE_MAX_READ_RECORDS_COUNT:50}" no_read_records_sleep: "${EDGES_NO_READ_RECORDS_SLEEP:1000}" sleep_between_batches: "${EDGES_SLEEP_BETWEEN_BATCHES:1000}" - scheduler_pool_size: "${EDGES_SCHEDULER_POOL_SIZE:4}" + scheduler_pool_size: "${EDGES_SCHEDULER_POOL_SIZE:1}" + send_scheduler_pool_size: "${EDGES_SEND_SCHEDULER_POOL_SIZE:1}" + grpc_callback_thread_pool_size: "${EDGES_GRPC_CALLBACK_POOL_SIZE:1}" edge_events_ttl: "${EDGES_EDGE_EVENTS_TTL:0}" state: persistToTelemetry: "${EDGES_PERSIST_STATE_TO_TELEMETRY:false}" From 00c3e3ebeb64e146fe91120136c289cb33ae990f Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 9 Jul 2021 10:53:32 +0300 Subject: [PATCH 49/52] Refactor - rename variables. Remove redundant executor service --- .../service/edge/rpc/EdgeGrpcService.java | 30 ++++------- .../service/edge/rpc/EdgeGrpcSession.java | 50 ++++++++----------- 2 files changed, 31 insertions(+), 49 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 37d3c42c8a..e118a0b0c2 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -54,7 +54,6 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -103,11 +102,9 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i private Server server; - private ScheduledExecutorService scheduler; + private ScheduledExecutorService edgeEventProcessingExecutorService; - private ExecutorService syncExecutorService; - - private ScheduledExecutorService sendScheduler; + private ScheduledExecutorService sendDownlinkExecutorService; @PostConstruct public void init() { @@ -134,10 +131,8 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i log.error("Failed to start Edge RPC server!", e); throw new RuntimeException("Failed to start Edge RPC server!"); } - this.scheduler = Executors.newScheduledThreadPool(schedulerPoolSize, ThingsBoardThreadFactory.forName("edge-scheduler")); - this.sendScheduler = Executors.newScheduledThreadPool(sendSchedulerPoolSize, ThingsBoardThreadFactory.forName("edge-send-scheduler")); - this.syncExecutorService = Executors.newFixedThreadPool( - Runtime.getRuntime().availableProcessors(), ThingsBoardThreadFactory.forName("edge-sync")); + this.edgeEventProcessingExecutorService = Executors.newScheduledThreadPool(schedulerPoolSize, ThingsBoardThreadFactory.forName("edge-scheduler")); + this.sendDownlinkExecutorService = Executors.newScheduledThreadPool(sendSchedulerPoolSize, ThingsBoardThreadFactory.forName("edge-send-scheduler")); log.info("Edge RPC service initialized!"); } @@ -154,20 +149,17 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i sessionEdgeEventChecks.remove(edgeId); } } - if (scheduler != null) { - scheduler.shutdownNow(); - } - if (sendScheduler != null) { - sendScheduler.shutdownNow(); + if (edgeEventProcessingExecutorService != null) { + edgeEventProcessingExecutorService.shutdownNow(); } - if (syncExecutorService != null) { - syncExecutorService.shutdownNow(); + if (sendDownlinkExecutorService != null) { + sendDownlinkExecutorService.shutdownNow(); } } @Override public StreamObserver handleMsgs(StreamObserver outputStream) { - return new EdgeGrpcSession(ctx, outputStream, this::onEdgeConnect, this::onEdgeDisconnect, mapper, syncExecutorService, sendScheduler).getInputStream(); + return new EdgeGrpcSession(ctx, outputStream, this::onEdgeConnect, this::onEdgeDisconnect, mapper, sendDownlinkExecutorService).getInputStream(); } @Override @@ -245,7 +237,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i EdgeId edgeId = session.getEdge().getId(); UUID tenantId = session.getEdge().getTenantId().getId(); if (sessions.containsKey(edgeId)) { - ScheduledFuture schedule = scheduler.schedule(() -> { + ScheduledFuture edgeEventCheckTask = edgeEventProcessingExecutorService.schedule(() -> { try { final Lock newEventLock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); newEventLock.lock(); @@ -275,7 +267,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i log.warn("[{}] Failed to process edge events for edge [{}]!", tenantId, session.getEdge().getId().getId(), e); } }, ctx.getEdgeEventStorageSettings().getNoRecordsSleepInterval(), TimeUnit.MILLISECONDS); - sessionEdgeEventChecks.put(edgeId, schedule); + sessionEdgeEventChecks.put(edgeId, edgeEventCheckTask); log.trace("[{}] Check edge event scheduled for edge [{}]", tenantId, edgeId.getId()); } else { log.debug("[{}] Session was removed and edge event check schedule must not be started [{}]", diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index f16df05af8..74edc66084 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -79,7 +79,6 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -103,8 +102,9 @@ public final class EdgeGrpcSession implements Closeable { private final ObjectMapper mapper; private final Map pendingMsgsMap = new LinkedHashMap<>(); - private SettableFuture pendingFuture; - private ScheduledFuture sendSchedule; + // TODO: voba - global future - possible refactoring + private SettableFuture sendDownlinkMsgsFuture; + private ScheduledFuture scheduledSendDownlinkTask; private EdgeContextComponent ctx; private Edge edge; @@ -113,20 +113,17 @@ public final class EdgeGrpcSession implements Closeable { private boolean connected; private boolean syncCompleted; - private ExecutorService syncExecutorService; - - private ScheduledExecutorService sendScheduler; + private ScheduledExecutorService sendDownlinkExecutorService; EdgeGrpcSession(EdgeContextComponent ctx, StreamObserver outputStream, BiConsumer sessionOpenListener, - Consumer sessionCloseListener, ObjectMapper mapper, ExecutorService syncExecutorService, ScheduledExecutorService sendScheduler) { + Consumer sessionCloseListener, ObjectMapper mapper, ScheduledExecutorService sendDownlinkExecutorService) { this.sessionId = UUID.randomUUID(); this.ctx = ctx; this.outputStream = outputStream; this.sessionOpenListener = sessionOpenListener; this.sessionCloseListener = sessionCloseListener; this.mapper = mapper; - this.syncExecutorService = syncExecutorService; - this.sendScheduler = sendScheduler; + this.sendDownlinkExecutorService = sendDownlinkExecutorService; initInputStream(); } @@ -194,13 +191,7 @@ public final class EdgeGrpcSession implements Closeable { public void startSyncProcess(TenantId tenantId, EdgeId edgeId) { log.trace("[{}][{}] Staring edge sync process", tenantId, edgeId); syncCompleted = false; - syncExecutorService.submit(() -> { - try { - doSync(new EdgeSyncCursor(ctx, edge)); - } catch (Exception e) { - log.error("[{}][{}] Exception during sync process", edge.getTenantId(), edge.getId(), e); - } - }); + doSync(new EdgeSyncCursor(ctx, edge)); } private void doSync(EdgeSyncCursor cursor) { @@ -273,10 +264,10 @@ public final class EdgeGrpcSession implements Closeable { } if (pendingMsgsMap.size() == 0) { log.debug("[{}] Pending msgs map is empty. Stopping current iteration {}", edge.getRoutingKey(), msg); - if (sendSchedule != null) { - sendSchedule.cancel(false); + if (scheduledSendDownlinkTask != null) { + scheduledSendDownlinkTask.cancel(false); } - pendingFuture.set(null); + sendDownlinkMsgsFuture.set(null); } } catch (Exception e) { log.error("[{}] Can't process downlink response message [{}]", this.sessionId, msg, e); @@ -399,21 +390,20 @@ public final class EdgeGrpcSession implements Closeable { } private ListenableFuture sendDownlinkMsgsPack(List downlinkMsgsPack) { - SettableFuture result = SettableFuture.create(); + sendDownlinkMsgsFuture = SettableFuture.create(); downlinkMsgsPackLock.lock(); try { pendingMsgsMap.clear(); downlinkMsgsPack.forEach(msg -> pendingMsgsMap.put(msg.getDownlinkMsgId(), msg)); - scheduleDownlinkMsgsPackSend(true, result); + scheduleDownlinkMsgsPackSend(true); } finally { downlinkMsgsPackLock.unlock(); } - return result; + return sendDownlinkMsgsFuture; } - private void scheduleDownlinkMsgsPackSend(boolean firstRun, SettableFuture futureResult) { - pendingFuture = futureResult; - Runnable runnable = () -> { + private void scheduleDownlinkMsgsPackSend(boolean firstRun) { + Runnable sendDownlinkMsgsTask = () -> { try { if (isConnected() && pendingMsgsMap.values().size() > 0) { if (!firstRun) { @@ -426,19 +416,19 @@ public final class EdgeGrpcSession implements Closeable { .setDownlinkMsg(downlinkMsg) .build()); } - scheduleDownlinkMsgsPackSend(false, futureResult); + scheduleDownlinkMsgsPackSend(false); } else { - futureResult.set(null); + sendDownlinkMsgsFuture.set(null); } } catch (Exception e) { - futureResult.setException(e); + sendDownlinkMsgsFuture.setException(e); } }; if (firstRun) { - syncExecutorService.submit(runnable); + sendDownlinkExecutorService.submit(sendDownlinkMsgsTask); } else { - sendSchedule = sendScheduler.schedule(runnable, ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches(), TimeUnit.MILLISECONDS); + scheduledSendDownlinkTask = sendDownlinkExecutorService.schedule(sendDownlinkMsgsTask, ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches(), TimeUnit.MILLISECONDS); } } From 9af40455bbdca027c9b4449e3266eff54d36d6d0 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 9 Jul 2021 11:06:29 +0300 Subject: [PATCH 50/52] Removed redundant lock --- .../service/edge/rpc/EdgeGrpcSession.java | 17 ++++++++--------- .../server/service/edge/rpc/EdgeSyncCursor.java | 12 ++++++------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 74edc66084..7fa5cc399e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -92,7 +92,6 @@ import java.util.stream.Collectors; public final class EdgeGrpcSession implements Closeable { private static final ReentrantLock downlinkMsgLock = new ReentrantLock(); - private static final ReentrantLock downlinkMsgsPackLock = new ReentrantLock(); private static final String QUEUE_START_TS_ATTR_KEY = "queueStartTs"; @@ -390,15 +389,15 @@ public final class EdgeGrpcSession implements Closeable { } private ListenableFuture sendDownlinkMsgsPack(List downlinkMsgsPack) { - sendDownlinkMsgsFuture = SettableFuture.create(); - downlinkMsgsPackLock.lock(); - try { - pendingMsgsMap.clear(); - downlinkMsgsPack.forEach(msg -> pendingMsgsMap.put(msg.getDownlinkMsgId(), msg)); - scheduleDownlinkMsgsPackSend(true); - } finally { - downlinkMsgsPackLock.unlock(); + if (sendDownlinkMsgsFuture != null && !sendDownlinkMsgsFuture.isDone()) { + String erroMsg = "[" + this.sessionId + "] Previous send downdlink future was not properly completed, stopping it now"; + log.error(erroMsg); + sendDownlinkMsgsFuture.setException(new RuntimeException(erroMsg)); } + sendDownlinkMsgsFuture = SettableFuture.create(); + pendingMsgsMap.clear(); + downlinkMsgsPack.forEach(msg -> pendingMsgsMap.put(msg.getDownlinkMsgId(), msg)); + scheduleDownlinkMsgsPackSend(true); return sendDownlinkMsgsFuture; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java index 85ef95ee12..cb7916965f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java @@ -32,6 +32,7 @@ import org.thingsboard.server.service.edge.rpc.fetch.TenantWidgetsBundlesEdgeEve import java.util.LinkedList; import java.util.List; +import java.util.NoSuchElementException; public class EdgeSyncCursor { @@ -59,13 +60,12 @@ public class EdgeSyncCursor { } public EdgeEventFetcher getNext() { - if (hasNext()) { - EdgeEventFetcher edgeEventFetcher = fetchers.get(currentIdx); - currentIdx++; - return edgeEventFetcher; - } else { - throw new IndexOutOfBoundsException(); + if (!hasNext()) { + throw new NoSuchElementException(); } + EdgeEventFetcher edgeEventFetcher = fetchers.get(currentIdx); + currentIdx++; + return edgeEventFetcher; } public int getCurrentIdx() { From e9419d7f998ad198d85c7a0e5d97fb88fe875b58 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 9 Jul 2021 19:55:50 +0300 Subject: [PATCH 51/52] Updated msg to be able identify that its expected --- .../java/org/thingsboard/server/edge/imitator/EdgeImitator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index af486ae0f4..9f95b11c3e 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -216,7 +216,7 @@ public class EdgeImitator { for (EntityDataProto entityData : downlinkMsg.getEntityDataList()) { if (randomFailuresOnTimeseriesDownlink) { if (getRandomBoolean()) { - result.add(Futures.immediateFailedFuture(new RuntimeException("Random failure"))); + result.add(Futures.immediateFailedFuture(new RuntimeException("Random failure. This is expected error for edge test"))); } else { result.add(saveDownlinkMsg(entityData)); } From a500aa013aa110fcabd3db593308684f4c9e0114 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 13 Jul 2021 21:40:58 +0300 Subject: [PATCH 52/52] Revert incorrect try/lock --- .../server/service/script/AbstractNashornJsInvokeService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java b/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java index 20b8d7979d..15a3cf1c15 100644 --- a/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java +++ b/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java @@ -124,8 +124,8 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer protected ListenableFuture doEval(UUID scriptId, String functionName, String jsScript) { jsPushedMsgs.incrementAndGet(); ListenableFuture result = jsExecutor.executeAsync(() -> { - evalLock.lock(); try { + evalLock.lock(); try { if (useJsSandbox()) { sandbox.eval(jsScript);