thingsboard-aplcache

Improvements

12/29/2016 12:28:49 PM

Details

diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/core/BasicGetAttributesRequest.java b/common/message/src/main/java/org/thingsboard/server/common/msg/core/BasicGetAttributesRequest.java
index a8fdc86..676cfb7 100644
--- a/common/message/src/main/java/org/thingsboard/server/common/msg/core/BasicGetAttributesRequest.java
+++ b/common/message/src/main/java/org/thingsboard/server/common/msg/core/BasicGetAttributesRequest.java
@@ -18,6 +18,8 @@ package org.thingsboard.server.common.msg.core;
 import lombok.ToString;
 import org.thingsboard.server.common.msg.session.MsgType;
 
+import java.util.Collections;
+import java.util.Optional;
 import java.util.Set;
 
 @ToString
@@ -28,6 +30,10 @@ public class BasicGetAttributesRequest extends BasicRequest implements GetAttrib
     private final Set<String> clientKeys;
     private final Set<String> sharedKeys;
 
+    public BasicGetAttributesRequest(Integer requestId) {
+        this(requestId, Collections.emptySet(), Collections.emptySet());
+    }
+
     public BasicGetAttributesRequest(Integer requestId, Set<String> clientKeys, Set<String> sharedKeys) {
         super(requestId);
         this.clientKeys = clientKeys;
@@ -40,13 +46,13 @@ public class BasicGetAttributesRequest extends BasicRequest implements GetAttrib
     }
 
     @Override
