From ccd4f4b09692c7b1f673e28238007f19182f744a Mon Sep 17 00:00:00 2001 From: Andrew Shvayka Date: Thu, 29 Dec 2016 16:28:49 +0200 Subject: [PATCH] Improvements --- .../msg/core/BasicGetAttributesRequest.java | 14 ++++++++--- .../common/msg/core/GetAttributesRequest.java | 5 ++-- .../cmd/AttributesSubscriptionCmd.java | 4 --- .../plugin/telemetry/cmd/SubscriptionCmd.java | 9 +++++++ .../cmd/TimeseriesSubscriptionCmd.java | 5 ---- .../handlers/TelemetryRuleMsgHandler.java | 10 +++++--- .../TelemetryWebsocketMsgHandler.java | 13 ++++++++-- .../coap/adaptors/JsonCoapAdaptor.java | 18 ++++++------- .../server/transport/coap/CoapServerTest.java | 2 +- .../transport/http/DeviceApiController.java | 25 +++++++++++-------- .../mqtt/adaptors/JsonMqttAdaptor.java | 11 +++++--- ui/src/app/api/device.service.js | 3 ++- 12 files changed, 72 insertions(+), 47 deletions(-) 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 a8fdc86454..676cfb795e 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 clientKeys; private final Set sharedKeys; + public BasicGetAttributesRequest(Integer requestId) { + this(requestId, Collections.emptySet(), Collections.emptySet()); + } + public BasicGetAttributesRequest(Integer requestId, Set clientKeys, Set sharedKeys) { super(requestId); this.clientKeys = clientKeys; @@ -40,13 +46,13 @@ public class BasicGetAttributesRequest extends BasicRequest implements GetAttrib } @Override - public Set getClientAttributeNames() { - return clientKeys; + public Optional> getClientAttributeNames() { + return Optional.of(clientKeys); } @Override - public Set getSharedAttributeNames() { - return sharedKeys; + public Optional> 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 49bca53951..0a9e1c2a9e 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 getClientAttributeNames(); - Set getSharedAttributeNames(); + Optional> getClientAttributeNames(); + Optional> 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 e7bc414227..3190bbf792 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 249dfa977d..0d5fa48200 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 0b0ff91d46..92d7259b15 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 f69d17b9f1..f14d25d016 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 getAttributeKvEntries(PluginContext ctx, DeviceId deviceId, String scope, Set names) { + private List getAttributeKvEntries(PluginContext ctx, DeviceId deviceId, String scope, Optional> names) { List 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 849b3225d5..f268dd8ce1 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 keys = new ArrayList<>(keysOptional.get()); List 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 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 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 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 26a905652a..a9c6086eea 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 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!")); + if (queryElements != null || queryElements.size() > 0) { + Set clientKeys = toKeys(ctx, queryElements, "clientKeys"); + Set sharedKeys = toKeys(ctx, queryElements, "sharedKeys"); + return new BasicGetAttributesRequest(0, clientKeys, sharedKeys); + } else { + return new BasicGetAttributesRequest(0); } - - Set clientKeys = toKeys(ctx, queryElements, "clientKeys"); - Set sharedKeys = toKeys(ctx, queryElements, "sharedKeys"); - if (clientKeys.isEmpty() && sharedKeys.isEmpty()) { - throw new AdaptorException("No clientKeys and serverKeys parameters!"); - } - return new BasicGetAttributesRequest(0, clientKeys, sharedKeys); } private Set toKeys(SessionContext ctx, List 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 a2d6c25f69..ceb6813ad7 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 e3e06663f2..e815bc5de9 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 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 responseWriter = new DeferredResult(); - 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 clientKeySet = new HashSet<>(Arrays.asList(clientKeys.split(","))); - Set 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 clientKeySet = !StringUtils.isEmpty(clientKeys) ? new HashSet<>(Arrays.asList(clientKeys.split(","))) : null; + Set 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 5af244ad74..e84e848541 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 clientKeys = toStringSet(requestBody, "clientKeys"); + Set 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 cf38d12c23..27cf605c6b 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 ?