Browse Source

lwm2m: abstract integration RPC test delete, create, writeAttribute, execute

pull/5171/head
nickAS21 5 years ago
parent
commit
0a3c626333
  1. 5
      application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java
  2. 1
      application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java
  3. 34
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java
  4. 70
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationCreateTest.java
  5. 96
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationDeleteTest.java
  6. 35
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationDiscoverTest.java
  7. 186
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationExecuteTest.java
  8. 16
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationReadTest.java
  9. 63
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteAttributesTest.java
  10. 71
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteTest.java
  11. 6
      application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/OtaLwM2MIntegrationTest.java
  12. 2
      common/data/src/main/java/org/thingsboard/server/common/data/device/data/lwm2m/OtherConfiguration.java
  13. 2
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java

5
application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java

@ -45,17 +45,22 @@ public class Lwm2mTestHelper {
public static final int TEMPERATURE_SENSOR = 3303;
// Ids in Client
public static final int objectId_0 = 0;
public static final int objectInstanceId_0 = 0;
public static final int objectInstanceId_1 = 1;
public static final int objectInstanceId_2 = 2;
public static final int objectInstanceId_12 = 12;
public static final int resourceId_0 = 0;
public static final int resourceId_1 = 1;
public static final int resourceId_2 = 2;
public static final int resourceId_3 = 3;
public static final int resourceId_4 = 4;
public static final int resourceId_8 = 8;
public static final int resourceId_9 = 9;
public static final int resourceId_11 = 11;
public static final int resourceId_14 = 14;
public static final int resourceId_15= 15;
public static final int resourceInstanceId_2 = 2;
public static final String resourceIdName_3_9 = "batteryLevel";
public static final String resourceIdName_3_14 = "UtfOffset";

1
application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java

@ -44,7 +44,6 @@ import org.eclipse.leshan.core.request.BootstrapRequest;
import org.eclipse.leshan.core.request.DeregisterRequest;
import org.eclipse.leshan.core.request.RegisterRequest;
import org.eclipse.leshan.core.request.UpdateRequest;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
import org.junit.Assert;

34
application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java

@ -59,6 +59,7 @@ import static org.eclipse.leshan.core.LwM2mId.ACCESS_CONTROL;
import static org.eclipse.leshan.core.LwM2mId.DEVICE;
import static org.eclipse.leshan.core.LwM2mId.FIRMWARE;
import static org.eclipse.leshan.core.LwM2mId.SERVER;
import static org.eclipse.leshan.core.LwM2mId.SOFTWARE_MANAGEMENT;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.BINARY_APP_DATA_CONTAINER;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.COAP_CONFIG;
@ -72,6 +73,7 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SECURITY;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SHORT_SERVER_ID;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SHORT_SERVER_ID_BS;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.TEMPERATURE_SENSOR;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectId_0;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectInstanceId_0;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectInstanceId_1;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceIdName_19_0_0;
@ -158,12 +160,16 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractWebsocketT
public Set expectedObjectIdVerInstances;
protected String objectInstanceIdVer_1;
protected String objectIdVer_0;
protected String objectIdVer_2;
private static final Predicate predicate_3 = path -> (!((String) path).contains("/" + TEMPERATURE_SENSOR) && ((String) path).contains("/" + DEVICE));
protected String objectIdVer_3;
protected String objectInstanceIdVer_3;
protected String objectInstanceIdVer_5;
protected String objectInstanceIdVer_9;
protected String objectIdVer_19;
protected String objectIdVer_50 = "/50";
protected String objectIdVer_3303;
public AbstractRpcLwM2MIntegrationTest(){ }
@ -212,13 +218,21 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractWebsocketT
});
}
});
objectInstanceIdVer_1 = (String) expectedObjectIdVerInstances.stream().filter(path -> (!((String) path).contains("/" + BINARY_APP_DATA_CONTAINER) && ((String) path).contains("/" + SERVER))).findFirst().get();
String ver_Id_0 = client.getClient().getObjectTree().getModel().getObjectModel(objectId_0).version;
if ("1.0".equals(ver_Id_0)) {
objectIdVer_0 = "/" + objectId_0;
}
else {
objectIdVer_0 = "/" + objectId_0 + "_" + ver_Id_0;
}
objectIdVer_2 = (String) expectedObjectIdVers.stream().filter(path -> ((String) path).contains("/" + ACCESS_CONTROL)).findFirst().get();
objectIdVer_3 = (String) expectedObjects.stream().filter(predicate_3).findFirst().get();
objectIdVer_19 = (String) expectedObjects.stream().filter(predicate_3).findFirst().get();
objectIdVer_19 = (String) expectedObjectIdVers.stream().filter(path -> ((String) path).contains("/" + BINARY_APP_DATA_CONTAINER)).findFirst().get();
objectIdVer_3303 = (String) expectedObjectIdVers.stream().filter(path -> ((String) path).contains("/" + TEMPERATURE_SENSOR)).findFirst().get();
objectInstanceIdVer_1 = (String) expectedObjectIdVerInstances.stream().filter(path -> (!((String) path).contains("/" + BINARY_APP_DATA_CONTAINER) && ((String) path).contains("/" + SERVER))).findFirst().get();
objectInstanceIdVer_3 = (String) expectedObjectIdVerInstances.stream().filter(predicate_3).findFirst().get();
objectInstanceIdVer_5 = (String) expectedObjectIdVerInstances.stream().filter(path -> ((String) path).contains("/" + FIRMWARE)).findFirst().get();
objectIdVer_19 = (String) expectedObjectIdVers.stream().filter(path -> ((String) path).contains("/" + BINARY_APP_DATA_CONTAINER)).findFirst().get();
objectInstanceIdVer_9 = (String) expectedObjectIdVerInstances.stream().filter(path -> ((String) path).contains("/" + SOFTWARE_MANAGEMENT)).findFirst().get();
}
protected void createDeviceProfile(String transportConfiguration) throws Exception {
@ -285,13 +299,13 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractWebsocketT
return bootstrap;
}
protected String objectIdVerToObjectId(String objectIdVer) {
return objectIdVer.contains("_") ? objectIdVer.split("_")[0] : objectIdVer;
}
protected String objectInstanceIdVerToObjectInstanceId(String objectInstanceIdVer) {
String[] objectIdVer = objectInstanceIdVer.split("/");
return objectIdVer[1].contains("_") ? objectIdVer[1].split("_")[0] + "/" + objectIdVer[2] : objectInstanceIdVer;
protected String pathIdVerToObjectId(String pathIdVer) {
if (pathIdVer.contains("_")){
String [] objVer = pathIdVer.split("/");
objVer[1] = objVer[1].split("_")[0];
return String.join("/", objVer);
}
return pathIdVer;
}
@After

70
application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationCreateTest.java

@ -17,6 +17,7 @@ package org.thingsboard.server.transport.lwm2m.rpc.sql;
import com.fasterxml.jackson.databind.node.ObjectNode;
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.server.transport.lwm2m.rpc.AbstractRpcLwM2MIntegrationTest;
@ -25,11 +26,29 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectInstanceId_0;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectInstanceId_1;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectInstanceId_12;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_0;
public class RpcLwm2mIntegrationCreateTest extends AbstractRpcLwM2MIntegrationTest {
/**
* Create {"id":"/19_1.1","value":{"0":{"0":"00AC"}, "1":1}}
*
* create_2_instances_in_object
* new ObjectInstance if Object is Multiple & Resource Single
* Create {"id":"/19_1.1/12","value":{"0":{"0":"00AC", "1":1}}}
* {"{"result":"CREATED"}"}
*/
@Test
public void testCreateObjectInstanceWithInstanceIdByIdKey_Result_CREATED() throws Exception {
String expectedPath = objectIdVer_19 + "/" + objectInstanceId_12;
String expectedValue = "{\"" + resourceId_0 + "\":{\"0\":\"00AC\"}, \"1\":1}";
String actualResult = sendRPCreateById(expectedPath, expectedValue);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CREATED.getName(), rpcActualResult.get("result").asText());
}
/**
* Create {"id":"/19_1.1","value":{"0":{"0":"00AC"}, "1":1}}
@ -38,10 +57,9 @@ public class RpcLwm2mIntegrationCreateTest extends AbstractRpcLwM2MIntegrationTe
* new ObjectInstance if Object is Multiple & Resource Single
* Create {"id":"/19_1.1/0","value":{"0":{"0":"00AC", "1":1}}}
* {"result":"BAD_REQUEST","error":"instance 0 already exists"}
*
*/
@Test
public void testCreateObjectInstanceWithInstanceIdAlreadyExistsByIdKey_Result_BAD_REQUEST() throws Exception {
public void testCreateObjectInstanceWithInstanceIdAlreadyExistsById_Result_BAD_REQUEST() throws Exception {
String expectedPath = objectIdVer_19 + "/" + objectInstanceId_0;
String expectedValue = "{\"" + resourceId_0 + "\":{\"0\":\"00AC\"}, \"1\":1}";
String actualResult = sendRPCreateById(expectedPath, expectedValue);
@ -54,20 +72,58 @@ public class RpcLwm2mIntegrationCreateTest extends AbstractRpcLwM2MIntegrationTe
/**
* failed: cannot_create_mandatory_single_object
* Create {"id":"/3/2","value":{"0":"00AC"}}
* Create {"id":"/3/1,"value":{"0":"00AC"}}
* {"result":"BAD_REQUEST","error":"Path /3/1. Object must be Multiple !"}
*/
@Test
public void testCreateObjectInstanceWithInstanceIdMandatorySingleObjectById_Result_BAD_REQUEST() throws Exception {
String expectedPath = objectIdVer_3 + "/" + objectInstanceId_1;
String expectedValue = "{\"" + resourceId_0 + "\":{\"0\":\"00AC\"}}";
String actualResult = sendRPCreateById(expectedPath, expectedValue);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText());
String expected = "Path " + expectedPath + ". Object must be Multiple !";
String actual = rpcActualResult.get("error").asText();
assertTrue(actual.equals(expected));
}
/**
* failed: cannot_create_instance_of_security_object
* Create {"id":"/0/2","value":{"0":"00AC"}}
* Create {"id":"/0/2","value":{"2":4}}
* {"result":"BAD_REQUEST","error":"Specified object id 0 absent in the list supported objects of the client or is security object!"}
*/
@Test
public void testCreateObjectInstanceWithInstanceIdSecurityObjectById_Result_BAD_REQUEST() throws Exception {
String expectedPath = objectIdVer_0 + "/" + objectInstanceId_1;
String expectedValue = "{\"" + resourceId_0 + "\":{\"2\":4}}";
String actualResult = sendRPCreateById(expectedPath, expectedValue);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText());
String expectedObjectId = pathIdVerToObjectId((String) expectedPath);
LwM2mPath expectedPathId = new LwM2mPath(expectedObjectId);
String expected = "Specified object id " + expectedPathId.getObjectId() + " absent in the list supported objects of the client or is security object!";
String actual = rpcActualResult.get("error").asText();
assertTrue(actual.equals(expected));
}
/**
* failed: cannot_create_instance_of_absent_object
* Create {"id":"/50/2","value":{"0":"00AC"}}
* Create {"id":"/50/1","value":{"0":"00AC"}}
* {"result":"BAD_REQUEST","error":"Specified object id 50 absent in the list supported objects of the client or is security object!"}
*/
@Test
public void testCreateObjectInstanceWithInstanceIdAbsentObjectById_Result_BAD_REQUEST() throws Exception {
String expectedPath = objectIdVer_50+ "/" + objectInstanceId_1;
String expectedValue = "{\"" + resourceId_0 + "\":{\"0\":\"00AC\"}}";
String actualResult = sendRPCreateById(expectedPath, expectedValue);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText());
String expectedObjectId = pathIdVerToObjectId((String) expectedPath);
LwM2mPath expectedPathId = new LwM2mPath(expectedObjectId);
String expected = "Specified object id " + expectedPathId.getObjectId() + " absent in the list supported objects of the client or is security object!";
String actual = rpcActualResult.get("error").asText();
assertTrue(actual.equals(expected));
}
private String sendRPCreateById(String path, String value) throws Exception {
String setRpcRequest = "{\"method\": \"Create\", \"params\": {\"id\": \"" + path + "\", \"value\": " + value + " }}";

96
application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationDeleteTest.java

@ -0,0 +1,96 @@
/**
* Copyright © 2016-2021 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.lwm2m.rpc.sql;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.eclipse.leshan.core.ResponseCode;
import org.junit.Test;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.transport.lwm2m.rpc.AbstractRpcLwM2MIntegrationTest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectInstanceId_0;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectInstanceId_12;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_9;
public class RpcLwm2mIntegrationDeleteTest extends AbstractRpcLwM2MIntegrationTest {
/**
* if there is such an instance
* Delete {"id":"/3303/12"}
* {"result":"DELETE"}
*/
@Test
public void testDeleteObjectInstanceIsSuchByIdKey_Result_DELETED() throws Exception {
String expectedPath = objectIdVer_3303 + "/" + objectInstanceId_12;
String actualResult = sendRPCDeleteById(expectedPath);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.DELETED.getName(), rpcActualResult.get("result").asText());
}
/**
* if there is no such instance
* Delete {"id":"/19/12"}
* {"result":"NOT_FOUND"}
*/
@Test
public void testDeleteObjectInstanceIsNotSuchByIdKey_Result_NOT_FOUND() throws Exception {
String expectedPath = objectIdVer_19 + "/" + objectInstanceId_12;
String actualResult = sendRPCDeleteById(expectedPath);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.NOT_FOUND.getName(), rpcActualResult.get("result").asText());
}
/**
* delete object
* Delete {"id":"/19_1.1"}
* {"result":"BAD_REQUEST","error":"Invalid path /19 : Only object instances can be delete"}
*/
@Test
public void testDeleteObjectByIdKey_Result_BAD_REQUEST() throws Exception {
String expectedPath = objectIdVer_19;
String actualResult = sendRPCDeleteById(expectedPath);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText());
String expected = "Invalid path " + pathIdVerToObjectId((String) expectedPath) + " : Only object instances can be delete";
String actual = rpcActualResult.get("error").asText();
assertTrue(actual.equals(expected));
}
/**
* delete resource
* Delete {"id":"/3/0/9"}
* {"result":"METHOD_NOT_ALLOWED"}
*/
@Test
public void testDeleteResourceByIdKey_Result_METHOD_NOT_ALLOWED() throws Exception {
String expectedPath = objectIdVer_3 + "/" + objectInstanceId_0 + resourceId_9;
String actualResult = sendRPCDeleteById(expectedPath);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.METHOD_NOT_ALLOWED.getName(), rpcActualResult.get("result").asText());
}
private String sendRPCDeleteById(String path) throws Exception {
String setRpcRequest = "{\"method\": \"Delete\", \"params\": {\"id\": \"" + path + "\"}}";
return doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setRpcRequest, String.class, status().isOk());
}
}

