9 changed files with 573 additions and 1 deletions
@ -0,0 +1,264 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.transport.mqtt.sparkplug; |
|||
|
|||
import com.google.common.util.concurrent.ListenableFuture; |
|||
import com.google.protobuf.ByteString; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.eclipse.paho.client.mqttv3.MqttClient; |
|||
import org.eclipse.paho.mqttv5.client.IMqttToken; |
|||
import org.eclipse.paho.mqttv5.client.MqttConnectionOptions; |
|||
import org.eclipse.paho.mqttv5.common.MqttMessage; |
|||
import org.eclipse.paho.mqttv5.common.packet.MqttConnAck; |
|||
import org.eclipse.paho.mqttv5.common.packet.MqttReturnCode; |
|||
import org.eclipse.paho.mqttv5.common.packet.MqttWireMessage; |
|||
import org.junit.Assert; |
|||
import org.thingsboard.server.common.data.TransportPayloadType; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|||
import org.thingsboard.server.common.data.kv.BasicTsKvEntry; |
|||
import org.thingsboard.server.common.data.kv.LongDataEntry; |
|||
import org.thingsboard.server.common.data.kv.TsKvEntry; |
|||
import org.thingsboard.server.gen.transport.mqtt.SparkplugBProto; |
|||
import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; |
|||
import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; |
|||
import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; |
|||
import org.thingsboard.server.transport.mqtt.util.sparkplug.MetricDataType; |
|||
import org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugMessageType; |
|||
import org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugMetricUtil; |
|||
|
|||
import java.io.ByteArrayOutputStream; |
|||
import java.io.DataOutputStream; |
|||
import java.io.IOException; |
|||
import java.io.ObjectOutputStream; |
|||
import java.nio.ByteBuffer; |
|||
import java.util.Calendar; |
|||
import java.util.Date; |
|||
import java.util.Optional; |
|||
import java.util.concurrent.ExecutorService; |
|||
import java.util.concurrent.TimeUnit; |
|||
import java.util.concurrent.atomic.AtomicReference; |
|||
|
|||
import static org.awaitility.Awaitility.await; |
|||
import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_CONNACK; |
|||
import static org.thingsboard.server.transport.mqtt.util.sparkplug.MetricDataType.Int64; |
|||
|
|||
/** |
|||
* Created by nickAS21 on 12.01.23 |
|||
*/ |
|||
@Slf4j |
|||
public abstract class AbstractMqttV5ClientSparkplugTest extends AbstractMqttIntegrationTest { |
|||
|
|||
protected MqttV5TestClient client; |
|||
protected Calendar calendar = Calendar.getInstance(); |
|||
|
|||
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"; |
|||
protected int bdSeq = 0; |
|||
protected int seq = 0; |
|||
protected static final long PUBLISH_TS_DELTA_MS = 86400000;// Publish start TS <-> 24h
|
|||
|
|||
|
|||
public void beforeSparkplugTest() throws Exception { |
|||
MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() |
|||
.gatewayName("Test Connect Sparkplug client node") |
|||
.isSparkPlug(true) |
|||
.transportPayloadType(TransportPayloadType.PROTOBUF) |
|||
.build(); |
|||
processBeforeTest(configProperties); |
|||
} |
|||
|
|||
public void processClientWithCorrectNodeAccess () throws Exception { |
|||
this.client = new MqttV5TestClient(); |
|||
MqttWireMessage response = clientWithCorrectNodeAccessToken(client); |
|||
Assert.assertEquals(MESSAGE_TYPE_CONNACK, response.getType()); |
|||
MqttConnAck connAckMsg = (MqttConnAck) response; |
|||
Assert.assertEquals(MqttReturnCode.RETURN_CODE_SUCCESS, connAckMsg.getReturnCode()); |
|||
} |
|||
|
|||
protected SparkplugBProto.Payload.Metric createMetric(TsKvEntry tsKvEntry, MetricDataType metricDataType) throws ThingsboardException { |
|||
SparkplugBProto.Payload.Metric metric = SparkplugBProto.Payload.Metric.newBuilder() |
|||
.setTimestamp(tsKvEntry.getTs()) |
|||
.setName(tsKvEntry.getKey()) |
|||
.setDatatype(metricDataType.toIntValue()) |
|||
.build(); |
|||
Object value = tsKvEntry.getValue(); |
|||
switch (metricDataType) { |
|||
case Int8: |
|||
case Int16: |
|||
case Int32: |
|||
case UInt8: |
|||
case UInt16: |
|||
case UInt32: |
|||
return metric.toBuilder().setIntValue(Integer.parseInt(String.valueOf(value))).build(); |
|||
case Int64: |
|||
case UInt64: |
|||
case DateTime: |
|||
return metric.toBuilder().setLongValue(Long.parseLong(String.valueOf(value))).build(); |
|||
case Float: |
|||
return metric.toBuilder().setFloatValue(Float.parseFloat(String.valueOf(value))).build(); |
|||
case Double: |
|||
return metric.toBuilder().setDoubleValue(Double.parseDouble(String.valueOf(value))).build(); |
|||
case Boolean: |
|||
return metric.toBuilder().setBooleanValue(Boolean.parseBoolean(String.valueOf(value))).build(); |
|||
case String: |
|||
case Text: |
|||
case UUID: |
|||
return metric.toBuilder().setDatasetValue((SparkplugBProto.Payload.DataSet) value).build(); |
|||
case DataSet: |
|||
return metric.toBuilder().setStringValue(String.valueOf(value)).build(); |
|||
case Bytes: |
|||
case Int8Array: |
|||
ByteString byteString = ByteString.copyFrom((byte[]) value); |
|||
return metric.toBuilder().setBytesValue(byteString).build(); |
|||
case Int16Array: |
|||
case UInt8Array: |
|||
byte[] int16Array = shortToByte_ByteBuffer_Method((short[]) value); |
|||
ByteString byteInt16Array = ByteString.copyFrom((int16Array)); |
|||
return metric.toBuilder().setBytesValue(byteInt16Array).build(); |
|||
case Int32Array: |
|||
case UInt16Array: |
|||
byte[] int32Array = integerToByte_ByteBuffer_Method((int[]) value); |
|||
ByteString byteInt32Array = ByteString.copyFrom((int32Array)); |
|||
return metric.toBuilder().setBytesValue(byteInt32Array).build(); |
|||
case Int64Array: |
|||
case UInt32Array: |
|||
byte[] int64Array = longToByte_ByteBuffer_Method((long[]) value); |
|||
ByteString byteInt64Array = ByteString.copyFrom((int64Array)); |
|||
return metric.toBuilder().setBytesValue(byteInt64Array).build(); |
|||
case UInt64Array: |
|||
case DoubleArray: |
|||
byte[] doubleArray = doubleToByte_ByteBuffer_Method((double[]) value); |
|||
ByteString byteDoubleArray = ByteString.copyFrom(doubleArray); |
|||
return metric.toBuilder().setBytesValue(byteDoubleArray).build(); |
|||
case FloatArray: |
|||
byte[] floatArray = floatToByte_ByteBuffer_Method((float[]) value); |
|||
ByteString byteFloatArray = ByteString.copyFrom(floatArray); |
|||
return metric.toBuilder().setBytesValue(byteFloatArray).build(); |
|||
case BooleanArray: |
|||
byte[] booleanArray = booleanToByte_ByteBuffer_Method((boolean[]) value); |
|||
ByteString byteBooleanArray = ByteString.copyFrom(booleanArray); |
|||
return metric.toBuilder().setBytesValue(byteBooleanArray).build(); |
|||
case StringArray: |
|||
byte[] stringArray = stringToByte_ByteBuffer_Method((String[]) value); |
|||
ByteString byteStringArray = ByteString.copyFrom(stringArray); |
|||
return metric.toBuilder().setBytesValue(byteStringArray).build(); |
|||
case DateTimeArray: |
|||
byte[] dateArray = dateToByte_ByteBuffer_Method((Date[]) value); |
|||
ByteString byteDateArray = ByteString.copyFrom(dateArray); |
|||
return metric.toBuilder().setBytesValue(byteDateArray).build(); |
|||
case File: |
|||
SparkplugMetricUtil.File file = (SparkplugMetricUtil.File) value; |
|||
ByteString byteFileString = ByteString.copyFrom(file.getBytes()); |
|||
return metric.toBuilder().setBytesValue(byteFileString).build(); |
|||
case Template: |
|||
return metric.toBuilder().setTemplateValue((SparkplugBProto.Payload.Template) value).build(); |
|||
case Unknown: |
|||
throw new ThingsboardException("Invalid value for MetricDataType " + metricDataType.name(), ThingsboardErrorCode.INVALID_ARGUMENTS); |
|||
} |
|||
return metric; |
|||
} |
|||
|
|||
private byte[] shortToByte_ByteBuffer_Method(short[] inputs) { |
|||
ByteBuffer bb = ByteBuffer.allocate(inputs.length * 2); |
|||
for (short d : inputs) { |
|||
bb.putShort(d); |
|||
} |
|||
return bb.array(); |
|||
} |
|||
|
|||
private byte[] integerToByte_ByteBuffer_Method(int[] inputs) { |
|||
ByteBuffer bb = ByteBuffer.allocate(inputs.length * 4); |
|||
for (int d : inputs) { |
|||
bb.putLong(d); |
|||
} |
|||
return bb.array(); |
|||
} |
|||
|
|||
private byte[] longToByte_ByteBuffer_Method(long[] inputs) { |
|||
ByteBuffer bb = ByteBuffer.allocate(inputs.length * 8); |
|||
for (long d : inputs) { |
|||
bb.putLong(d); |
|||
} |
|||
return bb.array(); |
|||
} |
|||
|
|||
private byte[] doubleToByte_ByteBuffer_Method(double[] inputs) { |
|||
ByteBuffer bb = ByteBuffer.allocate(inputs.length * 8); |
|||
for (double d : inputs) { |
|||
bb.putDouble(d); |
|||
} |
|||
return bb.array(); |
|||
} |
|||
|
|||
private byte[] floatToByte_ByteBuffer_Method(float[] inputs) throws ThingsboardException { |
|||
ByteArrayOutputStream bas = new ByteArrayOutputStream(); |
|||
DataOutputStream ds = new DataOutputStream(bas); |
|||
for (float f : inputs) { |
|||
try { |
|||
ds.writeFloat(f); |
|||
} catch (IOException e) { |
|||
throw new ThingsboardException("Invalid value float ", ThingsboardErrorCode.INVALID_ARGUMENTS); |
|||
} |
|||
} |
|||
return bas.toByteArray(); |
|||
} |
|||
|
|||
private byte[] booleanToByte_ByteBuffer_Method(boolean[] inputs) { |
|||
byte[] toReturn = new byte[inputs.length / 8]; |
|||
for (int entry = 0; entry < toReturn.length; entry++) { |
|||
for (int bit = 0; bit < 8; bit++) { |
|||
if (inputs[entry * 8 + bit]) { |
|||
toReturn[entry] |= (128 >> bit); |
|||
} |
|||
} |
|||
} |
|||
return toReturn; |
|||
} |
|||
|
|||
private byte[] stringToByte_ByteBuffer_Method(String[] inputs) throws ThingsboardException { |
|||
final ByteArrayOutputStream bas = new ByteArrayOutputStream(); |
|||
try { |
|||
final ObjectOutputStream os = new ObjectOutputStream(bas); |
|||
os.writeObject(inputs); |
|||
os.flush(); |
|||
os.close(); |
|||
} catch (Exception e) { |
|||
throw new ThingsboardException("Invalid value float ", ThingsboardErrorCode.INVALID_ARGUMENTS); |
|||
} |
|||
return bas.toByteArray(); |
|||
} |
|||
|
|||
private byte[] dateToByte_ByteBuffer_Method(Date[] inputs) { |
|||
long[] ll = new long[inputs.length]; |
|||
int i = 0; |
|||
for (Date date : inputs) { |
|||
ll[i] = date.getTime(); |
|||
i++; |
|||
} |
|||
return longToByte_ByteBuffer_Method(ll); |
|||
} |
|||
|
|||
|
|||
|
|||
private MqttWireMessage clientWithCorrectNodeAccessToken(MqttV5TestClient client) throws Exception { |
|||
IMqttToken connectionResult = client.connectAndWait(gatewayAccessToken); |
|||
return connectionResult.getResponse(); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,125 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.transport.mqtt.sparkplug.connection; |
|||
|
|||
import com.google.common.util.concurrent.ListenableFuture; |
|||
import com.google.protobuf.ByteString; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.eclipse.paho.client.mqttv3.MqttClient; |
|||
import org.eclipse.paho.mqttv5.client.IMqttToken; |
|||
import org.eclipse.paho.mqttv5.client.MqttConnectionOptions; |
|||
import org.eclipse.paho.mqttv5.common.MqttMessage; |
|||
import org.eclipse.paho.mqttv5.common.packet.MqttConnAck; |
|||
import org.eclipse.paho.mqttv5.common.packet.MqttReturnCode; |
|||
import org.eclipse.paho.mqttv5.common.packet.MqttWireMessage; |
|||
import org.junit.Assert; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|||
import org.thingsboard.server.common.data.kv.BasicTsKvEntry; |
|||
import org.thingsboard.server.common.data.kv.LongDataEntry; |
|||
import org.thingsboard.server.common.data.kv.TsKvEntry; |
|||
import org.thingsboard.server.gen.transport.mqtt.SparkplugBProto; |
|||
import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; |
|||
import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; |
|||
import org.thingsboard.server.transport.mqtt.sparkplug.AbstractMqttV5ClientSparkplugTest; |
|||
import org.thingsboard.server.transport.mqtt.util.sparkplug.MetricDataType; |
|||
import org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugMessageType; |
|||
import org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugMetricUtil; |
|||
|
|||
import java.io.ByteArrayOutputStream; |
|||
import java.io.DataOutputStream; |
|||
import java.io.IOException; |
|||
import java.io.ObjectOutputStream; |
|||
import java.nio.ByteBuffer; |
|||
import java.util.Calendar; |
|||
import java.util.Date; |
|||
import java.util.Optional; |
|||
import java.util.concurrent.ExecutorService; |
|||
import java.util.concurrent.TimeUnit; |
|||
import java.util.concurrent.atomic.AtomicReference; |
|||
|
|||
import static org.awaitility.Awaitility.await; |
|||
import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_CONNACK; |
|||
import static org.thingsboard.server.transport.mqtt.util.sparkplug.MetricDataType.Int64; |
|||
|
|||
/** |
|||
* Created by nickAS21 on 12.01.23 |
|||
*/ |
|||
@Slf4j |
|||
public abstract class AbstractMqttV5ClientSparkplugConnectionTest extends AbstractMqttV5ClientSparkplugTest { |
|||
|
|||
protected void processClientWithCorrectNodeAccessTokenTest() throws Exception { |
|||
processClientWithCorrectNodeAccess(); |
|||
} |
|||
|
|||
protected void processClientWithCorrectNodeAccessTokenWithNdeathTest() throws Exception { |
|||
long ts = calendar.getTimeInMillis()-PUBLISH_TS_DELTA_MS; |
|||
int value = bdSeq; |
|||
MetricDataType metricDataType = Int64; |
|||
TsKvEntry expectedTsKvEntryOriginal = new BasicTsKvEntry(ts, new LongDataEntry(keysBdSeq, Integer.toUnsignedLong(value))); |
|||
|
|||
SparkplugBProto.Payload.Builder deathPayload = SparkplugBProto.Payload.newBuilder() |
|||
.setTimestamp(calendar.getTimeInMillis()); |
|||
deathPayload.addMetrics(createMetric(expectedTsKvEntryOriginal, metricDataType)); |
|||
|
|||
byte[] deathBytes = deathPayload.build().toByteArray(); |
|||
|
|||
MqttWireMessage response = clientWithCorrectNodeAccessTokenWithNdeath(deathBytes); |
|||
|
|||
Assert.assertEquals(MESSAGE_TYPE_CONNACK, response.getType()); |
|||
|
|||
MqttConnAck connAckMsg = (MqttConnAck) response; |
|||
|
|||
Assert.assertEquals(MqttReturnCode.RETURN_CODE_SUCCESS, connAckMsg.getReturnCode()); |
|||
|
|||
String keys = SparkplugMessageType.NDEATH.name() + " " + keysBdSeq; |
|||
TsKvEntry expectedTsKvEntry = new BasicTsKvEntry(ts, new LongDataEntry(keys, Integer.toUnsignedLong(value))); |
|||
ListenableFuture<Optional<TsKvEntry>> future = tsService.findLatest(tenantId, savedGateway.getId(), keys); |
|||
AtomicReference<ListenableFuture<Optional<TsKvEntry>>> finalFuture = new AtomicReference<>(future); |
|||
await("Failed Post Telemetry node proto payload. SparkplugMessageType NDEATH") |
|||
.atMost(40, TimeUnit.SECONDS) |
|||
.until(() -> { |
|||
finalFuture.set(tsService.findLatest(tenantId, savedGateway.getId(), keys)); |
|||
return finalFuture.get().get().isPresent(); |
|||
}); |
|||
TsKvEntry actualTsKvEntry = finalFuture.get().get().get(); |
|||
Assert.assertEquals(expectedTsKvEntry, actualTsKvEntry); |
|||
client.disconnect(); |
|||
} |
|||
|
|||
protected void processClientWithCorrectAccessTokenCreatedDevices(int cntDevices) throws Exception { |
|||
processClientWithCorrectNodeAccess(); |
|||
|
|||
|
|||
|
|||
} |
|||
|
|||
private MqttWireMessage clientWithCorrectNodeAccessTokenWithNdeath(byte[] deathBytes) throws Exception { |
|||
this.client = new MqttV5TestClient(); |
|||
MqttConnectionOptions options = new MqttConnectionOptions(); |
|||
options.setUserName(gatewayAccessToken); |
|||
if (deathBytes != null) { |
|||
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); |
|||
return connectionResult.getResponse(); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.transport.mqtt.sparkplug.connection; |
|||
|
|||
import org.eclipse.paho.mqttv5.common.MqttException; |
|||
import org.junit.After; |
|||
import org.junit.Before; |
|||
import org.junit.Test; |
|||
import org.thingsboard.server.dao.service.DaoSqlTest; |
|||
|
|||
/** |
|||
* Created by nickAS21 on 12.01.23 |
|||
*/ |
|||
@DaoSqlTest |
|||
public class MqttV5ClientSparkplugBConnectionTest extends AbstractMqttV5ClientSparkplugConnectionTest { |
|||
|
|||
@Before |
|||
public void beforeTest() throws Exception { |
|||
beforeSparkplugTest(); |
|||
} |
|||
|
|||
@After |
|||
public void afterTest() throws MqttException { |
|||
if (client.isConnected()) { |
|||
client.disconnect(); |
|||
} |
|||
} |
|||
|
|||
@Test |
|||
public void testClientWithCorrectAccessToken() throws Exception { |
|||
processClientWithCorrectNodeAccessTokenTest(); |
|||
} |
|||
|
|||
@Test |
|||
public void testClientWithCorrectAccessTokenWithNDEATH() throws Exception { |
|||
processClientWithCorrectNodeAccessTokenWithNdeathTest(); |
|||
} |
|||
|
|||
@Test |
|||
public void testClientWithCorrectAccessTokenCreatedOneDevice() throws Exception { |
|||
processClientWithCorrectAccessTokenCreatedDevices(1); |
|||
} |
|||
|
|||
@Test |
|||
public void testClientWithCorrectAccessTokenCreatedTwoDevice() throws Exception { |
|||
processClientWithCorrectAccessTokenCreatedDevices(2); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.transport.mqtt.sparkplug.timeseries; |
|||
|
|||
import com.google.common.util.concurrent.ListenableFuture; |
|||
import com.google.protobuf.ByteString; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.eclipse.paho.mqttv5.client.IMqttToken; |
|||
import org.eclipse.paho.mqttv5.client.MqttConnectionOptions; |
|||
import org.eclipse.paho.mqttv5.common.MqttMessage; |
|||
import org.eclipse.paho.mqttv5.common.packet.MqttConnAck; |
|||
import org.eclipse.paho.mqttv5.common.packet.MqttReturnCode; |
|||
import org.eclipse.paho.mqttv5.common.packet.MqttWireMessage; |
|||
import org.junit.Assert; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|||
import org.thingsboard.server.common.data.kv.BasicTsKvEntry; |
|||
import org.thingsboard.server.common.data.kv.LongDataEntry; |
|||
import org.thingsboard.server.common.data.kv.TsKvEntry; |
|||
import org.thingsboard.server.gen.transport.mqtt.SparkplugBProto; |
|||
import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; |
|||
import org.thingsboard.server.transport.mqtt.sparkplug.AbstractMqttV5ClientSparkplugTest; |
|||
import org.thingsboard.server.transport.mqtt.util.sparkplug.MetricDataType; |
|||
import org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugMessageType; |
|||
import org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugMetricUtil; |
|||
|
|||
import java.io.ByteArrayOutputStream; |
|||
import java.io.DataOutputStream; |
|||
import java.io.IOException; |
|||
import java.io.ObjectOutputStream; |
|||
import java.nio.ByteBuffer; |
|||
import java.util.Date; |
|||
import java.util.Optional; |
|||
import java.util.concurrent.TimeUnit; |
|||
import java.util.concurrent.atomic.AtomicReference; |
|||
|
|||
import static org.awaitility.Awaitility.await; |
|||
import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_CONNACK; |
|||
import static org.thingsboard.server.transport.mqtt.util.sparkplug.MetricDataType.Int64; |
|||
|
|||
/** |
|||
* Created by nickAS21 on 12.01.23 |
|||
*/ |
|||
@Slf4j |
|||
public abstract class AbstractMqttV5ClientSparkplugTelemetryTest extends AbstractMqttV5ClientSparkplugTest { |
|||
|
|||
protected void processPushTelemetry() throws Exception { |
|||
processClientWithCorrectNodeAccess(); |
|||
|
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.transport.mqtt.sparkplug.timeseries; |
|||
|
|||
import org.eclipse.paho.mqttv5.common.MqttException; |
|||
import org.junit.After; |
|||
import org.junit.Before; |
|||
import org.junit.Test; |
|||
import org.thingsboard.server.dao.service.DaoSqlTest; |
|||
import org.thingsboard.server.transport.mqtt.sparkplug.connection.AbstractMqttV5ClientSparkplugConnectionTest; |
|||
|
|||
/** |
|||
* Created by nickAS21 on 12.01.23 |
|||
*/ |
|||
@DaoSqlTest |
|||
public class MqttV5ClientSparkplugBTelemetryTest extends AbstractMqttV5ClientSparkplugTelemetryTest { |
|||
|
|||
@Before |
|||
public void beforeTest() throws Exception { |
|||
beforeSparkplugTest(); |
|||
} |
|||
|
|||
@After |
|||
public void afterTest () throws MqttException { |
|||
if (client.isConnected()) { |
|||
client.disconnect(); } |
|||
} |
|||
|
|||
@Test |
|||
public void testPushTelemetry() throws Exception { |
|||
processPushTelemetry(); |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue