From 03560f05577c7c73f708271c98eb2418d2df52e0 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 26 Dec 2023 17:26:51 +0200 Subject: [PATCH] lwm2ml: add tests attributes --- ...pcLwm2mIntegrationWriteAttributesTest.java | 37 +++++++++++++-- .../profile/lwm2m/ObjectAttributes.java | 15 ++++++- .../DefaultLwM2mDownlinkMsgHandler.java | 45 +++++++++++++++---- 3 files changed, 83 insertions(+), 14 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteAttributesTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteAttributesTest.java index 6275a657b5..c2d87149de 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteAttributesTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteAttributesTest.java @@ -17,7 +17,6 @@ package org.thingsboard.server.transport.lwm2m.rpc.sql; import com.fasterxml.jackson.databind.node.ObjectNode; import org.eclipse.leshan.core.ResponseCode; -import org.junit.Ignore; import org.junit.Test; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.transport.lwm2m.rpc.AbstractRpcLwM2MIntegrationTest; @@ -30,22 +29,47 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID public class RpcLwm2mIntegrationWriteAttributesTest extends AbstractRpcLwM2MIntegrationTest { - @Ignore /** * WriteAttributes {"id":"/3/0/14","attributes":{"pmax":100, "pmin":10}} * if not implemented: - * {"result":"BAD_REQUEST","error":"Content Format is mandatory"} + * {"result":"INTERNAL_SERVER_ERROR","error":"not implemented"} * if implemented: * {"result":"CHANGED"} */ @Test public void testWriteAttributesResourceWithParametersById_Result_INTERNAL_SERVER_ERROR() throws Exception { String expectedPath = objectInstanceIdVer_3 + "/" + RESOURCE_ID_14; + sendRPCReadById(expectedPath); String expectedValue = "{\"pmax\":100, \"pmin\":10}"; String actualResult = sendRPCExecuteWithValueById(expectedPath, expectedValue); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); + assertEquals(ResponseCode.INTERNAL_SERVER_ERROR.getName(), rpcActualResult.get("result").asText()); + String expected = "not implemented"; + String actual = rpcActualResult.get("error").asText(); + assertTrue(actual.equals(expected)); + } + @Test + public void testWriteAttributesResourceVerWithParametersById_Result_BAD_REQUEST() throws Exception { + String expectedPath = objectIdVer_3; + String actualResult = sendRPCReadById(expectedPath); + String expectedValue = "{\"ver\":1.3}"; + actualResult = sendRPCExecuteWithValueById(expectedPath, expectedValue); + ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText()); - String expected = "Content Format is mandatory"; + String expected = "Attribute ver is of class PROPERTIES but only NOTIFICATION attribute can be used in WRITE ATTRIBUTE request."; + String actual = rpcActualResult.get("error").asText(); + assertTrue(actual.equals(expected)); + } + + @Test + public void testWriteAttributesResourceServerUriWithParametersById_Result_BAD_REQUEST() throws Exception { + String expectedPath = objectInstanceIdVer_1; + String actualResult = sendRPCReadById(expectedPath); + String expectedValue = "{\"uri\":\"coaps://localhost:5690\"}"; + actualResult = sendRPCExecuteWithValueById(expectedPath, expectedValue); + ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); + assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText()); + String expected = "Attribute uri is of class PROPERTIES but only NOTIFICATION attribute can be used in WRITE ATTRIBUTE request."; String actual = rpcActualResult.get("error").asText(); assertTrue(actual.equals(expected)); } @@ -55,4 +79,9 @@ public class RpcLwm2mIntegrationWriteAttributesTest extends AbstractRpcLwM2MInte return doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setRpcRequest, String.class, status().isOk()); } + private String sendRPCReadById(String path) throws Exception { + String setRpcRequest = "{\"method\": \"Read\", \"params\": {\"id\": \"" + path + "\"}}"; + return doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setRpcRequest, String.class, status().isOk()); + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/ObjectAttributes.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/ObjectAttributes.java index b195068b62..f22ffe4104 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/ObjectAttributes.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/ObjectAttributes.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.device.profile.lwm2m; import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data; +import org.eclipse.leshan.core.LwM2m; import java.io.Serializable; @@ -25,13 +26,25 @@ import java.io.Serializable; public class ObjectAttributes implements Serializable { private static final long serialVersionUID = 4765123984733721312L; - private Long dim; + private Long ssid; + private String uri; private String ver; + private String lwm2m; private Long pmin; private Long pmax; private Double gt; private Double lt; private Double st; + private Long epmin; + private Long epmax; + + public LwM2m.Version getVer(){ + return ver != null ? new LwM2m.Version(ver) : null; + } + + public LwM2m.LwM2mVersion getLwm2m(){ + return lwm2m != null ? LwM2m.LwM2mVersion.get(lwm2m) : null; + } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java index e124b8142d..3f2f8c598e 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java @@ -92,10 +92,17 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; +import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.DIMENSION; +import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.ENABLER_VERSION; +import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.EVALUATE_MAXIMUM_PERIOD; +import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.EVALUATE_MINIMUM_PERIOD; import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.GREATER_THAN; import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.LESSER_THAN; import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.MAXIMUM_PERIOD; import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.MINIMUM_PERIOD; +import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.OBJECT_VERSION; +import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.SERVER_URI; +import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.SHORT_SERVER_ID; import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.STEP; import static org.eclipse.leshan.core.model.ResourceModel.Type.OBJLNK; import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE; @@ -281,20 +288,40 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im if (request.getAttributes() == null) { throw new IllegalArgumentException("Attributes to write are not specified!"); } - ObjectAttributes params = request.getAttributes(); - List> attributes = new LinkedList<>(); - addAttribute(attributes, MAXIMUM_PERIOD, params.getPmax()); - addAttribute(attributes, MINIMUM_PERIOD, params.getPmin()); - addAttribute(attributes, GREATER_THAN, params.getGt()); - addAttribute(attributes, LESSER_THAN, params.getLt()); - addAttribute(attributes, STEP, params.getSt()); - LwM2mAttributeSet attributeSet = new LwM2mAttributeSet(attributes); - sendSimpleRequest(client, new WriteAttributesRequest(request.getObjectId(), attributeSet), request.getTimeout(), callback); + sendSimpleRequest(client, new WriteAttributesRequest(request.getObjectId(), getAttributesSet(request.getAttributes())), request.getTimeout(), callback); } catch (InvalidRequestException e) { callback.onValidationError(request.toString(), e.getMessage()); } } + private LwM2mAttributeSet getAttributesSet(ObjectAttributes params) { + List> attributes = new LinkedList<>(); + /** + * Only: AttributeClass.NOTIFICATION -> RW + */ + addAttribute(attributes, MAXIMUM_PERIOD, params.getPmax()); + addAttribute(attributes, MINIMUM_PERIOD, params.getPmin()); + addAttribute(attributes, GREATER_THAN, params.getGt()); + addAttribute(attributes, LESSER_THAN, params.getLt()); + addAttribute(attributes, STEP, params.getSt()); + addAttribute(attributes, EVALUATE_MAXIMUM_PERIOD, params.getEpmax()); + addAttribute(attributes, EVALUATE_MINIMUM_PERIOD, params.getEpmin()); + /** + * Only: AttributeClass.PROPERTIES -> R + */ + addAttribute(attributes, DIMENSION, params.getDim()); // Attachment.RESOURCE + addAttribute(attributes, SHORT_SERVER_ID, params.getSsid()); // Attachment.OBJECT_INSTANCE + addAttribute(attributes, SERVER_URI, params.getUri()); // Attachment.OBJECT_INSTANCE + if (params.getLwm2m() != null) { + addAttribute(attributes, ENABLER_VERSION, params.getLwm2m()); // attachment.ROOT + } + if (params.getVer() != null) { + addAttribute(attributes, OBJECT_VERSION, params.getVer()); // Attachment.OBJECT + } + + return new LwM2mAttributeSet(attributes); + } + @Override public void sendWriteReplaceRequest(LwM2mClient client, TbLwM2MWriteReplaceRequest request, DownlinkRequestCallback callback) { LwM2mPath resultIds = new LwM2mPath(request.getObjectId());