Commit 336f0dc07952845e814fdcd45f4073129e4c4105

Authored by Andrew Shvayka
1 parent f7b0ec98

Ability to fetch multiple device attributes using Gateway MQTT API

@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.transport.mqtt.session; 16 package org.thingsboard.server.transport.mqtt.session;
17 17
18 import com.google.gson.Gson; 18 import com.google.gson.Gson;
  19 +import com.google.gson.JsonArray;
19 import com.google.gson.JsonElement; 20 import com.google.gson.JsonElement;
20 import com.google.gson.JsonObject; 21 import com.google.gson.JsonObject;
21 import io.netty.buffer.ByteBuf; 22 import io.netty.buffer.ByteBuf;
@@ -24,6 +25,7 @@ import io.netty.buffer.UnpooledByteBufAllocator; @@ -24,6 +25,7 @@ import io.netty.buffer.UnpooledByteBufAllocator;
24 import io.netty.handler.codec.mqtt.*; 25 import io.netty.handler.codec.mqtt.*;
25 import org.thingsboard.server.common.data.Device; 26 import org.thingsboard.server.common.data.Device;
26 import org.thingsboard.server.common.data.id.SessionId; 27 import org.thingsboard.server.common.data.id.SessionId;
  28 +import org.thingsboard.server.common.data.kv.AttributeKvEntry;
27 import org.thingsboard.server.common.data.kv.KvEntry; 29 import org.thingsboard.server.common.data.kv.KvEntry;
28 import org.thingsboard.server.common.msg.core.*; 30 import org.thingsboard.server.common.msg.core.*;
29 import org.thingsboard.server.common.msg.kv.AttributesKVMsg; 31 import org.thingsboard.server.common.msg.kv.AttributesKVMsg;
@@ -35,6 +37,7 @@ import org.thingsboard.server.transport.mqtt.MqttTopics; @@ -35,6 +37,7 @@ import org.thingsboard.server.transport.mqtt.MqttTopics;
35 import org.thingsboard.server.transport.mqtt.MqttTransportHandler; 37 import org.thingsboard.server.transport.mqtt.MqttTransportHandler;
36 38
37 import java.nio.charset.Charset; 39 import java.nio.charset.Charset;
  40 +import java.util.List;
38 import java.util.Optional; 41 import java.util.Optional;
39 import java.util.concurrent.atomic.AtomicInteger; 42 import java.util.concurrent.atomic.AtomicInteger;
40 43
@@ -135,40 +138,43 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext { @@ -135,40 +138,43 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext {
135 if (responseData.isPresent()) { 138 if (responseData.isPresent()) {
136 AttributesKVMsg msg = responseData.get(); 139 AttributesKVMsg msg = responseData.get();
137 if (msg.getClientAttributes() != null) { 140 if (msg.getClientAttributes() != null) {
138 - msg.getClientAttributes().forEach(v -> addValueToJson(result, "value", v)); 141 + addValues(result, msg.getClientAttributes());
139 } 142 }
140 if (msg.getSharedAttributes() != null) { 143 if (msg.getSharedAttributes() != null) {
141 - msg.getSharedAttributes().forEach(v -> addValueToJson(result, "value", v)); 144 + addValues(result, msg.getSharedAttributes());
142 } 145 }
143 } 146 }
144 return createMqttPublishMsg(topic, result); 147 return createMqttPublishMsg(topic, result);
145 } 148 }
146 149
  150 + private void addValues(JsonObject result, List<AttributeKvEntry> kvList) {
  151 + if (kvList.size() == 1) {
  152 + addValueToJson(result, "value", kvList.get(0));
  153 + } else {
  154 + JsonObject values;
  155 + if (result.has("values")) {
  156 + values = result.get("values").getAsJsonObject();
  157 + } else {
  158 + values = new JsonObject();
  159 + result.add("values", values);
  160 + }
  161 + kvList.forEach(value -> addValueToJson(values, value.getKey(), value));
  162 + }
  163 + }
  164 +
