Browse Source

refactor(attributes): restrict gateway/device clientKeys & sharedKeys to CSV

The unified request mirrors the device MQTT API's comma-separated
clientKeys/sharedKeys format (with empty value = all in scope). Drop the
extra JSON-array input branch from parseAttributeScope so the accepted
format stays exactly the long-standing device contract; remove the two
array-specific unit tests accordingly.
pull/15865/head
dshvaika 3 months ago
parent
commit
8056989614
  1. 27
      common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java
  2. 22
      common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptorTest.java

27
common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java

@ -37,7 +37,6 @@ import org.thingsboard.server.transport.mqtt.session.MqttDeviceAwareSessionConte
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@ -244,11 +243,12 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor {
}
/**
* Three-state per-scope attribute selection shared by the device and gateway JSON request parsers:
* Three-state per-scope attribute selection shared by the device and gateway JSON request parsers,
* matching the comma-separated {@code clientKeys}/{@code sharedKeys} format of the device MQTT API:
* <ul>
* <li>field absent / null =&gt; the scope is excluded (neither names nor "all" is set);</li>
* <li>field present + empty value (empty string or empty array) =&gt; every key in that scope ({@code setAll});</li>
* <li>field present + a comma-separated string or a JSON array of names =&gt; only those keys ({@code setNames}).</li>
* <li>field present + empty (or blank) string =&gt; every key in that scope ({@code setAll});</li>
* <li>field present + a comma-separated string of names =&gt; only those keys ({@code setNames}).</li>
* </ul>
*/
public static void parseAttributeScope(JsonObject json, String field,
@ -256,24 +256,11 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor {
if (!json.has(field) || json.get(field).isJsonNull()) {
return;
}
JsonElement element = json.get(field);
List<String> names = new ArrayList<>();
if (element.isJsonArray()) {
for (JsonElement e : element.getAsJsonArray()) {
names.add(e.getAsString());
}
} else {
String value = element.getAsString();
if (value.trim().isEmpty()) {
setAll.run();
return;
}
names.addAll(Arrays.asList(value.split(",")));
}
if (names.isEmpty()) {
String value = json.get(field).getAsString();
if (value.trim().isEmpty()) {
setAll.run();
} else {
setNames.accept(names);
setNames.accept(Arrays.asList(value.split(",")));
}
}

22
common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptorTest.java

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.transport.mqtt.adaptors;
import com.google.gson.JsonArray;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import org.junit.jupiter.api.Test;
@ -71,15 +70,6 @@ public class JsonMqttAdaptorTest {
assertTrue(names.isEmpty());
}
@Test
public void emptyArray_setsAll() {
JsonObject json = new JsonObject();
json.add("clientKeys", new JsonArray());
parseClientKeys(json);
assertTrue(allInvoked.get());
assertTrue(names.isEmpty());
}
@Test
public void commaSeparatedString_setsNames() {
JsonObject json = new JsonObject();
@ -88,16 +78,4 @@ public class JsonMqttAdaptorTest {
assertFalse(allInvoked.get());
assertEquals(List.of("a", "b", "c"), names);
}
@Test
public void jsonArray_setsNames() {
JsonObject json = new JsonObject();
JsonArray arr = new JsonArray();
arr.add("a");
arr.add("b");
json.add("clientKeys", arr);
parseClientKeys(json);
assertFalse(allInvoked.get());
assertEquals(List.of("a", "b"), names);
}
}

Loading…
Cancel
Save