diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index e1180a651a..724cf2e3d0 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -57,9 +57,7 @@ import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilde import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.context.WebApplicationContext; -import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.MailService; -import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileType; @@ -93,7 +91,6 @@ import org.thingsboard.server.config.ThingsboardSecurityConfiguration; import org.thingsboard.server.dao.Dao; import org.thingsboard.server.dao.tenant.TenantProfileService; import org.thingsboard.server.dao.timeseries.TimeseriesService; -import org.thingsboard.server.service.mail.TestMailService; import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRequest; import org.thingsboard.server.service.security.auth.rest.LoginRequest; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/AbstractMqttV5ClientSparkplugTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/AbstractMqttV5ClientSparkplugTest.java index 99caf85cf7..28b0830b39 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/AbstractMqttV5ClientSparkplugTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/AbstractMqttV5ClientSparkplugTest.java @@ -67,6 +67,7 @@ import static org.thingsboard.server.transport.mqtt.util.sparkplug.MetricDataTyp import static org.thingsboard.server.transport.mqtt.util.sparkplug.MetricDataType.UInt64; import static org.thingsboard.server.transport.mqtt.util.sparkplug.MetricDataType.UInt8; import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugMetricUtil.createMetric; +import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugTopicUtil.NAMESPACE; /** * Created by nickAS21 on 12.01.23 @@ -79,7 +80,6 @@ public abstract class AbstractMqttV5ClientSparkplugTest extends AbstractMqttInte protected Calendar calendar = Calendar.getInstance(); protected ThreadLocalRandom random = ThreadLocalRandom.current(); - protected static final String NAMESPACE = "spBv1.0"; protected static final String groupId = "SparkplugBGroupId"; protected static final String edgeNode = "SparkpluBNode"; protected static final String keysBdSeq = "bdSeq"; @@ -114,6 +114,14 @@ public abstract class AbstractMqttV5ClientSparkplugTest extends AbstractMqttInte } public void clientWithCorrectNodeAccessTokenWithNDEATH(long ts, long value) throws Exception { + IMqttToken connectionResult = clientConnectWithNDEATH(ts, value); + MqttWireMessage response = connectionResult.getResponse(); + Assert.assertEquals(MESSAGE_TYPE_CONNACK, response.getType()); + MqttConnAck connAckMsg = (MqttConnAck) response; + Assert.assertEquals(MqttReturnCode.RETURN_CODE_SUCCESS, connAckMsg.getReturnCode()); + } + + public IMqttToken clientConnectWithNDEATH(long ts, long value, String... nameSpaceBad) throws Exception { String key = keysBdSeq; MetricDataType metricDataType = Int64; SparkplugBProto.Payload.Builder deathPayload = SparkplugBProto.Payload.newBuilder() @@ -125,18 +133,15 @@ public abstract class AbstractMqttV5ClientSparkplugTest extends AbstractMqttInte this.client.setCallback(this.mqttCallback); MqttConnectionOptions options = new MqttConnectionOptions(); options.setUserName(gatewayAccessToken); - String topic = NAMESPACE + "/" + groupId + "/" + SparkplugMessageType.NDEATH.name() + "/" + edgeNode; + String nameSpace = nameSpaceBad.length == 0 ? NAMESPACE : nameSpaceBad[0]; + String topic = nameSpace + "/" + groupId + "/" + SparkplugMessageType.NDEATH.name() + "/" + edgeNode; MqttMessage msg = new MqttMessage(); msg.setId(0); msg.setPayload(deathBytes); options.setWill(topic, msg); - IMqttToken connectionResult = client.connect(options); - - MqttWireMessage response = connectionResult.getResponse(); - Assert.assertEquals(MESSAGE_TYPE_CONNACK, response.getType()); - MqttConnAck connAckMsg = (MqttConnAck) response; - Assert.assertEquals(MqttReturnCode.RETURN_CODE_SUCCESS, connAckMsg.getReturnCode()); + return client.connect(options); } + protected List connectClientWithCorrectAccessTokenWithNDEATHCreatedDevices(int cntDevices, long ts) throws Exception { List devices = new ArrayList<>(); clientWithCorrectNodeAccessTokenWithNDEATH(); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/attributes/AbstractMqttV5ClientSparkplugAttributesTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/attributes/AbstractMqttV5ClientSparkplugAttributesTest.java index 9ebf28429c..6f0181cbf1 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/attributes/AbstractMqttV5ClientSparkplugAttributesTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/attributes/AbstractMqttV5ClientSparkplugAttributesTest.java @@ -33,6 +33,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.thingsboard.server.common.data.DataConstants.CLIENT_SCOPE; import static org.thingsboard.server.transport.mqtt.util.sparkplug.MetricDataType.UInt32; import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugMessageType.NCMD; +import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugTopicUtil.NAMESPACE; /** * Created by nickAS21 on 12.01.23 diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/connection/AbstractMqttV5ClientSparkplugConnectionTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/connection/AbstractMqttV5ClientSparkplugConnectionTest.java index 19cc0d14c7..5f9b794739 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/connection/AbstractMqttV5ClientSparkplugConnectionTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/connection/AbstractMqttV5ClientSparkplugConnectionTest.java @@ -40,6 +40,7 @@ import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugConn import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugConnectionState.ONLINE; import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugMessageType.STATE; import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugMessageType.messageName; +import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugTopicUtil.NAMESPACE; /** * Created by nickAS21 on 12.01.23 @@ -74,6 +75,16 @@ public abstract class AbstractMqttV5ClientSparkplugConnectionTest extends Abstra Assert.assertEquals(expectedReasonCode, actualException.getReasonCode()); } + protected void processClientWithCorrectNodeAccessTokenNameSpaceInvalid_Test() throws Exception { + long ts = calendar.getTimeInMillis() - PUBLISH_TS_DELTA_MS; + long value = bdSeq = 0; + MqttException actualException = Assert.assertThrows(MqttException.class, () -> clientConnectWithNDEATH(ts, value, "spBv1.2")); + String expectedMessage = "Server unavailable."; + int expectedReasonCode = 136; + Assert.assertEquals(expectedMessage, actualException.getMessage()); + Assert.assertEquals(expectedReasonCode, actualException.getReasonCode()); + } + protected void processClientWithCorrectAccessTokenWithNDEATHCreatedDevices(int cntDevices) throws Exception { long ts = calendar.getTimeInMillis(); connectClientWithCorrectAccessTokenWithNDEATHCreatedDevices(cntDevices, ts); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/connection/MqttV5ClientSparkplugBConnectionTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/connection/MqttV5ClientSparkplugBConnectionTest.java index c4277b1f10..71c9391a29 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/connection/MqttV5ClientSparkplugBConnectionTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/connection/MqttV5ClientSparkplugBConnectionTest.java @@ -49,6 +49,10 @@ public class MqttV5ClientSparkplugBConnectionTest extends AbstractMqttV5ClientSp processClientWithCorrectNodeAccessTokenWithoutNDEATH_Test(); } + @Test + public void testClientWithCorrectNodeAccessTokenNameSpaceInvalid() throws Exception { + processClientWithCorrectNodeAccessTokenNameSpaceInvalid_Test(); + } @Test public void testClientWithCorrectAccessTokenWithNDEATHCreatedOneDevice() throws Exception { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/rpc/AbstractMqttV5RpcSparkplugTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/rpc/AbstractMqttV5RpcSparkplugTest.java index 439d7a6ed7..b08baac875 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/rpc/AbstractMqttV5RpcSparkplugTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/rpc/AbstractMqttV5RpcSparkplugTest.java @@ -31,6 +31,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.thingsboard.server.common.data.exception.ThingsboardErrorCode.INVALID_ARGUMENTS; import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugMessageType.DCMD; import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugMessageType.NCMD; +import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugTopicUtil.NAMESPACE; @Slf4j public abstract class AbstractMqttV5RpcSparkplugTest extends AbstractMqttV5ClientSparkplugTest { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/timeseries/AbstractMqttV5ClientSparkplugTelemetryTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/timeseries/AbstractMqttV5ClientSparkplugTelemetryTest.java index 23ee41e394..587494f869 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/timeseries/AbstractMqttV5ClientSparkplugTelemetryTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/sparkplug/timeseries/AbstractMqttV5ClientSparkplugTelemetryTest.java @@ -29,6 +29,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import static org.awaitility.Awaitility.await; +import static org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugTopicUtil.NAMESPACE; /** * Created by nickAS21 on 12.01.23 diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/MetricDataType.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/MetricDataType.java index d4a6ad183a..d5e781a402 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/MetricDataType.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/MetricDataType.java @@ -146,8 +146,6 @@ public enum MetricDataType { } /** - * Returns the class type for this DataType - * * @return the class type for this DataType */ public Class getClazz() { diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/SparkplugTopic.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/SparkplugTopic.java index 9feea997e5..be721f11bb 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/SparkplugTopic.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/SparkplugTopic.java @@ -25,10 +25,7 @@ public class SparkplugTopic { /** * The Sparkplug namespace version. - * For the Sparkplug™ A version of the payload definition, the UTF-8 string constant for the namespace element will be: - * “spAv1.0” - * For the Sparkplug™ B version of the specification, the UTF-8 string constant for the namespace element will be: - * “spBv1.0” + * For the Sparkplug™ B version of the specification, the UTF-8 string constant for the namespace element will be: “spBv1.0” */ private String namespace; @@ -105,9 +102,7 @@ public class SparkplugTopic { } /** - * Returns the Sparkplug namespace version. - * - * @return the namespace + * @return the Sparkplug namespace version */ public String getNamespace() { return namespace; @@ -123,17 +118,13 @@ public class SparkplugTopic { } /** - * Returns the ID of the Edge of Network (EoN) Node. - * - * @return the edge node ID + * @return the ID of the Edge of Network (EoN) Node */ public String getEdgeNodeId() { return edgeNodeId; } /** - * Returns the ID of the device. - * * @return the device ID */ public String getDeviceId() { @@ -141,8 +132,6 @@ public class SparkplugTopic { } /** - * Returns the message type. - * * @return the message type */ public SparkplugMessageType getType() { @@ -162,8 +151,6 @@ public class SparkplugTopic { } /** - * Returns true if this topic's type matches the passes in type, false otherwise. - * * @param type the type to check * @return true if this topic's type matches the passes in type, false otherwise */ diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/SparkplugTopicUtil.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/SparkplugTopicUtil.java index 46c2ce5741..b727db7a08 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/SparkplugTopicUtil.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/SparkplugTopicUtil.java @@ -30,6 +30,7 @@ public class SparkplugTopicUtil { private static final Map SPLIT_TOPIC_CACHE = new HashMap(); private static final String TOPIC_INVALID_NUMBER = "Invalid number of topic elements: "; + public static final String NAMESPACE = "spBv1.0"; public static String[] getSplitTopic(String topic) { String[] splitTopic = SPLIT_TOPIC_CACHE.get(topic); @@ -93,7 +94,7 @@ public class SparkplugTopicUtil { } else { SparkplugMessageType type; String namespace, edgeNodeId, groupId, deviceId; - namespace = splitTopic[0]; + namespace = validateNameSpace(splitTopic[0]); groupId = length > 1 ? splitTopic[1] : null; type = length > 2 ? SparkplugMessageType.parseMessageType(splitTopic[2]) : null; edgeNodeId = length > 3 ? splitTopic[3] : null; @@ -102,4 +103,14 @@ public class SparkplugTopicUtil { } } + /** + * For the Sparkplug™ B version of the specification, the UTF-8 string constant for the namespace element will be: "spBv1.0" + * @param nameSpace + * @return + */ + private static String validateNameSpace(String nameSpace) throws ThingsboardException { + if ("spBv1.0".equals(nameSpace)) return nameSpace; + throw new ThingsboardException("The namespace [" + nameSpace + "] is not valid and must be [spBv1.0] for the Sparkplug™ B version.", ThingsboardErrorCode.INVALID_ARGUMENTS); + } + }