147 private void addValueToJson(JsonObject json, String name, KvEntry entry) { 165 private void addValueToJson(JsonObject json, String name, KvEntry entry) {
148 switch (entry.getDataType()) { 166 switch (entry.getDataType()) {
149 case BOOLEAN: 167 case BOOLEAN:
150 - Optional<Boolean> booleanValue = entry.getBooleanValue();  
151 - if (booleanValue.isPresent()) {  
152 - json.addProperty(name, booleanValue.get());  
153 - } 168 + entry.getBooleanValue().ifPresent(aBoolean -> json.addProperty(name, aBoolean));
154 break; 169 break;
155 case STRING: 170 case STRING:
156 - Optional<String> stringValue = entry.getStrValue();  
157 - if (stringValue.isPresent()) {  
158 - json.addProperty(name, stringValue.get());  
159 - } 171 + entry.getStrValue().ifPresent(aString -> json.addProperty(name, aString));
160 break; 172 break;
161 case DOUBLE: 173 case DOUBLE:
162 - Optional<Double> doubleValue = entry.getDoubleValue();  
163 - if (doubleValue.isPresent()) {  
164 - json.addProperty(name, doubleValue.get());  
165 - } 174 + entry.getDoubleValue().ifPresent(aDouble -> json.addProperty(name, aDouble));
166 break; 175 break;
167 case LONG: 176 case LONG:
168 - Optional<Long> longValue = entry.getLongValue();  
169 - if (longValue.isPresent()) {  
170 - json.addProperty(name, longValue.get());  
171 - } 177 + entry.getLongValue().ifPresent(aLong -> json.addProperty(name, aLong));
172 break; 178 break;
173 } 179 }
174 } 180 }
@@ -41,10 +41,7 @@ import org.thingsboard.server.dao.relation.RelationService; @@ -41,10 +41,7 @@ import org.thingsboard.server.dao.relation.RelationService;
41 import org.thingsboard.server.transport.mqtt.MqttTransportHandler; 41 import org.thingsboard.server.transport.mqtt.MqttTransportHandler;
42 import org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor; 42 import org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor;
43 43
44 -import java.util.Collections;  
45 -import java.util.HashMap;  
46 -import java.util.Map;  
47 -import java.util.Optional; 44 +import java.util.*;
48 import java.util.stream.Collectors; 45 import java.util.stream.Collectors;
49 46
50 import static org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor.validateJsonPayload; 47 import static org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor.validateJsonPayload;
@@ -193,13 +190,22 @@ public class GatewaySessionCtx { @@ -193,13 +190,22 @@ public class GatewaySessionCtx {
193 int requestId = jsonObj.get("id").getAsInt(); 190 int requestId = jsonObj.get("id").getAsInt();
194 String deviceName = jsonObj.get(DEVICE_PROPERTY).getAsString(); 191 String deviceName = jsonObj.get(DEVICE_PROPERTY).getAsString();
195 boolean clientScope = jsonObj.get("client").getAsBoolean(); 192 boolean clientScope = jsonObj.get("client").getAsBoolean();
196 - String key = jsonObj.get("key").getAsString(); 193 + Set<String> keys;
  194 + if (jsonObj.has("key")) {
  195 + keys = Collections.singleton(jsonObj.get("key").getAsString());
  196 + } else {
  197 + JsonArray keysArray = jsonObj.get("keys").getAsJsonArray();
  198 + keys = new HashSet<>();
  199 + for (JsonElement keyObj : keysArray) {
  200 + keys.add(keyObj.getAsString());
  201 + }
  202 + }
197 203
198 BasicGetAttributesRequest request; 204 BasicGetAttributesRequest request;
199 if (clientScope) { 205 if (clientScope) {
200 - request = new BasicGetAttributesRequest(requestId, Collections.singleton(key), null); 206 + request = new BasicGetAttributesRequest(requestId, keys, null);
201 } else { 207 } else {
202 - request = new BasicGetAttributesRequest(requestId, null, Collections.singleton(key)); 208 + request = new BasicGetAttributesRequest(requestId, null, keys);
203 } 209 }
204 GatewayDeviceSessionCtx deviceSessionCtx = devices.get(deviceName); 210 GatewayDeviceSessionCtx deviceSessionCtx = devices.get(deviceName);
205 processor.process(new BasicToDeviceActorSessionMsg(deviceSessionCtx.getDevice(), 211 processor.process(new BasicToDeviceActorSessionMsg(deviceSessionCtx.getDevice(),
@@ -251,7 +257,7 @@ public class GatewaySessionCtx { @@ -251,7 +257,7 @@ public class GatewaySessionCtx {
251 } 257 }
252 258
253 private void ack(MqttPublishMessage msg) { 259 private void ack(MqttPublishMessage msg) {
254 - if(msg.variableHeader().messageId() > 0) { 260 + if (msg.variableHeader().messageId() > 0) {
255 writeAndFlush(MqttTransportHandler.createMqttPubAckMsg(msg.variableHeader().messageId())); 261 writeAndFlush(MqttTransportHandler.createMqttPubAckMsg(msg.variableHeader().messageId()));
256 } 262 }
257 } 263 }