35
application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationDiscoverTest.java

@ -74,7 +74,7 @@ public class RpcLwm2mIntegrationDiscoverTest extends AbstractRpcLwM2MIntegration
expectedObjectIdVers.forEach(expected -> {
try {
String actualResult = sendDiscover((String) expected);
String expectedObjectId = objectIdVerToObjectId ((String) expected);
String expectedObjectId = pathIdVerToObjectId((String) expected);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText());
String[] actualValues = rpcActualResult.get("value").asText().split(",");
@ -88,8 +88,12 @@ public class RpcLwm2mIntegrationDiscoverTest extends AbstractRpcLwM2MIntegration
/**
* Discover {"id":"3/0"}
*
* @throws Exception
* If WriteAttributes not implemented:
* {"result":"CONTENT","value":"</3/0>,</3/0/0>,</3/0/1>,</3/0/2>,</3/0/3>,</3/0/4>,</3/0/5>,</3/0/6>,</3/0/7>,</3/0/8>,</3/0/9>,</3/0/10>,</3/0/11>,</3/0/12>,</3/0/13>,</3/0/14>,</3/0/15>,</3/0/16>,</3/0/1
* 7>,</3/0/18>,</3/0/19>,</3/0/20>,</3/0/21>,</3/0/22>"}
* If WriteAttributes implemented and WriteAttributes saved
* Discover {"id":"19/0"}
* {"result":"CONTENT","value":"[</19/0>;dim=2;pmin=10;pmax=60;gt=50;lt=42.2,</19/0/0>;pmax=120, </19/0/1>, </19/0/2>, </19/0/3>, </19/0/4>, </19/0/5>;lt=45]"}
*/
@Test
public void testDiscoverInstance_Return_CONTENT_LinksResourcesOnLyExpectedInstance() throws Exception {
@ -97,7 +101,7 @@ public class RpcLwm2mIntegrationDiscoverTest extends AbstractRpcLwM2MIntegration
String actualResult = sendDiscover(expected);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText());
String expectedObjectInstanceId = objectInstanceIdVerToObjectInstanceId (expected);
String expectedObjectInstanceId = pathIdVerToObjectId(expected);
String[] actualValues = rpcActualResult.get("value").asText().split(",");
assertTrue(actualValues.length > 0);
assertEquals(0, Arrays.stream(actualValues).filter(path -> !path.contains(expectedObjectInstanceId)).collect(Collectors.toList()).size());
@ -105,13 +109,20 @@ public class RpcLwm2mIntegrationDiscoverTest extends AbstractRpcLwM2MIntegration
/**
* Discover {"id":"3/0/14"}
*
* @throws Exception
* If WriteAttributes implemented:
* {"result":"CONTENT","value":"</3/0/14>;pmax=100, "pmin":10, "ver"=1.0"}
* If WriteAttributes not implemented:
* {"result":"CONTENT","value":"</3/0/14>"}
* Discover {"id":"19_1.1/0/0"}
* If WriteAttributes implemented:
* {"result":"CONTENT","value":"</19/0/0>;pmax=100, "pmin":10, "ver"=1.1"}
* If WriteAttributes not implemented:
* {"result":"CONTENT","value":"</19/0/0>"}
*/
@Test
public void testDiscoverResource_Return_CONTENT_LinksResourceOnLyExpectedResource() throws Exception {
String expectedInstance = (String) expectedInstances.stream().findFirst().get();
String expectedObjectInstanceId = objectInstanceIdVerToObjectInstanceId (expectedInstance);
String expectedObjectInstanceId = pathIdVerToObjectId(expectedInstance);
LwM2mPath expectedPath = new LwM2mPath(expectedObjectInstanceId);
int expectedResource = client.getClient().getObjectTree().getObjectEnablers().get(expectedPath.getObjectId()).getObjectModel().resources.entrySet().stream().findAny().get().getKey();
String expected = expectedInstance + "/" + expectedResource;
@ -125,12 +136,11 @@ public class RpcLwm2mIntegrationDiscoverTest extends AbstractRpcLwM2MIntegration
}
/**
* Discover {"id":"2/0/2"}
*
* @throws Exception
* Discover {"id":"2/0"}
*{"result":"NOT_FOUND"}
*/
@Test
public void testDiscoverInstanceAbsentInObject_Return_NOT_FOUND() throws Exception {
public void testDiscoverObjectInstanceAbsentInObject_Return_NOT_FOUND() throws Exception {
String expected = objectIdVer_2 + "/" + objectInstanceId_0;
String actualResult = sendDiscover(expected);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
@ -138,8 +148,7 @@ public class RpcLwm2mIntegrationDiscoverTest extends AbstractRpcLwM2MIntegration
}
/**
* Discover {"id":"2/0/2"}
*
* @throws Exception
* {"result":"NOT_FOUND"}
*/
@Test
public void testDiscoverResourceAbsentInObject_Return_NOT_FOUND() throws Exception {

186
application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationExecuteTest.java

@ -0,0 +1,186 @@
/**
* Copyright © 2016-2021 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.lwm2m.rpc.sql;
import com.fasterxml.jackson.databind.node.ObjectNode;
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.server.transport.lwm2m.rpc.AbstractRpcLwM2MIntegrationTest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectInstanceId_0;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_2;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_3;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_4;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_8;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_9;
public class RpcLwm2mIntegrationExecuteTest extends AbstractRpcLwM2MIntegrationTest {
/**
* Update FW
* Execute {"id":"5/0/2"}
* {"result":"CHANGED"}
*/
@Test
public void testExecuteUpdateFWById_Result_CHANGED() throws Exception {
String expectedPath = objectInstanceIdVer_5 + "/" + resourceId_2;
String actualResult = sendRPCExecuteById(expectedPath);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
}
/**
* Update SW
* Execute {"id":"9/0/4"}
* {"result":"CHANGED"}
*/
@Test
public void testExecuteUpdateSWById_Result_CHANGED() throws Exception {
String expectedPath = objectInstanceIdVer_9 + "/" + resourceId_4;
String actualResult = sendRPCExecuteById(expectedPath);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
}
/**
* Reboot
* Execute {"id":"3/0/4"}
* {"result":"CHANGED"}
*/
@Test
public void testExecuteRebootById_Result_CHANGED() throws Exception {
String expectedPath = objectInstanceIdVer_3 + "/" + resourceId_4;
String actualResult = sendRPCExecuteById(expectedPath);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
}
/**
* Registration Update Trigger
* Execute {"id":"1/0/8"}
* {"result":"CHANGED"}
*/
@Test
public void testExecuteRegistrationUpdateTriggerById_Result_CHANGED() throws Exception {
String expectedPath = objectInstanceIdVer_1 + "/" + resourceId_8;
String actualResult = sendRPCExecuteById(expectedPath);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
}
/**
* execute_resource_with_parameters (execute reboot after 60 seconds on device)
* Execute {"id":"3/0/4","value":60}
* {"result":"CHANGED"}
*/
@Test
public void testExecuteResourceWithParametersById_Result_CHANGED() throws Exception {
String expectedPath = objectInstanceIdVer_3 + "/" + resourceId_4;
Object expectedValue = 60;
String actualResult = sendRPCExecuteWithValueById(expectedPath, expectedValue);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
}
/**
* Bootstrap-Request Trigger
* Execute {"id":"1/0/9"}
* {"result":"BAD_REQUEST","error":"probably no bootstrap server configured"}
*/
@Test
public void testExecuteBootstrapRequestTriggerById_Result_BAD_REQUEST_Error_NoBootstrapServerConfigured() throws Exception {
String expectedPath = objectInstanceIdVer_1 + "/" + resourceId_9;
String actualResult = sendRPCExecuteById(expectedPath);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText());
String expected = "probably no bootstrap server configured";
String actual = rpcActualResult.get("error").asText();
assertTrue(actual.equals(expected));
}
/**
* bad: resource operation not "E"
* Execute {"id":"5/0/3"}
* {"result":"BAD_REQUEST","error":"Resource with /5/0/3 is not executable."}
*/
@Test
public void testExecuteResourceWithOperationNotExecuteById_Result_METHOD_NOT_ALLOWED() throws Exception {
String expectedPath = objectInstanceIdVer_5 + "/" + resourceId_3;
String actualResult = sendRPCExecuteById(expectedPath);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText());
String expectedObjectId = pathIdVerToObjectId((String) expectedPath);
String expected = "Resource with " + expectedObjectId + " is not executable.";
String actual = rpcActualResult.get("error").asText();
assertTrue(actual.equals(expected));
}
/**
* bad: execute_non_existing_resource_on_non_existing_object
* Execute {"id":"50/0/3"}
* {"result":"BAD_REQUEST","error":"Specified object id 50 absent in the list supported objects of the client or is security object!"}
*/
@Test
public void testExecuteNonExistingResourceOnNonExistingObjectById_Result_BAD_REQUEST() throws Exception {
String expectedPath = objectIdVer_50 + "/" + objectInstanceId_0 + "/" + resourceId_3;
String actualResult = sendRPCExecuteById(expectedPath);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText());
String expectedObjectId = pathIdVerToObjectId((String) expectedPath);
LwM2mPath expectedPathId = new LwM2mPath(expectedObjectId);
String expected = "Specified object id " + expectedPathId.getObjectId() + " absent in the list supported objects of the client or is security object!";
String actual = rpcActualResult.get("error").asText();
assertTrue(actual.equals(expected));
}
/**
* bad: execute security object
* Execute {"id":"0/0/3"}
* {"result":"BAD_REQUEST","error":"Specified object id 0 absent in the list supported objects of the client or is security object!"}
*/
@Test
public void testExecuteSecurityObjectById_Result_NOT_FOUND() throws Exception {
String expectedPath = objectIdVer_0 + "/" + objectInstanceId_0 + "/" + resourceId_3;
String actualResult = sendRPCExecuteById(expectedPath);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText());
String expectedObjectId = pathIdVerToObjectId((String) expectedPath);
LwM2mPath expectedPathId = new LwM2mPath(expectedObjectId);
String expected = "Specified object id " + expectedPathId.getObjectId() + " absent in the list supported objects of the client or is security object!";
String actual = rpcActualResult.get("error").asText();
assertTrue(actual.equals(expected));
}
private String sendRPCExecuteById(String path) throws Exception {
String setRpcRequest = "{\"method\": \"Execute\", \"params\": {\"id\": \"" + path + "\"}}";
return doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setRpcRequest, String.class, status().isOk());
}
private String sendRPCExecuteWithValueById(String path, Object value) throws Exception {
String setRpcRequest = "{\"method\": \"Execute\", \"params\": {\"id\": \"" + path + "\", \"value\": " + value + " }}";
return doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setRpcRequest, String.class, status().isOk());
}
}

