diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 50a4f7d01b..6f66a77eb2 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -30,7 +30,6 @@ import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; @@ -85,6 +84,9 @@ import java.util.UUID; import java.util.function.Consumer; import java.util.stream.Collectors; +import static org.thingsboard.server.common.data.DataConstants.CLIENT_SCOPE; +import static org.thingsboard.server.common.data.DataConstants.SHARED_SCOPE; + /** * @author Andrew Shvayka */ @@ -261,10 +263,8 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { } private void handleGetAttributesRequest(ActorContext context, SessionInfoProto sessionInfo, GetAttributeRequestMsg request) { - ListenableFuture> clientAttributesFuture = getAttributeKvEntries(deviceId, DataConstants.CLIENT_SCOPE, toOptionalSet(request.getClientAttributeNamesList())); - ListenableFuture> sharedAttributesFuture = getAttributeKvEntries(deviceId, DataConstants.SHARED_SCOPE, toOptionalSet(request.getSharedAttributeNamesList())); int requestId = request.getRequestId(); - Futures.addCallback(Futures.allAsList(Arrays.asList(clientAttributesFuture, sharedAttributesFuture)), new FutureCallback>>() { + Futures.addCallback(getAttributesKvEntries(request), new FutureCallback>>() { @Override public void onSuccess(@Nullable List> result) { GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder() @@ -285,16 +285,76 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { }); } - private ListenableFuture> getAttributeKvEntries(DeviceId deviceId, String scope, Optional> names) { - if (names.isPresent()) { - if (!names.get().isEmpty()) { - return systemContext.getAttributesService().find(tenantId, deviceId, scope, names.get()); + private ListenableFuture>> getAttributesKvEntries(GetAttributeRequestMsg request) { + ListenableFuture> clientAttributesFuture; + ListenableFuture> sharedAttributesFuture; + if (!clientIsPresent(request) && !sharedIsPresent(request)) { + clientAttributesFuture = findAllClientAttributes(); + sharedAttributesFuture = findAllSharedAttributes(); + } else if (clientIsPresent(request) && sharedIsPresent(request)) { + if (clientIsNotEmpty(request) && sharedIsNotEmpty(request)) { + clientAttributesFuture = findClientAttributes(request); + sharedAttributesFuture = findSharedAttributes(request); } else { - return systemContext.getAttributesService().findAll(tenantId, deviceId, scope); + clientAttributesFuture = findAllClientAttributes(); + sharedAttributesFuture = findAllSharedAttributes(); } + } else if (clientIsPresent(request) && !sharedIsPresent(request)) { + if (clientIsNotEmpty(request)) { + clientAttributesFuture = findClientAttributes(request); + } else { + clientAttributesFuture = findAllClientAttributes(); + } + sharedAttributesFuture = Futures.immediateFuture(Collections.emptyList()); } else { - return systemContext.getAttributesService().findAll(tenantId, deviceId, scope); + if (sharedIsNotEmpty(request)) { + sharedAttributesFuture = findSharedAttributes(request); + } else { + sharedAttributesFuture = findAllSharedAttributes(); + } + clientAttributesFuture = Futures.immediateFuture(Collections.emptyList()); } + return Futures.allAsList(Arrays.asList(clientAttributesFuture, sharedAttributesFuture)); + } + + private ListenableFuture> findAllSharedAttributes() { + return systemContext.getAttributesService().findAll(tenantId, deviceId, SHARED_SCOPE); + } + + private ListenableFuture> findAllClientAttributes() { + return systemContext.getAttributesService().findAll(tenantId, deviceId, CLIENT_SCOPE); + } + + private ListenableFuture> findSharedAttributes(GetAttributeRequestMsg request) { + return systemContext.getAttributesService().find(tenantId, deviceId, SHARED_SCOPE, getSharedAttributesSet(request)); + } + + private ListenableFuture> findClientAttributes(GetAttributeRequestMsg request) { + return systemContext.getAttributesService().find(tenantId, deviceId, CLIENT_SCOPE, getClientAttributesSet(request)); + } + + private boolean clientIsNotEmpty(GetAttributeRequestMsg request) { + return !getClientAttributesSet(request).isEmpty(); + } + + private boolean sharedIsNotEmpty(GetAttributeRequestMsg request) { + return !getSharedAttributesSet(request).isEmpty(); + } + + private Set getSharedAttributesSet(GetAttributeRequestMsg request) { + return toOptionalSet(request.getSharedAttributeNamesList()).get(); + } + + private Set getClientAttributesSet(GetAttributeRequestMsg request) { + return toOptionalSet(request.getClientAttributeNamesList()).get(); + } + + private boolean sharedIsPresent(GetAttributeRequestMsg request) { + return toOptionalSet(request.getSharedAttributeNamesList()).isPresent(); + } + + private boolean clientIsPresent(GetAttributeRequestMsg request) { + return toOptionalSet(request.getClientAttributeNamesList()).isPresent(); } private void handlePostAttributesRequest(ActorContext context, SessionInfoProto sessionInfo, PostAttributeMsg postAttributes) { @@ -366,7 +426,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { AttributeUpdateNotificationMsg.Builder notification = AttributeUpdateNotificationMsg.newBuilder(); if (msg.isDeleted()) { List sharedKeys = msg.getDeletedKeys().stream() - .filter(key -> DataConstants.SHARED_SCOPE.equals(key.getScope())) + .filter(key -> SHARED_SCOPE.equals(key.getScope())) .map(AttributeKey::getAttributeKey) .collect(Collectors.toList()); if (!sharedKeys.isEmpty()) { @@ -374,7 +434,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { hasNotificationData = true; } } else { - if (DataConstants.SHARED_SCOPE.equals(msg.getScope())) { + if (SHARED_SCOPE.equals(msg.getScope())) { List attributes = new ArrayList<>(msg.getValues()); if (attributes.size() > 0) { List sharedUpdated = msg.getValues().stream().map(this::toTsKvProto)