thingsboard-aplcache

Details

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 50a4f7d..6f66a77 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<List<AttributeKvEntry>> clientAttributesFuture = getAttributeKvEntries(deviceId, DataConstants.CLIENT_SCOPE, toOptionalSet(request.getClientAttributeNamesList()));
-        ListenableFuture<List<AttributeKvEntry>> sharedAttributesFuture = getAttributeKvEntries(deviceId, DataConstants.SHARED_SCOPE, toOptionalSet(request.getSharedAttributeNamesList()));
         int requestId = request.getRequestId();
-        Futures.addCallback(Futures.allAsList(Arrays.asList(clientAttributesFuture, sharedAttributesFuture)), new FutureCallback<List<List<AttributeKvEntry>>>() {
+        Futures.addCallback(getAttributesKvEntries(request), new FutureCallback<List<List<AttributeKvEntry>>>() {
             @Override
             public void onSuccess(@Nullable List<List<AttributeKvEntry>> result) {
                 GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()
@@ -285,16 +285,76 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
         });
     }
 
-    private ListenableFuture<List<AttributeKvEntry>> getAttributeKvEntries(DeviceId deviceId, String scope, Optional<Set<String>> names) {
-        if (names.isPresent()) {
-            if (!names.get().isEmpty()) {
-                return systemContext.getAttributesService().find(tenantId, deviceId, scope, names.get());
+    private ListenableFuture<List<List<AttributeKvEntry>>> getAttributesKvEntries(GetAttributeRequestMsg request) {
+        ListenableFuture<List<AttributeKvEntry>> clientAttributesFuture;
+        ListenableFuture<List<AttributeKvEntry>> 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 {
+                clientAttributesFuture = findAllClientAttributes();
+                sharedAttributesFuture = findAllSharedAttributes();
+            }
+        } else if (clientIsPresent(request) && !sharedIsPresent(request)) {
+            if (clientIsNotEmpty(request)) {
+                clientAttributesFuture = findClientAttributes(request);
             } else {
-                return systemContext.getAttributesService().findAll(tenantId, deviceId, scope);
+                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<List<AttributeKvEntry>> findAllSharedAttributes() {
+        return systemContext.getAttributesService().findAll(tenantId, deviceId, SHARED_SCOPE);
+    }
+
+    private ListenableFuture<List<AttributeKvEntry>> findAllClientAttributes() {
+        return systemContext.getAttributesService().findAll(tenantId, deviceId, CLIENT_SCOPE);
+    }
+
+    private ListenableFuture<List<AttributeKvEntry>> findSharedAttributes(GetAttributeRequestMsg request) {
+        return systemContext.getAttributesService().find(tenantId, deviceId, SHARED_SCOPE, getSharedAttributesSet(request));
+    }
+
+    private ListenableFuture<List<AttributeKvEntry>> 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<String> getSharedAttributesSet(GetAttributeRequestMsg request) {
+        return toOptionalSet(request.getSharedAttributeNamesList()).get();
+    }
+
+    private Set<String> 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<String> 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<AttributeKvEntry> attributes = new ArrayList<>(msg.getValues());
                     if (attributes.size() > 0) {
                         List<TsKvProto> sharedUpdated = msg.getValues().stream().map(this::toTsKvProto)