lwm2m: add tests
This commit is contained in:
parent
7422ec38e1
commit
e5c6be6e08
@ -129,7 +129,7 @@ public class LwM2mBinaryAppDataContainer extends BaseInstanceEnabler implements
|
||||
fireResourceChange(resourceId);
|
||||
return WriteResponse.success();
|
||||
} else {
|
||||
WriteResponse.badRequest("Invalidate value ...");
|
||||
return WriteResponse.badRequest("Invalidate value ...");
|
||||
}
|
||||
case 1:
|
||||
setPriority((Integer) (value.getValue() instanceof Long ? ((Long) value.getValue()).intValue() : value.getValue()));
|
||||
|
||||
@ -20,6 +20,7 @@ import org.eclipse.leshan.core.ResponseCode;
|
||||
import org.eclipse.leshan.core.node.LwM2mPath;
|
||||
import org.junit.Test;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.script.api.tbel.TbUtils;
|
||||
import org.thingsboard.server.transport.lwm2m.rpc.AbstractRpcLwM2MIntegrationTest;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@ -76,7 +77,157 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
|
||||
String expected = "LwM2mSingleResource [id=" + RESOURCE_ID_14 + ", value=" + expectedValue + ", type=STRING]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteReplaceValueMultipleResource_Result_CHANGED_Multi_Instance_Resource_must_One() throws Exception {
|
||||
int resourceInstanceId0 = 0;
|
||||
String expectedPath = objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0 + "/" + resourceInstanceId0;
|
||||
// base64/String
|
||||
String expectedValue = "QUJDREVGRw";
|
||||
String actualResult = sendRPCWriteStringById("WriteReplace", expectedPath, expectedValue);
|
||||
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
String actualValues = rpcActualResult.get("value").asText();
|
||||
byte[] expectedValue0 = TbUtils.base64ToBytes(expectedValue);
|
||||
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
// base64/String
|
||||
expectedValue = "ABCDEFG";
|
||||
actualResult = sendRPCWriteStringById("WriteReplace", expectedPath, expectedValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expectedValue0 = TbUtils.base64ToBytes(expectedValue);
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
// hexDecimal/String
|
||||
expectedValue = "01ABCDEF";
|
||||
actualResult = sendRPCWriteStringById("WriteReplace", expectedPath, expectedValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue.length()/2 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
// Integer
|
||||
Integer expectedIntegerValue = 1234566;
|
||||
actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedIntegerValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + 4 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
expectedIntegerValue = Integer.MAX_VALUE;
|
||||
actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedIntegerValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + 4 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
expectedIntegerValue = Integer.MIN_VALUE;
|
||||
actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedIntegerValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + 4 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
// Long
|
||||
Long expectedLongValue = 4406483977L;
|
||||
actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedLongValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + 8 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
expectedLongValue = Long.MAX_VALUE;
|
||||
actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedLongValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + 8 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
expectedLongValue = Long.MIN_VALUE;
|
||||
actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedLongValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + 8 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
// Float to byte[]: byte[] bytes = ByteBuffer.allocate(4).putFloat(((Float) value).floatValue()).array();
|
||||
// Float from byte[]: float f = ByteBuffer.wrap(bytes).getFloat();
|
||||
Float expectedFloatValue = 8.02f;
|
||||
actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedFloatValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + 4 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
expectedFloatValue = Float.MAX_VALUE;
|
||||
actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedFloatValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + 4 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
expectedFloatValue = Float.MIN_VALUE;
|
||||
actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedFloatValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + 4 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
// Double to byte[]: byte[] bytes = ByteBuffer.allocate(8).putDouble(((Double) value).doubleValue()).array();
|
||||
// Double from byte[]: double d = ByteBuffer.wrap(bytes).getDouble();
|
||||
Double expectedDoubleValue = 1022.5906d;
|
||||
actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedDoubleValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + 4 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
expectedDoubleValue = Double.MAX_VALUE;
|
||||
actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedDoubleValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + 8 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
expectedDoubleValue = Double.MIN_VALUE;
|
||||
actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedDoubleValue);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
actualResult = sendRPCReadById(expectedPath);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + 8 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
}
|
||||
|
||||
/**
|
||||
* id
|
||||
@ -88,9 +239,9 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
|
||||
String expectedPath = objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0;
|
||||
int resourceInstanceId0 = 0;
|
||||
int resourceInstanceId15 = 15;
|
||||
String expectedValue0 = "0000ad45675600";
|
||||
String expectedValue15 = "1525ad45675600cdef";
|
||||
String expectedValue = "{\"" + resourceInstanceId0 + "\":\"" + expectedValue0 + "\", \"" + resourceInstanceId15 + "\":\"" + expectedValue15 + "\"}";
|
||||
String expectedValue0 = "1525ad45675600cdef";
|
||||
Integer expectedValue15 = Integer.MAX_VALUE;
|
||||
String expectedValue = "{\"" + resourceInstanceId0 + "\":\"" + expectedValue0 + "\", \"" + resourceInstanceId15 + "\":" + expectedValue15 + "}";
|
||||
String actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedValue);
|
||||
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
@ -99,12 +250,12 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
|
||||
actualResult = sendRPCReadById(expectedPath0);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
String actualValues = rpcActualResult.get("value").asText();
|
||||
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length()/2 + "Bytes, type=OPAQUE]";
|
||||
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length() / 2 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
actualResult = sendRPCReadById(expectedPath15);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId15 + ", value=" + expectedValue15.length()/2 + "Bytes, type=OPAQUE]";
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId15 + ", value=" + Integer.toHexString(expectedValue15).length()/2 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
}
|
||||
|
||||
@ -130,7 +281,7 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
|
||||
actualResult = sendRPCReadById(expectedPath0);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
String actualValues = rpcActualResult.get("value").asText();
|
||||
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length()/2 + "Bytes, type=OPAQUE]";
|
||||
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length() / 2 + "Bytes, type=OPAQUE]";
|
||||
assertFalse(actualValues.contains(expected));
|
||||
}
|
||||
|
||||
@ -193,16 +344,16 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
|
||||
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||
String expectedPath0 = expectedPath + "/" + RESOURCE_ID_0 + "/" + resourceInstanceId0;
|
||||
String expectedPath25 =expectedPath + "/" + RESOURCE_ID_0 + "/" + resourceInstanceId25;
|
||||
String expectedPath25 = expectedPath + "/" + RESOURCE_ID_0 + "/" + resourceInstanceId25;
|
||||
actualResult = sendRPCReadById(expectedPath0);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
String actualValues = rpcActualResult.get("value").asText();
|
||||
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length()/2 + "Bytes, type=OPAQUE]";
|
||||
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length() / 2 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
actualResult = sendRPCReadById(expectedPath25);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId25 + ", value=" + expectedValue25.length()/2 + "Bytes, type=OPAQUE]";
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId25 + ", value=" + expectedValue25.length() / 2 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
}
|
||||
|
||||
@ -232,13 +383,14 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
|
||||
actualResult = sendRPCReadById(expectedPath_19_0 + "/" + RESOURCE_ID_0 + "/" + resourceInstanceId0);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
String actualValues = rpcActualResult.get("value").asText();
|
||||
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length()/2 + "Bytes, type=OPAQUE]";
|
||||
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length() / 2 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
actualResult = sendRPCReadById(expectedPath_19_0 + "/" + RESOURCE_ID_0 + "/" + resourceInstanceId25);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId25 + ", value=" + expectedValue25.length()/2 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected)); actualResult = sendRPCReadByKey(expectedKey3_0_14);
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId25 + ", value=" + expectedValue25.length() / 2 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
actualResult = sendRPCReadByKey(expectedKey3_0_14);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mSingleResource [id=" + RESOURCE_ID_14 + ", value=" + expectedValue3_0_14 + ", type=STRING]";
|
||||
@ -270,12 +422,12 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
|
||||
actualResult = sendRPCReadById(expectedPath_19_0 + "/" + RESOURCE_ID_0 + "/" + resourceInstanceId0);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
String actualValues = rpcActualResult.get("value").asText();
|
||||
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length()/2 + "Bytes, type=OPAQUE]";
|
||||
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length() / 2 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
actualResult = sendRPCReadById(expectedPath_19_0 + "/" + RESOURCE_ID_0 + "/" + resourceInstanceId25);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
actualValues = rpcActualResult.get("value").asText();
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId25 + ", value=" + expectedValue25.length()/2 + "Bytes, type=OPAQUE]";
|
||||
expected = "LwM2mResourceInstance [id=" + resourceInstanceId25 + ", value=" + expectedValue25.length() / 2 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
}
|
||||
|
||||
@ -301,7 +453,7 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
|
||||
actualResult = sendRPCReadById(expectedPath19_1_0_2);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
String actualValues = rpcActualResult.get("value").asText();
|
||||
String expected = "LwM2mResourceInstance [id=" + RESOURCE_INSTANCE_ID_2 + ", value=" + expectedValue19_1_0_2.length()/2 + "Bytes, type=OPAQUE]";
|
||||
String expected = "LwM2mResourceInstance [id=" + RESOURCE_INSTANCE_ID_2 + ", value=" + expectedValue19_1_0_2.length() / 2 + "Bytes, type=OPAQUE]";
|
||||
assertTrue(actualValues.contains(expected));
|
||||
actualResult = sendRPCReadByKey(expectedKey3_0_14);
|
||||
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.thingsboard.server.transport.lwm2m.server.downlink;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -396,7 +397,12 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
|
||||
String msgError = "";
|
||||
if (resourceModelWrite.multiple) {
|
||||
try {
|
||||
Map<Integer, Object> value = convertMultiResourceValuesFromRpcBody(request.getValue(), resourceModelWrite.type, request.getObjectId());
|
||||
Object valueForMultiResource = request.getValue();
|
||||
if (resultIds.isResourceInstance()) {
|
||||
String resourceInstance = "{" + resultIds.getResourceInstanceId() + "=" + request.getValue() + "}";
|
||||
valueForMultiResource = JsonParser.parseString(resourceInstance);
|
||||
}
|
||||
Map<Integer, Object> value = convertMultiResourceValuesFromRpcBody(valueForMultiResource, resourceModelWrite.type, request.getObjectId());
|
||||
downlink = new WriteRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId(),
|
||||
value, resourceModelWrite.type);
|
||||
} catch (Exception e) {
|
||||
@ -707,7 +713,7 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
|
||||
LwM2mPath pathIds = new LwM2mPath(fromVersionedIdToObjectId(versionedId));
|
||||
if (pathIds.isResourceInstance() || pathIds.isResource()) {
|
||||
ResourceModel resourceModel = client.getResourceModel(versionedId, modelProvider);
|
||||
if (resourceModel != null && (pathIds.isResourceInstance() || (pathIds.isResource() && !resourceModel.multiple))) {
|
||||
if (resourceModel != null && !resourceModel.multiple) {
|
||||
ContentFormat[] desiredFormats;
|
||||
if (OBJLNK.equals(resourceModel.type)) {
|
||||
desiredFormats = new ContentFormat[]{ContentFormat.LINK, ContentFormat.CBOR, ContentFormat.SENML_CBOR, ContentFormat.SENML_JSON};
|
||||
|
||||
@ -277,17 +277,6 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler {
|
||||
|
||||
private void sendWriteReplaceRequest(LwM2mClient client, TransportProtos.ToDeviceRpcRequestMsg requestMsg, String versionedId) {
|
||||
RpcWriteReplaceRequest requestBody = JacksonUtil.fromString(requestMsg.getParams(), RpcWriteReplaceRequest.class);
|
||||
LwM2mPath path = new LwM2mPath(fromVersionedIdToObjectId(versionedId));
|
||||
if (path.isResource()) {
|
||||
ResourceModel resourceModel = client.getResourceModel(versionedId, modelProvider);
|
||||
if (resourceModel != null && resourceModel.multiple) {
|
||||
try {
|
||||
Map<Integer, Object> value = convertMultiResourceValuesFromRpcBody(requestBody.getValue(), resourceModel.type, versionedId);
|
||||
requestBody.setValue(value);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
TbLwM2MWriteReplaceRequest request = TbLwM2MWriteReplaceRequest.builder().versionedId(versionedId)
|
||||
.value(requestBody.getValue())
|
||||
.timeout(clientContext.getRequestTimeout(client)).build();
|
||||
@ -330,7 +319,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler {
|
||||
|
||||
if (versionedId == null) {
|
||||
if (path.isResourceInstance()) {
|
||||
setValueToCompositeNodes(client, newNodes, nodes, key, value.toString());
|
||||
setValueToCompositeNodes(client, newNodes, nodes, key, value);
|
||||
} else if (path.isResource()) {
|
||||
validateResource(client, newNodes, nodes, key , value);
|
||||
} else if (path.isObjectInstance() && value instanceof Map<?, ?>) {
|
||||
@ -342,7 +331,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler {
|
||||
"The WriteComposite operation is only used for SingleResources or/and ResourceInstance.", nodes));
|
||||
}
|
||||
} else {
|
||||
setValueToCompositeNodes(client, newNodes, nodes, versionedId, value.toString());
|
||||
setValueToCompositeNodes(client, newNodes, nodes, versionedId, value);
|
||||
}
|
||||
});
|
||||
return newNodes;
|
||||
@ -351,10 +340,10 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler {
|
||||
private void validateResource(LwM2mClient client, Map newNodes, Map nodes, String resourceId , Object value) {
|
||||
if (value instanceof Map<?, ?>) {
|
||||
((Map<?, ?>) value).forEach((k, v) -> {
|
||||
setValueToCompositeNodes(client, newNodes, nodes, validateResourceId (resourceId, k.toString(), nodes), v.toString());
|
||||
setValueToCompositeNodes(client, newNodes, nodes, validateResourceId (resourceId, k.toString(), nodes), v);
|
||||
});
|
||||
} else {
|
||||
setValueToCompositeNodes(client, newNodes, nodes, resourceId, value.toString());
|
||||
setValueToCompositeNodes(client, newNodes, nodes, resourceId, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,7 +357,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void setValueToCompositeNodes (LwM2mClient client, Map newNodes, Map nodes, String versionedId , String value) {
|
||||
private void setValueToCompositeNodes (LwM2mClient client, Map newNodes, Map nodes, String versionedId , Object value) {
|
||||
// validate value. Must be only primitive, not JsonObject or JsonArray
|
||||
try {
|
||||
JsonElement element = JsonUtils.parse(value);
|
||||
@ -378,7 +367,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler {
|
||||
}
|
||||
// convert value from JsonPrimitive() to resource/ResourceInstance type
|
||||
ResourceModel resourceModel = client.getResourceModel(versionedId, modelProvider);
|
||||
Object newValue = convertValueByTypeResource(value, resourceModel.type, versionedId);
|
||||
Object newValue = convertValueByTypeResource(element, resourceModel.type, versionedId);
|
||||
|
||||
// add new value after convert
|
||||
newNodes.put(fromVersionedIdToObjectId(versionedId), newValue);
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
package org.thingsboard.server.transport.lwm2m.utils;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.californium.elements.config.Configuration;
|
||||
import org.eclipse.leshan.core.model.LwM2mModel;
|
||||
@ -27,7 +28,6 @@ import org.eclipse.leshan.core.node.LwM2mPath;
|
||||
import org.eclipse.leshan.core.node.LwM2mResource;
|
||||
import org.eclipse.leshan.core.node.LwM2mSingleResource;
|
||||
import org.eclipse.leshan.core.util.Hex;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
import org.thingsboard.server.common.data.DeviceTransportType;
|
||||
import org.thingsboard.server.common.data.StringUtils;
|
||||
@ -35,7 +35,6 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportC
|
||||
import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential;
|
||||
import org.thingsboard.server.common.data.ota.OtaPackageKey;
|
||||
import org.thingsboard.server.common.transport.util.JsonUtils;
|
||||
import org.thingsboard.server.transport.lwm2m.config.TbLwM2mVersion;
|
||||
import org.thingsboard.server.transport.lwm2m.server.LwM2mOtaConvert;
|
||||
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
|
||||
@ -62,6 +61,7 @@ import static org.eclipse.leshan.core.model.ResourceModel.Type.STRING;
|
||||
import static org.eclipse.leshan.core.model.ResourceModel.Type.TIME;
|
||||
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY;
|
||||
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
|
||||
import static org.thingsboard.server.common.transport.util.JsonUtils.convertToJsonObject;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_RESULT_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_STATE_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SW_RESULT_ID;
|
||||
@ -180,9 +180,11 @@ public class LwM2MTransportUtil {
|
||||
*/
|
||||
public static ResourceModel.Type equalsResourceTypeGetSimpleName(Object value) {
|
||||
switch (value.getClass().getSimpleName()) {
|
||||
case "Float":
|
||||
case "Double":
|
||||
return FLOAT;
|
||||
case "Integer":
|
||||
case "Long":
|
||||
return INTEGER;
|
||||
case "String":
|
||||
return STRING;
|
||||
@ -199,6 +201,30 @@ public class LwM2MTransportUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getJsonPrimitiveValue(JsonPrimitive value) {
|
||||
if(value.isString()) {
|
||||
return value.getAsString();
|
||||
} else if (value.isNumber()){
|
||||
try {
|
||||
return Integer.valueOf(value.toString());
|
||||
} catch (NumberFormatException i) {
|
||||
try {
|
||||
return Long.valueOf(value.toString());
|
||||
} catch (NumberFormatException l){
|
||||
if (value.getAsFloat() >= Float.MIN_VALUE && value.getAsFloat() <= Float.MAX_VALUE) {
|
||||
return value.getAsFloat();
|
||||
} else {
|
||||
return value.getAsDouble();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (value.isBoolean()){
|
||||
return value.getAsBoolean();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateVersionedId(LwM2mClient client, HasVersionedId request) {
|
||||
String msgExceptionStr = "";
|
||||
if (request.getObjectId() == null) {
|
||||
@ -212,22 +238,29 @@ public class LwM2MTransportUtil {
|
||||
}
|
||||
|
||||
public static Map<Integer, Object> convertMultiResourceValuesFromRpcBody(Object value, ResourceModel.Type type, String versionedId) throws Exception {
|
||||
String valueJsonStr = JacksonUtil.toString(value);
|
||||
JsonElement element = JsonUtils.parse(valueJsonStr);
|
||||
return convertMultiResourceValuesFromJson(element, type, versionedId);
|
||||
if (value instanceof JsonElement) {
|
||||
return convertMultiResourceValuesFromJson((JsonElement) value, type, versionedId);
|
||||
} else if (value instanceof Map) {
|
||||
JsonElement valueConvert = convertToJsonObject((Map<String, ?>) value);
|
||||
return convertMultiResourceValuesFromJson(valueConvert, type, versionedId);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<Integer, Object> convertMultiResourceValuesFromJson(JsonElement newValProto, ResourceModel.Type type, String versionedId) {
|
||||
Map<Integer, Object> newValues = new HashMap<>();
|
||||
newValProto.getAsJsonObject().entrySet().forEach((obj) -> {
|
||||
newValues.put(Integer.valueOf(obj.getKey()), convertValueByTypeResource(obj.getValue().getAsString(), type, versionedId));
|
||||
Object valueByTypeResource = convertValueByTypeResource(obj.getValue(), type, versionedId);
|
||||
newValues.put(Integer.valueOf(obj.getKey()), valueByTypeResource);
|
||||
});
|
||||
return newValues;
|
||||
}
|
||||
|
||||
public static Object convertValueByTypeResource(String value, ResourceModel.Type type, String versionedId) {
|
||||
return LwM2mValueConverterImpl.getInstance().convertValue(value,
|
||||
STRING, type, new LwM2mPath(fromVersionedIdToObjectId(versionedId)));
|
||||
public static Object convertValueByTypeResource(Object value, ResourceModel.Type type, String versionedId) {
|
||||
Object valueCurrent = getJsonPrimitiveValue((JsonPrimitive) value);
|
||||
return LwM2mValueConverterImpl.getInstance().convertValue(valueCurrent,
|
||||
equalsResourceTypeGetSimpleName(valueCurrent), type, new LwM2mPath(fromVersionedIdToObjectId(versionedId)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -25,6 +25,7 @@ import org.eclipse.leshan.core.util.Hex;
|
||||
import org.thingsboard.server.common.data.StringUtils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Base64;
|
||||
@ -165,7 +166,19 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter {
|
||||
}
|
||||
break;
|
||||
case OPAQUE:
|
||||
if (currentType == Type.STRING) {
|
||||
if (currentType == Type.INTEGER) {
|
||||
if (value instanceof Integer) {
|
||||
return ByteBuffer.allocate(4).putInt((Integer) value).array();
|
||||
} else {
|
||||
return ByteBuffer.allocate(8).putLong((Long) value).array();
|
||||
}
|
||||
} else if (currentType == Type.FLOAT) {
|
||||
if (value instanceof Float) {
|
||||
return ByteBuffer.allocate(4).putFloat((Float) value).array();
|
||||
} else {
|
||||
return ByteBuffer.allocate(8).putDouble((Double) value).array();
|
||||
}
|
||||
} else if (currentType == Type.STRING) {
|
||||
/** let's assume we received an hexadecimal string */
|
||||
log.debug("Trying to convert hexadecimal/base64 string [{}] to byte array", value);
|
||||
try {
|
||||
@ -178,6 +191,8 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter {
|
||||
value, resourcePath);
|
||||
}
|
||||
}
|
||||
} else if (currentType == Type.BOOLEAN) {
|
||||
return new byte[] {(byte)((boolean)value ? 1 : 0)};
|
||||
}
|
||||
break;
|
||||
case OBJLNK:
|
||||
|
||||
@ -18,9 +18,11 @@ package org.thingsboard.server.common.transport.util;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.KeyValueProto;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JsonUtils {
|
||||
|
||||
@ -47,9 +49,30 @@ public class JsonUtils {
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
public static JsonElement parse(String params) {
|
||||
return JsonParser.parseString(params);
|
||||
public static JsonElement parse(Object value) {
|
||||
if (value instanceof Integer) {
|
||||
return new JsonPrimitive((Integer) value);
|
||||
} else if (value instanceof Long) {
|
||||
return new JsonPrimitive((Long) value);
|
||||
} else if (value instanceof String) {
|
||||
return JsonParser.parseString((String) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
return new JsonPrimitive((Boolean) value);
|
||||
} else if (value instanceof Double) {
|
||||
return new JsonPrimitive((Double) value);
|
||||
} else if (value instanceof Float) {
|
||||
return new JsonPrimitive((Float) value);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported type: " + value.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject convertToJsonObject(Map<String,?> map) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
for (Map.Entry<String, ?> entry : map.entrySet()) {
|
||||
jsonObject.add(entry.getKey(), parse(entry.getValue()));
|
||||
}
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user