16
application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationReadTest.java

@ -52,7 +52,7 @@ public class RpcLwm2mIntegrationReadTest extends AbstractRpcLwM2MIntegrationTest
expectedObjectIdVers.forEach(expected -> {
try {
String actualResult = sendRPCById((String) expected);
String expectedObjectId = objectIdVerToObjectId ((String) expected);
String expectedObjectId = pathIdVerToObjectId((String) expected);
LwM2mPath expectedPath = new LwM2mPath(expectedObjectId);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText());
@ -77,7 +77,7 @@ public class RpcLwm2mIntegrationReadTest extends AbstractRpcLwM2MIntegrationTest
expectedObjectIdVerInstances.forEach(expected -> {
try {
String actualResult = sendRPCById((String) expected);
String expectedObjectId = objectInstanceIdVerToObjectInstanceId ((String) expected);
String expectedObjectId = pathIdVerToObjectId((String) expected);
LwM2mPath expectedPath = new LwM2mPath(expectedObjectId);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText());
@ -136,10 +136,10 @@ public class RpcLwm2mIntegrationReadTest extends AbstractRpcLwM2MIntegrationTest
@Test
public void testReadCompositeSingleResourceByIds_Result_CONTENT_Value_IsObjectIsLwM2mSingleResourceIsLwM2mMultipleResource() throws Exception {
String expectedIdVer_1 = (String) expectedObjectIdVers.stream().filter(path -> (!((String)path).contains("/" + BINARY_APP_DATA_CONTAINER) && ((String)path).contains("/" + SERVER))).findFirst().get();
String objectId_1 = objectIdVerToObjectId(expectedIdVer_1);
String objectId_1 = pathIdVerToObjectId(expectedIdVer_1);
String expectedIdVer3_0_1 = objectInstanceIdVer_3 + "/" + resourceId_1;
String expectedIdVer3_0_11 = objectInstanceIdVer_3 + "/" + resourceId_11;
String objectInstanceId_3 = objectIdVerToObjectId(objectInstanceIdVer_3);
String objectInstanceId_3 = pathIdVerToObjectId(objectInstanceIdVer_3);
String expectedIds = "[\"" + expectedIdVer_1 + "\", \"" + expectedIdVer3_0_1 + "\", \"" + expectedIdVer3_0_11 + "\"]";
String actualResult = sendCompositeRPCByIds(expectedIds);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
@ -165,10 +165,10 @@ public class RpcLwm2mIntegrationReadTest extends AbstractRpcLwM2MIntegrationTest
String actualResult = sendCompositeRPCByIds(expectedIds);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText());
String objectInstanceId_3 = objectInstanceIdVerToObjectInstanceId(objectInstanceIdVer_3);
String objectInstanceId_3 = pathIdVerToObjectId(objectInstanceIdVer_3);
LwM2mPath path = new LwM2mPath(objectInstanceId_3);
String expected3_0 = objectInstanceId_3 + "=LwM2mObjectInstance [id=" + path.getObjectInstanceId() + ", resources={";
String objectInstanceId_1 = objectInstanceIdVerToObjectInstanceId(objectInstanceIdVer_1);
String objectInstanceId_1 = pathIdVerToObjectId(objectInstanceIdVer_1);
String expected1_0_1 = objectInstanceId_1 + "/" + resourceId_1 + "=LwM2mSingleResource [id=" + resourceId_1 + ", value=";
String expected1_0_2 = objectInstanceId_1 + "/" + resourceId_2 + "=null";
String actualValues = rpcActualResult.get("value").asText();
@ -190,8 +190,8 @@ public class RpcLwm2mIntegrationReadTest extends AbstractRpcLwM2MIntegrationTest
String actualResult = sendCompositeRPCByKeys(expectedKeys);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText());
String objectInstanceId_3 = objectInstanceIdVerToObjectInstanceId(objectInstanceIdVer_3);
String objectId_19 = objectIdVerToObjectId(objectIdVer_19);
String objectInstanceId_3 = pathIdVerToObjectId(objectInstanceIdVer_3);
String objectId_19 = pathIdVerToObjectId(objectIdVer_19);
String expected3_0_9 = objectInstanceId_3 + "/" + resourceId_9 + "=LwM2mSingleResource [id=" + resourceId_9 + ", value=";
String expected3_0_14 = objectInstanceId_3 + "/" + resourceId_14 + "=LwM2mSingleResource [id=" + resourceId_14 + ", value=";
String expected19_0_0 = objectId_19 + "/" + objectInstanceId_0 + "/" + resourceId_0 + "=null";

63
application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteAttributesTest.java

@ -0,0 +1,63 @@
/**
* Copyright © 2016-2021 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.lwm2m.rpc.sql;
import com.fasterxml.jackson.databind.node.ObjectNode;
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.server.transport.lwm2m.rpc.AbstractRpcLwM2MIntegrationTest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectInstanceId_0;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_14;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_2;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_3;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_4;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_8;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_9;
public class RpcLwm2mIntegrationWriteAttributesTest extends AbstractRpcLwM2MIntegrationTest {
/**
* WriteAttributes {"id":"/3/0/14","attributes":{"pmax":100, "pmin":10}}
* if not implemented:
* {"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 + "/" + resourceId_14;
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));
}
private String sendRPCExecuteWithValueById(String path, String value) throws Exception {
String setRpcRequest = "{\"method\": \"WriteAttributes\", \"params\": {\"id\": \"" + path + "\", \"attributes\": " + value + " }}";
return doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setRpcRequest, String.class, status().isOk());
}
}

71
application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteTest.java

@ -17,6 +17,7 @@ package org.thingsboard.server.transport.lwm2m.rpc.sql;
import com.fasterxml.jackson.databind.node.ObjectNode;
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.server.transport.lwm2m.rpc.AbstractRpcLwM2MIntegrationTest;
@ -27,18 +28,21 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.BINARY_APP_DATA_CONTAINER;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectInstanceId_0;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectInstanceId_1;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.objectInstanceId_2;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceIdName_3_14;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_0;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_14;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_15;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceId_9;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resourceInstanceId_2;
public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTest {
/**
* id
* update SingleResource:
* WriteReplace {"id":"3/0/14","value":"+12"}
* {"result":"CHANGED"}
*/
@Test
public void testWriteReplaceValueSingleResourceById_Result_CHANGED() throws Exception {
@ -57,6 +61,7 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
/**
* key
* WriteReplace {"key":"timezone","value":"+10"}
* {"result":"CHANGED"}
*/
@Test
public void testWriteReplaceValueSingleResourceByKey_Result_CHANGED() throws Exception {
@ -76,6 +81,7 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
/**
* id
* WriteReplace {"id": "/19_1.1/0/0","value": {"0":"0000ad45675600", "15":"1525ad45675600cdef"}}
* {"result":"CHANGED"}
*/
@Test
public void testWriteReplaceValueMultipleResource_Result_CHANGED_Value_Multi_Instance_Resource_must_in_Json_format() throws Exception {
@ -121,7 +127,7 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
/**
* bad - only read
* bad: singleResource, operation="R" - only read
* WriteReplace {"id":"/3/0/9","value":90}
* {"result":"METHOD_NOT_ALLOWED"}
*/
@ -137,7 +143,7 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
/**
* ids
* WriteUpdate {"id":"/3/0","value":{"14":"+5","15":"Kiyv/Europe"}}
*
* {"result":"CHANGED"}
*/
@Test
public void testWriteUpdateValueSingleResourceById_Result_CHANGED() throws Exception {
@ -165,6 +171,7 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
/**
* id
* WriteUpdate {"id": "/19_1.1/0","value": {"0":{"0":"00ad456756", "25":"25ad456756"}}}
* {"result":"CHANGED"}
*/
@Test
public void testWriteUpdateValueMultipleResourceById_Result_CHANGED() throws Exception {
@ -194,6 +201,7 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
/**
* ResourceInstance + KeySingleResource + IdSingleResource
* WriteComposite {"nodes":{"/19/1/0/2":"00001234", "UtfOffset":"+04", "/3/0/15":"Kiyv/Europe"}}
* {"result":"CHANGED"}
*/
@Test
public void testWriteCompositeValueSingleResourceResourceInstanceByIdKey_Result_CHANGED() throws Exception {
@ -246,15 +254,17 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
/**
* create_2_instances_in_object
* new ObjectInstance if Object is Multiple & Resource Single
* Create {"id":"/19/2","value":{"1":2}}
* Create {"id":"/19/3","value":{"0":{"0":"00AC", "1":"ddff12"}}}
* update_resourceInstances&update_singleResource
* new ResourceInstance if Resource is Multiple & Resource Single
* - WriteReplace {"id":"/19_1.2/1/0","value":{"2":ddff12"}}
* - WriteReplace {"key":"UtfOffset","value":"+04"}
* - WriteReplace {"id":"/3/0/15","value":"Kiyv/Europe"}
* WriteComposite {"nodes":{"/19_1.1/1/0/2":"00001234", "UtfOffset":"+04", "/3/0/15":"Kiyv/Europe"}}}
* {"result":"CHANGED"}
*/
@Test
public void testCreateObjectInstanceSingleByIdKey_Result_CHANGED() throws Exception {
int resourceInstanceId2 = 2;
String expectedPath19_1_0_2 = objectIdVer_19 + "/" + objectInstanceId_1 + "/" + resourceId_0 + "/" + resourceInstanceId2;
public void testWriteCompositeCreateResourceInstanceUpdateSingleResourceByIdKey_Result_CHANGED() throws Exception {
String expectedPath19_1_0_2 = objectIdVer_19 + "/" + objectInstanceId_1 + "/" + resourceId_0 + "/" + resourceInstanceId_2;
String expectedValue19_1_0_2 = "00001234";
String expectedKey3_0_14 = resourceIdName_3_14;
String expectedValue3_0_14 = "+04";
@ -268,7 +278,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=" + resourceInstanceId2 + ", value=" + expectedValue19_1_0_2.length()/2 + "Bytes, type=OPAQUE]";
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId_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);
@ -283,20 +293,33 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
}
/**
* failed: cannot_create_mandatory_single_object
* Create {"id":"/3/2","value":{"0":"00AC"}}
*/
/**
* failed: cannot_create_instance_of_security_object
* Create {"id":"/0/2","value":{"0":"00AC"}}
*/
/**
* failed: cannot_create_instance_of_absent_object
* Create {"id":"/50/2","value":{"0":"00AC"}}
* composite_not created_new_instance...
* new ObjectInstance if Object is Multiple - bad
* - WriteReplace {"id":"/19_1.2/2/0","value":{"2":ddff12"}}
* - WriteReplace {"key":"UtfOffset","value":"+04"}
* - WriteReplace {"id":"/3/0/15","value":"Kiyv/Europe"}
* WriteComposite {"nodes":{"/19_1.1/1/0/2":"00001234", "UtfOffset":"+04", "/3/0/15":"Kiyv/Europe"}}}
* {"result":"BAD_REQUEST","error":"object instance /19/2 not found"}
*/
@Test
public void testWriteCompositeCreateObjectInstanceUpdateSingleResourceByIdKey_Result_BAD_REQUEST() throws Exception {
String expectedPath19_1_2_2 = objectIdVer_19 + "/" + objectInstanceId_2 + "/" + resourceId_0 + "/" + resourceInstanceId_2;
String expectedValue19_1_0_2 = "00001234";
String expectedKey3_0_14 = resourceIdName_3_14;
String expectedValue3_0_14 = "+04";
String expectedPath3_0_15 = objectInstanceIdVer_3 + "/" + resourceId_15;
String expectedValue3_0_15 = "Kiyv/Europe";
String nodes = "{\"" + expectedPath19_1_2_2 + "\":\"" + expectedValue19_1_0_2 + "\", \"" + expectedKey3_0_14 +
"\":\"" + expectedValue3_0_14 + "\", \"" + expectedPath3_0_15 + "\":\"" + expectedValue3_0_15 + "\"}";
String actualResult = sendCompositeRPC(nodes);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText());
String expectedObjectId = pathIdVerToObjectId((String) expectedPath19_1_2_2);
LwM2mPath expectedPathId = new LwM2mPath(expectedObjectId);
String expected = "object instance " + "/" + expectedPathId.getObjectId() + "/" + expectedPathId.getObjectInstanceId() + " not found";
String actual = rpcActualResult.get("error").asText();
assertTrue(actual.equals(expected));
}
private String sendRPCWriteStringById(String method, String path, String value) throws Exception {
String setRpcRequest = "{\"method\": \"" + method + "\", \"params\": {\"id\": \"" + path + "\", \"value\": \"" + value + "\" }}";

6
application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/OtaLwM2MIntegrationTest.java

@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecClientCredentials;
import org.thingsboard.server.common.data.kv.KvEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus;
import org.thingsboard.server.transport.lwm2m.client.LwM2MTestClient;
import org.thingsboard.server.transport.lwm2m.security.AbstractLwM2MIntegrationTest;
@ -40,6 +41,9 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.Matchers.hasSize;
import static org.thingsboard.rest.client.utils.RestJsonConverter.toTimeseries;
import static org.thingsboard.server.common.data.ota.OtaPackageKey.CHECKSUM;
import static org.thingsboard.server.common.data.ota.OtaPackageKey.CHECKSUM_ALGORITHM;
import static org.thingsboard.server.common.data.ota.OtaPackageKey.SIZE;
import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED;
import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADING;
import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED;
@ -133,7 +137,7 @@ public class OtaLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest {
"}";
@Test
public void testFirmwareUpdateWithClientWithoutFirmwareInfo() throws Exception {
public void testFirmwareUpdateWithClientWithoutFirmwareOtaInfoFromProfile() throws Exception {
String endpoint = "WithoutFirmwareInfoDevice";
createDeviceProfile(TRANSPORT_CONFIGURATION);
NoSecClientCredentials clientCredentials = new NoSecClientCredentials();

2
common/data/src/main/java/org/thingsboard/server/common/data/device/data/lwm2m/OtherConfiguration.java

@ -33,6 +33,4 @@ public class OtherConfiguration extends PowerSavingConfiguration {
private Long pagingTransmissionWindow;
private String fwUpdateResource;
private String swUpdateResource;
private boolean compositeOperationsSupport;
}

2
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java

@ -363,7 +363,7 @@ public class LwM2mClient implements Serializable {
LwM2mPath pathIds = new LwM2mPath(fromVersionedIdToObjectId(path));
String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId());
if (verSupportedObject == null) {
return String.format("Specified resource id %s is missing from the client!", path);
return String.format("Specified object id %s absent in the list supported objects of the client or is security object!", pathIds.getObjectId());
} else {
String verRez = getVerFromPathIdVerOrId(path);
if ((verRez != null && !verRez.equals(verSupportedObject)) ||

Loading…
Cancel
Save