-    public Set<String> getClientAttributeNames() {
-        return clientKeys;
+    public Optional<Set<String>> getClientAttributeNames() {
+        return Optional.of(clientKeys);
     }
 
     @Override
-    public Set<String> getSharedAttributeNames() {
-        return sharedKeys;
+    public Optional<Set<String>> getSharedAttributeNames() {
+        return Optional.ofNullable(sharedKeys);
     }
 
 }
diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/core/GetAttributesRequest.java b/common/message/src/main/java/org/thingsboard/server/common/msg/core/GetAttributesRequest.java
index 49bca53..0a9e1c2 100644
--- a/common/message/src/main/java/org/thingsboard/server/common/msg/core/GetAttributesRequest.java
+++ b/common/message/src/main/java/org/thingsboard/server/common/msg/core/GetAttributesRequest.java
@@ -15,6 +15,7 @@
  */
 package org.thingsboard.server.common.msg.core;
 
+import java.util.Optional;
 import java.util.Set;
 
 import org.thingsboard.server.common.msg.session.FromDeviceMsg;
@@ -22,7 +23,7 @@ import org.thingsboard.server.common.msg.session.FromDeviceRequestMsg;
 
 public interface GetAttributesRequest extends FromDeviceRequestMsg {
 
-    Set<String> getClientAttributeNames();
-    Set<String> getSharedAttributeNames();
+    Optional<Set<String>> getClientAttributeNames();
+    Optional<Set<String>> getSharedAttributeNames();
 
 }
diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/cmd/AttributesSubscriptionCmd.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/cmd/AttributesSubscriptionCmd.java
index e7bc414..3190bbf 100644
--- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/cmd/AttributesSubscriptionCmd.java
+++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/cmd/AttributesSubscriptionCmd.java
@@ -24,10 +24,6 @@ import org.thingsboard.server.extensions.core.plugin.telemetry.sub.SubscriptionT
 @NoArgsConstructor
 public class AttributesSubscriptionCmd extends SubscriptionCmd {
 
-    public AttributesSubscriptionCmd(int cmdId, String deviceId, String keys, boolean unsubscribe) {
-        super(cmdId, deviceId, keys, unsubscribe);
-    }
-
     @Override
     public SubscriptionType getType() {
         return SubscriptionType.ATTRIBUTES;
diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/cmd/SubscriptionCmd.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/cmd/SubscriptionCmd.java
index 249dfa9..0d5fa48 100644
--- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/cmd/SubscriptionCmd.java
+++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/cmd/SubscriptionCmd.java
@@ -26,6 +26,7 @@ public abstract class SubscriptionCmd implements TelemetryPluginCmd {
     private int cmdId;
     private String deviceId;
     private String keys;
+    private String scope;
     private boolean unsubscribe;
 
     public abstract SubscriptionType getType();
@@ -62,6 +63,14 @@ public abstract class SubscriptionCmd implements TelemetryPluginCmd {
         this.unsubscribe = unsubscribe;
     }
 
+    public String getScope() {
+        return scope;
+    }
+
+    public void setKeys(String keys) {
+        this.keys = keys;
+    }
+
     @Override
     public String toString() {
         return "SubscriptionCmd [deviceId=" + deviceId + ", tags=" + keys + ", unsubscribe=" + unsubscribe + "]";
diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/cmd/TimeseriesSubscriptionCmd.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/cmd/TimeseriesSubscriptionCmd.java
index 0b0ff91..92d7259 100644
--- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/cmd/TimeseriesSubscriptionCmd.java
+++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/cmd/TimeseriesSubscriptionCmd.java
@@ -26,11 +26,6 @@ public class TimeseriesSubscriptionCmd extends SubscriptionCmd {
 
     private long timeWindow;
 
-    public TimeseriesSubscriptionCmd(int cmdId, String deviceId, String keys, boolean unsubscribe, long timeWindow) {
-        super(cmdId, deviceId, keys, unsubscribe);
-        this.timeWindow = timeWindow;
-    }
-
     public long getTimeWindow() {
         return timeWindow;
     }
diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRuleMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRuleMsgHandler.java
index f69d17b..f14d25d 100644
--- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRuleMsgHandler.java
+++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRuleMsgHandler.java
@@ -58,10 +58,14 @@ public class TelemetryRuleMsgHandler extends DefaultRuleMsgHandler {
         ctx.reply(new ResponsePluginToRuleMsg(msg.getUid(), tenantId, ruleId, response));
     }
 
-    private List<AttributeKvEntry> getAttributeKvEntries(PluginContext ctx, DeviceId deviceId, String scope, Set<String> names) {
+    private List<AttributeKvEntry> getAttributeKvEntries(PluginContext ctx, DeviceId deviceId, String scope, Optional<Set<String>> names) {
         List<AttributeKvEntry> attributes;
-        if (!names.isEmpty()) {
-            attributes = ctx.loadAttributes(deviceId, scope, new ArrayList<>(names));
+        if (names.isPresent()) {
+            if (!names.get().isEmpty()) {
+                attributes = ctx.loadAttributes(deviceId, scope, new ArrayList<>(names.get()));
+            } else {
+                attributes = ctx.loadAttributes(deviceId, scope);
+            }
         } else {
             attributes = Collections.emptyList();
         }
diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java
index 849b322..f268dd8 100644
--- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java
+++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java
@@ -105,7 +105,12 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler {
                 if (keysOptional.isPresent()) {
                     List<String> keys = new ArrayList<>(keysOptional.get());
                     List<AttributeKvEntry> data = new ArrayList<>();
-                    Arrays.stream(DataConstants.ALL_SCOPES).forEach(s -> data.addAll(ctx.loadAttributes(deviceId, s, keys)));
+                    if (StringUtils.isEmpty(cmd.getScope())) {
+                        Arrays.stream(DataConstants.ALL_SCOPES).forEach(s -> data.addAll(ctx.loadAttributes(deviceId, s, keys)));
+                    } else {
+                        data.addAll(ctx.loadAttributes(deviceId, cmd.getScope(), keys));
+                    }
+
                     List<TsKvEntry> attributesData = data.stream().map(d -> new BasicTsKvEntry(d.getLastUpdateTs(), d)).collect(Collectors.toList());
                     sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), attributesData));
 
@@ -116,7 +121,11 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler {
                     sub = new SubscriptionState(sessionId, cmd.getCmdId(), deviceId, SubscriptionType.ATTRIBUTES, false, subState);
                 } else {
                     List<AttributeKvEntry> data = new ArrayList<>();
-                    Arrays.stream(DataConstants.ALL_SCOPES).forEach(s -> data.addAll(ctx.loadAttributes(deviceId, s)));
+                    if (StringUtils.isEmpty(cmd.getScope())) {
+                        Arrays.stream(DataConstants.ALL_SCOPES).forEach(s -> data.addAll(ctx.loadAttributes(deviceId, s)));
+                    } else {
+                        data.addAll(ctx.loadAttributes(deviceId, cmd.getScope()));
+                    }
                     List<TsKvEntry> attributesData = data.stream().map(d -> new BasicTsKvEntry(d.getLastUpdateTs(), d)).collect(Collectors.toList());
                     sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), attributesData));
 
diff --git a/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java b/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java
index 26a9056..a9c6086 100644
--- a/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java
+++ b/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java
@@ -167,17 +167,13 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
 
     private FromDeviceMsg convertToGetAttributesRequest(SessionContext ctx, Request inbound) throws AdaptorException {
         List<String> queryElements = inbound.getOptions().getUriQuery();
-        if (queryElements == null || queryElements.size() == 0) {
-            log.warn("[{}] Query is empty!", ctx.getSessionId());
-            throw new AdaptorException(new IllegalArgumentException("Query is empty!"));
-        }
-
-        Set<String> clientKeys = toKeys(ctx, queryElements, "clientKeys");
-        Set<String> sharedKeys = toKeys(ctx, queryElements, "sharedKeys");
-        if (clientKeys.isEmpty() && sharedKeys.isEmpty()) {
-            throw new AdaptorException("No clientKeys and serverKeys parameters!");
+        if (queryElements != null || queryElements.size() > 0) {
+            Set<String> clientKeys = toKeys(ctx, queryElements, "clientKeys");
+            Set<String> sharedKeys = toKeys(ctx, queryElements, "sharedKeys");
+            return new BasicGetAttributesRequest(0, clientKeys, sharedKeys);
+        } else {
+            return new BasicGetAttributesRequest(0);
         }
-        return new BasicGetAttributesRequest(0, clientKeys, sharedKeys);
     }
 
     private Set<String> toKeys(SessionContext ctx, List<String> queryElements, String attributeName) throws AdaptorException {
@@ -191,7 +187,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
         if (!StringUtils.isEmpty(keys)) {
             return new HashSet<>(Arrays.asList(keys.split(",")));
         } else {
-            return Collections.emptySet();
+            return null;
         }
     }
 
diff --git a/transport/coap/src/test/java/org/thingsboard/server/transport/coap/CoapServerTest.java b/transport/coap/src/test/java/org/thingsboard/server/transport/coap/CoapServerTest.java
index a2d6c25..ceb6813 100644
--- a/transport/coap/src/test/java/org/thingsboard/server/transport/coap/CoapServerTest.java
+++ b/transport/coap/src/test/java/org/thingsboard/server/transport/coap/CoapServerTest.java
@@ -182,7 +182,7 @@ public class CoapServerTest {
     public void testNoKeysAttributesGetRequest() {
         CoapClient client = new CoapClient(getBaseTestUrl() + DEVICE1_TOKEN + "/" + FeatureType.ATTRIBUTES.name().toLowerCase() + "?data=key1,key2");
         CoapResponse response = client.setTimeout(6000).get();
-        Assert.assertEquals(ResponseCode.BAD_REQUEST, response.getCode());
+        Assert.assertEquals(ResponseCode.CONTENT, response.getCode());
     }
 
     @Test
diff --git a/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java b/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java
index e3e0666..e815bc5 100644
--- a/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java
+++ b/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java
@@ -38,6 +38,7 @@ import org.thingsboard.server.common.transport.auth.DeviceAuthService;
 import org.thingsboard.server.transport.http.session.HttpSessionCtx;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -60,20 +61,22 @@ public class DeviceApiController {
 
     @RequestMapping(value = "/{deviceToken}/attributes", method = RequestMethod.GET, produces = "application/json")
     public DeferredResult<ResponseEntity> getDeviceAttributes(@PathVariable("deviceToken") String deviceToken,
-                                                              @RequestParam(value = "clientKeys", required = false) String clientKeys,
-                                                              @RequestParam(value = "sharedKeys", required = false) String sharedKeys) {
+                                                              @RequestParam(value = "clientKeys", required = false, defaultValue = "") String clientKeys,
+                                                              @RequestParam(value = "sharedKeys", required = false, defaultValue = "") String sharedKeys) {
         DeferredResult<ResponseEntity> responseWriter = new DeferredResult<ResponseEntity>();
-        if (StringUtils.isEmpty(clientKeys) && StringUtils.isEmpty(sharedKeys)) {
-            responseWriter.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));
-        } else {
-            HttpSessionCtx ctx = getHttpSessionCtx(responseWriter);
-            if (ctx.login(new DeviceTokenCredentials(deviceToken))) {
-                Set<String> clientKeySet = new HashSet<>(Arrays.asList(clientKeys.split(",")));
-                Set<String> sharedKeySet = new HashSet<>(Arrays.asList(clientKeys.split(",")));
-                process(ctx, new BasicGetAttributesRequest(0, clientKeySet, sharedKeySet));
+        HttpSessionCtx ctx = getHttpSessionCtx(responseWriter);
+        if (ctx.login(new DeviceTokenCredentials(deviceToken))) {
+            GetAttributesRequest request;
+            if (StringUtils.isEmpty(clientKeys) && StringUtils.isEmpty(sharedKeys)) {
+                request = new BasicGetAttributesRequest(0);
             } else {
-                responseWriter.setResult(new ResponseEntity<>(HttpStatus.UNAUTHORIZED));
+                Set<String> clientKeySet = !StringUtils.isEmpty(clientKeys) ? new HashSet<>(Arrays.asList(clientKeys.split(","))) : null;
+                Set<String> sharedKeySet = !StringUtils.isEmpty(sharedKeys) ? new HashSet<>(Arrays.asList(sharedKeys.split(","))) : null;
+                request = new BasicGetAttributesRequest(0, clientKeySet, sharedKeySet);
             }
+            process(ctx, request);
+        } else {
+            responseWriter.setResult(new ResponseEntity<>(HttpStatus.UNAUTHORIZED));
         }
 
         return responseWriter;
diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java
index 5af244a..e84e848 100644
--- a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java
+++ b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java
@@ -162,8 +162,13 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor {
             Integer requestId = Integer.valueOf(topicName.substring(MqttTransportHandler.ATTRIBUTES_REQUEST_TOPIC_PREFIX.length()));
             String payload = inbound.payload().toString(UTF8);
             JsonElement requestBody = new JsonParser().parse(payload);
-            return new BasicGetAttributesRequest(requestId,
-                    toStringSet(requestBody, "clientKeys"), toStringSet(requestBody, "sharedKeys"));
+            Set<String> clientKeys = toStringSet(requestBody, "clientKeys");
+            Set<String> sharedKeys = toStringSet(requestBody, "sharedKeys");
+            if (clientKeys == null && sharedKeys == null) {
+                return new BasicGetAttributesRequest(requestId);
+            } else {
+                return new BasicGetAttributesRequest(requestId, clientKeys, sharedKeys);
+            }
         } catch (RuntimeException e) {
             log.warn("Failed to decode get attributes request", e);
             throw new AdaptorException(e);
@@ -189,7 +194,7 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor {
         if (element != null) {
             return new HashSet<>(Arrays.asList(element.getAsString().split(",")));
         } else {
-            return Collections.emptySet();
+            return null;
         }
     }
 
diff --git a/ui/src/app/api/device.service.js b/ui/src/app/api/device.service.js
index cf38d12..27cf605 100644
--- a/ui/src/app/api/device.service.js
+++ b/ui/src/app/api/device.service.js
@@ -293,7 +293,8 @@ function DeviceService($http, $q, $filter, telemetryWebsocketService, types) {
         var deviceAttributesSubscription = deviceAttributesSubscriptionMap[subscriptionId];
         if (!deviceAttributesSubscription) {
             var subscriptionCommand = {
-                deviceId: deviceId
+                deviceId: deviceId,
+                scope: attributeScope
             };
 
             var type = attributeScope === types.latestTelemetry.value ?