diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java index fd785e9de0..9f0c18b449 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -25,6 +25,8 @@ import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.util.SocketUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; @@ -65,6 +67,8 @@ import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataCmd; import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataUpdate; import org.thingsboard.server.service.telemetry.cmd.v2.LatestValueCmd; import org.thingsboard.server.transport.lwm2m.client.LwM2MTestClient; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; +import org.thingsboard.server.transport.lwm2m.server.uplink.DefaultLwM2mUplinkMsgHandler; import java.io.IOException; import java.net.ServerSocket; @@ -84,6 +88,7 @@ import static org.eclipse.californium.core.config.CoapConfig.COAP_PORT; import static org.eclipse.californium.core.config.CoapConfig.COAP_SECURE_PORT; import static org.eclipse.leshan.client.object.Security.noSec; import static org.eclipse.leshan.client.object.Security.noSecBootstap; +import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_STARTED; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_SUCCESS; @@ -97,6 +102,11 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfil @DaoSqlTest public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest { + @SpyBean + DefaultLwM2mUplinkMsgHandler defaultLwM2mUplinkMsgHandlerTest; + + @Autowired + private LwM2mClientContext clientContextTest; // Lwm2m Server public static final int port = 5685; @@ -235,7 +245,11 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest Assert.assertEquals(device.getId(), eData.get(0).getEntityId()); Assert.assertNotNull(eData.get(0).getLatest().get(EntityKeyType.TIME_SERIES)); var tsValue = eData.get(0).getLatest().get(EntityKeyType.TIME_SERIES).get("batteryLevel"); - Assert.assertEquals(42, Long.parseLong(tsValue.getValue())); + Assert.assertThat(Long.parseLong(tsValue.getValue()), instanceOf(Long.class)); + int expectedMax = 50; + int expectedMin = 5; + Assert.assertTrue(expectedMax >= Long.parseLong(tsValue.getValue())); + Assert.assertTrue(expectedMin <= Long.parseLong(tsValue.getValue())); } protected void createDeviceProfile(Lwm2mDeviceProfileTransportConfiguration transportConfiguration) throws Exception { @@ -288,7 +302,8 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest this.clientDestroy(); lwM2MTestClient = new LwM2MTestClient(this.executor, endpoint); int clientPort = SocketUtils.findAvailableUdpPort(); - lwM2MTestClient.init(security, coapConfig, clientPort, isRpc, isBootstrap, this.shortServerId, this.shortServerIdBs, securityBs); + lwM2MTestClient.init(security, coapConfig, clientPort, isRpc, isBootstrap, this.shortServerId, this.shortServerIdBs, + securityBs, this.defaultLwM2mUplinkMsgHandlerTest, this.clientContextTest); } private void clientDestroy() { @@ -298,7 +313,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest awaitClientDestroy(lwM2MTestClient.getLeshanClient()); } } catch (Exception e) { - log.error("", e); + log.error("Failed client Destroy", e); } } @@ -358,7 +373,6 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest .until(() -> isServerPortsAvailable() == null); } - private static String isServerPortsAvailable() { for (int port : SERVERS_PORT_NUMBERS) { try (ServerSocket serverSocket = new ServerSocket(port)) { diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java index f662b61d91..8ff0962811 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java @@ -46,6 +46,7 @@ public class Lwm2mTestHelper { public static final String RESOURCE_ID_NAME_3_14 = "UtfOffset"; public static final String RESOURCE_ID_NAME_19_0_0 = "dataRead"; public static final String RESOURCE_ID_NAME_19_1_0 = "dataWrite"; + public static final String RESOURCE_ID_NAME_19_0_3 = "dataDescription"; public enum LwM2MClientState { diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java index 6e055783fe..e169705f22 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java @@ -42,13 +42,20 @@ import org.eclipse.leshan.core.request.DeregisterRequest; import org.eclipse.leshan.core.request.RegisterRequest; import org.eclipse.leshan.core.request.UpdateRequest; import org.junit.Assert; +import org.mockito.Mockito; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; +import org.thingsboard.server.transport.lwm2m.server.uplink.DefaultLwM2mUplinkMsgHandler; import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; + import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY; import static org.eclipse.leshan.core.LwM2mId.ACCESS_CONTROL; @@ -105,9 +112,16 @@ public class LwM2MTestClient { private LwM2mTemperatureSensor lwM2MTemperatureSensor; private LwM2MClientState clientState; private Set clientStates; + private DefaultLwM2mUplinkMsgHandler defaultLwM2mUplinkMsgHandlerTest; + private LwM2mClientContext clientContext; - public void init(Security security, Configuration coapConfig, int port, boolean isRpc, boolean isBootstrap, int shortServerId, int shortServerIdBs, Security securityBs) throws InvalidDDFFileException, IOException { + public void init(Security security, Configuration coapConfig, int port, boolean isRpc, boolean isBootstrap, + int shortServerId, int shortServerIdBs, Security securityBs, + DefaultLwM2mUplinkMsgHandler defaultLwM2mUplinkMsgHandler, + LwM2mClientContext clientContext) throws InvalidDDFFileException, IOException { Assert.assertNull("client already initialized", leshanClient); + this.defaultLwM2mUplinkMsgHandlerTest = defaultLwM2mUplinkMsgHandler; + this.clientContext = clientContext; List models = new ArrayList<>(); for (String resourceName : resources) { models.addAll(ObjectLoader.loadDdfFile(LwM2MTestClient.class.getClassLoader().getResourceAsStream("lwm2m/" + resourceName), resourceName)); @@ -138,7 +152,7 @@ public class LwM2MTestClient { initializer.setInstancesForObject(SERVER, instances); } } - initializer.setInstancesForObject(DEVICE, lwM2MDevice = new SimpleLwM2MDevice()); + initializer.setInstancesForObject(DEVICE, lwM2MDevice = new SimpleLwM2MDevice(executor)); initializer.setInstancesForObject(FIRMWARE, fwLwM2MDevice = new FwLwM2MDevice()); initializer.setInstancesForObject(SOFTWARE_MANAGEMENT, swLwM2MDevice = new SwLwM2MDevice()); initializer.setClassForObject(ACCESS_CONTROL, DummyInstanceEnabler.class); @@ -277,7 +291,7 @@ public class LwM2MTestClient { this.leshanClient.addObserver(observer); if (!isRpc) { - leshanClient.start(); + this.start(true); } } @@ -294,7 +308,7 @@ public class LwM2MTestClient { if (lwm2mServerBs != null) { lwm2mServerBs = null; } - if (lwm2mServer != null) { + if (lwm2mServer != null) { lwm2mServer = null; } if (lwM2MDevice != null) { @@ -314,9 +328,29 @@ public class LwM2MTestClient { } } - public void start() { + public void start(boolean isStartLw) { if (leshanClient != null) { leshanClient.start(); + if (isStartLw) { + this.awaitClientAfterStartConnectLw(); + } + } + } + + private void awaitClientAfterStartConnectLw() { + LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(endpoint); + CountDownLatch latch = new CountDownLatch(1); + Mockito.doAnswer(invocation -> { + latch.countDown(); + return null; + }).when(defaultLwM2mUplinkMsgHandlerTest).initAttributes(lwM2MClient, true); + + try { + if (!latch.await(1, TimeUnit.SECONDS)) { + throw new RuntimeException("Failed to await TimeOut lwm2m client initialization!"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Exception Failed to await lwm2m client initialization! ", e); } } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2mBinaryAppDataContainer.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2mBinaryAppDataContainer.java index a88c795f9c..797a5da2e3 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2mBinaryAppDataContainer.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2mBinaryAppDataContainer.java @@ -173,7 +173,8 @@ public class LwM2mBinaryAppDataContainer extends BaseInstanceEnabler implements } private String getDescription() { - return this.description == null ? "meter reading" : this.description; +// return this.description == null ? "meter reading" : this.description; + return this.description; } private void setTimestamp(long time) { @@ -203,6 +204,10 @@ public class LwM2mBinaryAppDataContainer extends BaseInstanceEnabler implements } private Map getData() { + if (data == null) { + this.data = new HashMap<>(); + this.data.put(0, new byte[]{(byte) 0xAC}); + } return data; } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/SimpleLwM2MDevice.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/SimpleLwM2MDevice.java index 37d93279bf..ffd3df0a09 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/SimpleLwM2MDevice.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/SimpleLwM2MDevice.java @@ -32,16 +32,39 @@ import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.PrimitiveIterator; import java.util.Random; import java.util.TimeZone; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; @Slf4j public class SimpleLwM2MDevice extends BaseInstanceEnabler implements Destroyable { private static final Random RANDOM = new Random(); + private static final int min = 5; + private static final int max = 50; + private static final PrimitiveIterator.OfInt randomIterator = new Random().ints(min,max + 1).iterator(); private static final List supportedResources = Arrays.asList(0, 1, 2, 3, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21); + + public SimpleLwM2MDevice() { + } + + public SimpleLwM2MDevice(ScheduledExecutorService executorService) { + try { + executorService.scheduleWithFixedDelay(() -> { + fireResourceChange(9); + } + , 1800000, 1800000, TimeUnit.MILLISECONDS); // 30 MIN + } catch (Throwable e) { + log.error("[{}]Throwable", e.toString()); + e.printStackTrace(); + } + } + + @Override public ReadResponse read(ServerIdentity identity, int resourceId) { if (!identity.isSystem()) @@ -135,7 +158,8 @@ public class SimpleLwM2MDevice extends BaseInstanceEnabler implements Destroyabl } private int getBatteryLevel() { - return 42; + return randomIterator.nextInt(); +// return 42; } private long getMemoryFree() { diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/ota/sql/OtaLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/ota/sql/OtaLwM2MIntegrationTest.java index e572b854b5..8173b39b5c 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/ota/sql/OtaLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/ota/sql/OtaLwM2MIntegrationTest.java @@ -100,9 +100,6 @@ public class OtaLwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest { LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(this.CLIENT_ENDPOINT_WITHOUT_FW_INFO)); final Device device = createDevice(deviceCredentials, this.CLIENT_ENDPOINT_WITHOUT_FW_INFO); createNewClient(SECURITY_NO_SEC, COAP_CONFIG, false, this.CLIENT_ENDPOINT_WITHOUT_FW_INFO, false, null); - - Thread.sleep(1000); - device.setFirmwareId(createFirmware().getId()); final Device savedDevice = doPost("/api/device", device, Device.class); @@ -126,9 +123,6 @@ public class OtaLwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest { LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(this.CLIENT_ENDPOINT_OTA5)); final Device device = createDevice(deviceCredentials, this.CLIENT_ENDPOINT_OTA5); createNewClient(SECURITY_NO_SEC, COAP_CONFIG, false, this.CLIENT_ENDPOINT_OTA5, false, null); - - Thread.sleep(1000); - device.setFirmwareId(createFirmware().getId()); final Device savedDevice = doPost("/api/device", device, Device.class); diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java index 669d8de55a..28fd86a383 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java @@ -60,7 +60,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg 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)); + private static final Predicate PREDICATE_3 = path -> (!((String) path).startsWith("/" + TEMPERATURE_SENSOR) && ((String) path).startsWith("/" + DEVICE)); protected String objectIdVer_3; protected String objectInstanceIdVer_3; protected String objectInstanceIdVer_5; @@ -70,6 +70,8 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg protected String objectIdVer_3303; protected static AtomicInteger endpointSequence = new AtomicInteger(); protected static String DEVICE_ENDPOINT_RPC_PREF = "deviceEndpointRpc"; + protected String idVer_3_0_9; + protected String idVer_19_0_0; public AbstractRpcLwM2MIntegrationTest() { setResources(resources); @@ -90,9 +92,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg lwM2MTestClient.getLeshanClient().getObjectTree().getObjectEnablers().forEach((key, val) -> { if (key > 0) { String objectVerId = "/" + key; - if (!val.getObjectModel().version.equals("1.0")) { - objectVerId += ("_" + val.getObjectModel().version); - } + objectVerId += ("_" + val.getObjectModel().version); expectedObjects.add("/" + key); expectedObjectIdVers.add(objectVerId); String finalObjectVerId = objectVerId; @@ -103,38 +103,37 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg } }); String ver_Id_0 = lwM2MTestClient.getLeshanClient().getObjectTree().getModel().getObjectModel(OBJECT_ID_0).version; - if ("1.0".equals(ver_Id_0)) { - objectIdVer_0 = "/" + OBJECT_ID_0; - } else { - objectIdVer_0 = "/" + OBJECT_ID_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) 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(); + objectIdVer_0 = "/" + OBJECT_ID_0 + "_" + ver_Id_0; + objectIdVer_2 = (String) expectedObjectIdVers.stream().filter(path -> ((String) path).startsWith("/" + ACCESS_CONTROL)).findFirst().get(); + objectIdVer_3 = (String) expectedObjectIdVers.stream().filter(PREDICATE_3).findFirst().get(); + objectIdVer_19 = (String) expectedObjectIdVers.stream().filter(path -> ((String) path).startsWith("/" + BINARY_APP_DATA_CONTAINER)).findFirst().get(); + objectIdVer_3303 = (String) expectedObjectIdVers.stream().filter(path -> ((String) path).startsWith("/" + TEMPERATURE_SENSOR)).findFirst().get(); + objectInstanceIdVer_1 = (String) expectedObjectIdVerInstances.stream().filter(path -> (!((String) path).startsWith("/" + BINARY_APP_DATA_CONTAINER) && ((String) path).startsWith("/" + 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(); - objectInstanceIdVer_9 = (String) expectedObjectIdVerInstances.stream().filter(path -> ((String) path).contains("/" + SOFTWARE_MANAGEMENT)).findFirst().get(); + objectInstanceIdVer_5 = (String) expectedObjectIdVerInstances.stream().filter(path -> ((String) path).startsWith("/" + FIRMWARE)).findFirst().get(); + objectInstanceIdVer_9 = (String) expectedObjectIdVerInstances.stream().filter(path -> ((String) path).startsWith("/" + SOFTWARE_MANAGEMENT)).findFirst().get(); + + idVer_3_0_9 = objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_9; + idVer_19_0_0 = objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0; OBSERVE_ATTRIBUTES_WITH_PARAMS_RPC = " {\n" + " \"keyName\": {\n" + - " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_9 + "\": \"" + RESOURCE_ID_NAME_3_9 + "\",\n" + + " \"" + idVer_3_0_9 + "\": \"" + RESOURCE_ID_NAME_3_9 + "\",\n" + " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_14 + "\": \"" + RESOURCE_ID_NAME_3_14 + "\",\n" + - " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0 + "\": \"" + RESOURCE_ID_NAME_19_0_0 + "\",\n" + + " \"" + idVer_19_0_0 + "\": \"" + RESOURCE_ID_NAME_19_0_0 + "\",\n" + " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_1 + "/" + RESOURCE_ID_0 + "\": \"" + RESOURCE_ID_NAME_19_1_0 + "\"\n" + " },\n" + " \"observe\": [\n" + - " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_9 + "\",\n" + - " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0 + "\"\n" + + " \"" + idVer_3_0_9 + "\",\n" + + " \"" + idVer_19_0_0 + "\"\n" + " ],\n" + " \"attribute\": [\n" + + " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_14 + "\"\n" + " ],\n" + " \"telemetry\": [\n" + - " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_9 + "\",\n" + - " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_14 + "\",\n" + - " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0 + "\",\n" + + " \"" + idVer_3_0_9 + "\",\n" + + " \"" + idVer_19_0_0 + "\",\n" + " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_1 + "/" + RESOURCE_ID_0 + "\"\n" + " ],\n" + " \"attributeLwm2m\": {}\n" + @@ -147,7 +146,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg final Device device = createDevice(deviceCredentials, endpoint); deviceId = device.getId().getId().toString(); - lwM2MTestClient.start(); + lwM2MTestClient.start(true); } protected String pathIdVerToObjectId(String pathIdVer) { diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationExecuteTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationExecuteTest.java index cd016de5ba..073a9fa8ed 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationExecuteTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationExecuteTest.java @@ -121,8 +121,8 @@ public class RpcLwm2mIntegrationExecuteTest extends AbstractRpcLwM2MIntegrationT /** * bad: resource operation not "E" - * Execute {"id":"5/0/3"} - * {"result":"BAD_REQUEST","error":"Resource with /5/0/3 is not executable."} + * Execute {"id":"5_1.0/0/3"} + * {"result":"BAD_REQUEST","error":"Resource with /5_1.0/0/3 is not executable."} */ @Test public void testExecuteResourceWithOperationNotExecuteById_Result_METHOD_NOT_ALLOWED() throws Exception { @@ -130,8 +130,7 @@ public class RpcLwm2mIntegrationExecuteTest extends AbstractRpcLwM2MIntegrationT 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 expected = "Resource with " + expectedPath + " is not executable."; String actual = rpcActualResult.get("error").asText(); assertTrue(actual.equals(expected)); } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationObserveTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationObserveTest.java index d9631928a7..77d6e6cfab 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationObserveTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationObserveTest.java @@ -26,11 +26,11 @@ import static org.eclipse.leshan.core.LwM2mId.ACCESS_CONTROL; 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.BINARY_APP_DATA_CONTAINER; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INSTANCE_ID_0; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_0; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_14; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_3; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_9; +import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.fromVersionedIdToObjectId; public class RpcLwm2mIntegrationObserveTest extends AbstractRpcLwM2MIntegrationTest { @@ -40,23 +40,42 @@ public class RpcLwm2mIntegrationObserveTest extends AbstractRpcLwM2MIntegrationT */ @Test public void testObserveReadAllNothingObservation_Result_CONTENT_Value_Count_0() throws Exception { + String actualResultBefore = sendObserve("ObserveReadAll", null); + ObjectNode rpcActualResultBefore = JacksonUtil.fromString(actualResultBefore, ObjectNode.class); + assertEquals(ResponseCode.CONTENT.getName(), rpcActualResultBefore.get("result").asText()); + assertTrue(rpcActualResultBefore.get("value").asText().contains(fromVersionedIdToObjectId(idVer_3_0_9))); + assertTrue(rpcActualResultBefore.get("value").asText().contains(fromVersionedIdToObjectId(idVer_19_0_0))); String actualResult = sendObserve("ObserveCancelAll", null); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText()); - actualResult = sendObserve("ObserveReadAll", null); - rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); - assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText()); - assertEquals("[]", rpcActualResult.get("value").asText()); + assertEquals("2", rpcActualResult.get("value").asText()); + String actualResultAfter = sendObserve("ObserveReadAll", null); + ObjectNode rpcActualResultAfter = JacksonUtil.fromString(actualResultAfter, ObjectNode.class); + assertEquals(ResponseCode.CONTENT.getName(), rpcActualResultAfter.get("result").asText()); + String expectResultAfter = "[]"; + assertEquals( expectResultAfter, rpcActualResultAfter.get("value").asText()); } /** - * Observe {"id":"/3/0/9"} + * Observe {"id":"/3/0/0"} * @throws Exception */ @Test - public void testObserveSingleResource_Result_CONTENT_Value_SingleResource() throws Exception { - String expectedIdVer = objectInstanceIdVer_3 + "/" + RESOURCE_ID_9; - String actualResult = sendObserve("Observe", expectedIdVer); + public void testObserveSingleResourceWithout_IdVer_1_0_Result_CONTENT_Value_SingleResource() throws Exception { + String expectedId = objectInstanceIdVer_3 + "/" + RESOURCE_ID_0; + String actualResult = sendObserve("Observe", fromVersionedIdToObjectId(expectedId)); + ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); + assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText()); + assertTrue(rpcActualResult.get("value").asText().contains("LwM2mSingleResource")); + } + /** + * Observe {"id":"/3_1.0/0/14"} + * @throws Exception + */ + @Test + public void testObserveSingleResourceWith_IdVer_1_0_Result_CONTENT_Value_SingleResource() throws Exception { + String expectedId = objectInstanceIdVer_3 + "/" + RESOURCE_ID_14; + String actualResult = sendObserve("Observe", expectedId); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText()); assertTrue(rpcActualResult.get("value").asText().contains("LwM2mSingleResource")); @@ -100,11 +119,10 @@ public class RpcLwm2mIntegrationObserveTest extends AbstractRpcLwM2MIntegrationT */ @Test public void testObserveNoImplementedResourceOnDeviceValueNull_Result_BadRequest() throws Exception { - String objectIdVer = (String) expectedObjectIdVers.stream().filter(path -> ((String)path).contains("/" + BINARY_APP_DATA_CONTAINER)).findFirst().get(); - String expected = objectIdVer + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0; + String expected = objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_3; String actualResult = sendObserve("Observe", expected); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); - String expectedValue = "values MUST NOT be null"; + String expectedValue = "value MUST NOT be null"; assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText()); assertEquals(expectedValue, rpcActualResult.get("error").asText()); } @@ -125,14 +143,12 @@ public class RpcLwm2mIntegrationObserveTest extends AbstractRpcLwM2MIntegrationT /** * Repeated request on Observe - * Observe {"id":"/3/0/0"} + * Observe {"id":"/3/0/9"} * @throws Exception */ @Test public void testObserveRepeatedRequestObserveOnDevice_Result_BAD_REQUEST_ErrorMsg_AlreadyRegistered() throws Exception { - String expectedId = objectInstanceIdVer_3 + "/" + RESOURCE_ID_0; - sendObserve("Observe", expectedId); - String actualResult = sendObserve("Observe", expectedId); + String actualResult = sendObserve("Observe", idVer_3_0_9); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText()); String expected = "Observation is already registered!"; @@ -144,18 +160,18 @@ public class RpcLwm2mIntegrationObserveTest extends AbstractRpcLwM2MIntegrationT * @throws Exception */ @Test - public void testObserveReadAll_Result_CONTENT_Value_Contains_Paths_Count_ObserveAll() throws Exception { - sendObserve("ObserveCancelAll", null); - String expectedId_0 = objectInstanceIdVer_3 + "/" + RESOURCE_ID_0; - String expectedId_9 = objectInstanceIdVer_3 + "/" + RESOURCE_ID_9; - sendObserve("Observe", expectedId_0); - sendObserve("Observe", expectedId_9); + public void testObserveReadAll_Result_CONTENT_Value_Contains_Paths_Count_ObserveReadAll() throws Exception { + String actualResultCancel = sendObserve("ObserveCancelAll", null); + ObjectNode rpcActualResultCancel = JacksonUtil.fromString(actualResultCancel, ObjectNode.class); + assertEquals(ResponseCode.CONTENT.getName(), rpcActualResultCancel.get("result").asText()); + sendObserve("Observe",idVer_19_0_0); + sendObserve("Observe", idVer_3_0_9); String actualResult = sendObserve("ObserveReadAll", null); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText()); String actualValues = rpcActualResult.get("value").asText(); - assertTrue(actualValues.contains(expectedId_0)); - assertTrue(actualValues.contains(expectedId_9)); + assertTrue(actualValues.contains(fromVersionedIdToObjectId(idVer_19_0_0))); + assertTrue(actualValues.contains(fromVersionedIdToObjectId(idVer_3_0_9))); assertEquals(2, actualValues.split(",").length); } @@ -167,11 +183,11 @@ public class RpcLwm2mIntegrationObserveTest extends AbstractRpcLwM2MIntegrationT @Test public void testObserveCancelOneResource_Result_CONTENT_Value_Count_1() throws Exception { sendObserve("ObserveCancelAll", null); - String expectedId_0 = objectInstanceIdVer_3 + "/" + RESOURCE_ID_0; - String expectedId_3 = objectInstanceIdVer_5 + "/" + RESOURCE_ID_3; - sendObserve("Observe", expectedId_0); - sendObserve("Observe", expectedId_3); - String actualResult = sendObserve("ObserveCancel", expectedId_0); + String expectedId_3_0_3 = objectInstanceIdVer_3 + "/" + RESOURCE_ID_3; + String expectedId_5_0_3 = objectInstanceIdVer_5 + "/" + RESOURCE_ID_3; + sendObserve("Observe", expectedId_3_0_3); + sendObserve("Observe", expectedId_5_0_3); + String actualResult = sendObserve("ObserveCancel", expectedId_3_0_3); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText()); assertEquals("1", rpcActualResult.get("value").asText()); diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationReadTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationReadTest.java index 4b13c8d757..404bbdc545 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationReadTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationReadTest.java @@ -30,6 +30,7 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.BINARY_APP_ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INSTANCE_ID_0; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INSTANCE_ID_1; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_NAME_19_0_0; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_NAME_19_0_3; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_NAME_19_1_0; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_NAME_3_14; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_NAME_3_9; @@ -181,11 +182,12 @@ public class RpcLwm2mIntegrationReadTest extends AbstractRpcLwM2MIntegrationTest * ReadComposite {"keys":["batteryLevel", "UtfOffset", "dataRead", "dataWrite"]} */ @Test - public void testReadCompositeSingleResourceByKeys_Result_CONTENT_Value_3_0_IsLwM2mSingleResource_19_0_0_AND_19_0_1_Null() throws Exception { + public void testReadCompositeSingleResourceByKeys_Result_CONTENT_Value_3_0_IsLwM2mSingleResource_19_0_0_AND_19_0_1__IsLwM2mMultipleResource() throws Exception { String expectedKey3_0_9 = RESOURCE_ID_NAME_3_9; String expectedKey3_0_14 = RESOURCE_ID_NAME_3_14; String expectedKey19_0_0 = RESOURCE_ID_NAME_19_0_0; String expectedKey19_1_0 = RESOURCE_ID_NAME_19_1_0; + String expectedKey19_X_0 = "=LwM2mMultipleResource [id=0, values={0=LwM2mResourceInstance [id=0, value=1Bytes, type=OPAQUE]"; String expectedKeys = "[\"" + expectedKey3_0_9 + "\", \"" + expectedKey3_0_14 + "\", \"" + expectedKey19_0_0 + "\", \"" + expectedKey19_1_0 + "\"]"; String actualResult = sendCompositeRPCByKeys(expectedKeys); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); @@ -194,8 +196,8 @@ public class RpcLwm2mIntegrationReadTest extends AbstractRpcLwM2MIntegrationTest String objectId_19 = pathIdVerToObjectId(objectIdVer_19); String expected3_0_9 = objectInstanceId_3 + "/" + RESOURCE_ID_9 + "=LwM2mSingleResource [id=" + RESOURCE_ID_9 + ", value="; String expected3_0_14 = objectInstanceId_3 + "/" + RESOURCE_ID_14 + "=LwM2mSingleResource [id=" + RESOURCE_ID_14 + ", value="; - String expected19_0_0 = objectId_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0 + "=null"; - String expected19_1_0 = objectId_19 + "/" + OBJECT_INSTANCE_ID_1 + "/" + RESOURCE_ID_0 + "=null"; + String expected19_0_0 = objectId_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0 + expectedKey19_X_0; + String expected19_1_0 = objectId_19 + "/" + OBJECT_INSTANCE_ID_1 + "/" + RESOURCE_ID_0 + expectedKey19_X_0; String actualValues = rpcActualResult.get("value").asText(); assertTrue(actualValues.contains(expected3_0_9)); assertTrue(actualValues.contains(expected3_0_14)); @@ -203,6 +205,23 @@ public class RpcLwm2mIntegrationReadTest extends AbstractRpcLwM2MIntegrationTest assertTrue(actualValues.contains(expected19_1_0)); } + /** + * ReadComposite {"keys":["batteryLevel", "UtfOffset", "dataDescription"]} + */ + @Test + public void testReadCompositeSingleResourceByKeys_Result_CONTENT_Value_3_0_IsLwM2mSingleResource_19_0_3_IsNotConfiguredInTheDeviceProfile() throws Exception { + String expectedKey3_0_9 = RESOURCE_ID_NAME_3_9; + String expectedKey3_0_14 = RESOURCE_ID_NAME_3_14; + String expectedKey19_0_3 = RESOURCE_ID_NAME_19_0_3; + String expectedKeys = "[\"" + expectedKey3_0_9 + "\", \"" + expectedKey3_0_14 + "\", \"" + expectedKey19_0_3 + "\"]"; + String actualResult = sendCompositeRPCByKeys(expectedKeys); + ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); + assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText()); + String actualValue = rpcActualResult.get("error").asText(); + String expectedValue = expectedKey19_0_3 + " is not configured in the device profile!"; + assertEquals(actualValue, expectedValue); + } + private String sendRPCById(String path) throws Exception { String setRpcRequest = "{\"method\": \"Read\", \"params\": {\"id\": \"" + path + "\"}}"; diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java index fa4b601ed0..e357b23afe 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java @@ -15,10 +15,12 @@ */ package org.thingsboard.server.transport.lwm2m.security; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import org.eclipse.californium.elements.config.Configuration; import org.eclipse.leshan.client.object.Security; +import org.eclipse.leshan.core.ResponseCode; import org.eclipse.leshan.core.util.Hex; import org.junit.Assert; import org.springframework.test.web.servlet.MvcResult; @@ -61,6 +63,7 @@ import java.util.concurrent.TimeUnit; import static org.awaitility.Awaitility.await; import static org.eclipse.leshan.client.object.Security.noSecBootstap; +import static org.junit.Assert.assertEquals; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_STARTED; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_SUCCESS; @@ -173,7 +176,8 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M awaitAlias, expectedStatuses, true, - finishState); + finishState, + false); } protected void basicTestConnection(Security security, @@ -184,13 +188,13 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M String awaitAlias, Set expectedStatuses, boolean isBootstrap, - LwM2MClientState finishState) throws Exception { + LwM2MClientState finishState, + boolean isStartLw) throws Exception { createNewClient(security, coapConfig, true, endpoint, isBootstrap, null); createDeviceProfile(transportConfiguration); final Device device = createDevice(deviceCredentials, endpoint); device.getId().getId().toString(); - lwM2MTestClient.start(); - + lwM2MTestClient.start(isStartLw); await(awaitAlias) .atMost(1000, TimeUnit.MILLISECONDS) .until(() -> finishState.equals(lwM2MTestClient.getClientState())); @@ -228,15 +232,17 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M createDeviceProfile(transportConfiguration); final Device device = createDevice(deviceCredentials, endpoint); String deviceId = device.getId().getId().toString(); - lwM2MTestClient.start(); - + lwM2MTestClient.start(true); await(awaitAlias) .atMost(1000, TimeUnit.MILLISECONDS) .until(() -> ON_REGISTRATION_SUCCESS.equals(lwM2MTestClient.getClientState())); Assert.assertEquals(expectedStatusesLwm2m, lwM2MTestClient.getClientStates()); - String executedPath = getObjectIdVer_1() + "/0/" + RESOURCE_ID_9; - sendRPCSecurityExecuteById(executedPath, deviceId, endpoint); + String executedPath = "/" + OBJECT_ID_1 + "_" + lwM2MTestClient.getLeshanClient().getObjectTree().getModel().getObjectModel(OBJECT_ID_1).version + + "/0/" + RESOURCE_ID_9; + String actualResult = sendRPCSecurityExecuteById(executedPath, deviceId, endpoint); + ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); + assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText()); expectedStatusesBs.add(ON_DEREGISTRATION_STARTED); expectedStatusesBs.add(ON_DEREGISTRATION_SUCCESS); await(awaitAlias) @@ -398,15 +404,4 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M String setRpcRequest = "{\"method\": \"Execute\", \"params\": {\"id\": \"" + path + "\"}}"; return doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setRpcRequest, String.class, status().isOk()); } - - private String getObjectIdVer_1() { - String ver_Id_0 = lwM2MTestClient.getLeshanClient().getObjectTree().getModel().getObjectModel(OBJECT_ID_1).version; - String objectIdVer_1; - if ("1.0".equals(ver_Id_0)) { - objectIdVer_1 = "/" + OBJECT_ID_1; - } else { - objectIdVer_1 = "/" + OBJECT_ID_1 + "_" + ver_Id_0; - } - return objectIdVer_1; - } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/NoSecLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/NoSecLwM2MIntegrationTest.java index 345902aa6e..203b1f56c7 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/NoSecLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/NoSecLwM2MIntegrationTest.java @@ -66,28 +66,28 @@ public class NoSecLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationT } @Test - public void testWithNoSecBootstrapRequestTriggerConnectBsSuccess_UpdateTwoSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { + public void testWithNoSecConnectLwm2mSuccessBootstrapRequestTriggerConnectBsSuccess_UpdateTwoSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { String clientEndpoint = CLIENT_ENDPOINT_NO_SEC_BS + "Trigger" + BOTH.name(); String awaitAlias = "await on client state (NoSecBS Trigger Two section)"; basicTestConnectionBootstrapRequestTriggerBefore(clientEndpoint, awaitAlias, BOTH); } @Test - public void testWithNoSecBootstrapRequestTriggerConnectBsSuccess_UpdateBootstrapSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { + public void testWithNoSecConnectLwm2mSuccessBootstrapRequestTriggerConnectBsSuccess_UpdateBootstrapSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { String clientEndpoint = CLIENT_ENDPOINT_NO_SEC_BS + "Trigger" + BOOTSTRAP_ONLY.name(); String awaitAlias = "await on client state (NoSecBS Trigger Bootstrap section)"; basicTestConnectionBootstrapRequestTriggerBefore(clientEndpoint, awaitAlias, BOOTSTRAP_ONLY); } @Test - public void testWithNoSecBootstrapRequestTriggerConnectBsSuccess_UpdateLwm2mSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { + public void testWithNoSecConnectLwm2mSuccessBootstrapRequestTriggerConnectBsSuccess_UpdateLwm2mSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { String clientEndpoint = CLIENT_ENDPOINT_NO_SEC_BS + "Trigger" + LWM2M_ONLY.name(); String awaitAlias = "await on client state (NoSecBS Trigger Lwm2m section)"; basicTestConnectionBootstrapRequestTriggerBefore(clientEndpoint, awaitAlias, LWM2M_ONLY); } @Test - public void testWithNoSecBootstrapRequestTriggerConnectBsSuccess_UpdateNoneSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { + public void testWithNoSecConnectLwm2mSuccessBootstrapRequestTriggerConnectBsSuccess_UpdateNoneSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { String clientEndpoint = CLIENT_ENDPOINT_NO_SEC_BS + "Trigger" + NONE.name(); String awaitAlias = "await on client state (NoSecBS Trigger None section)"; basicTestConnectionBootstrapRequestTriggerBefore(clientEndpoint, awaitAlias, NONE); diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java index feff1ee926..7eeb4b4090 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java @@ -62,7 +62,8 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes "await on client state (Psk_Lwm2m)", expectedStatusesRegistrationLwm2mSuccess, false, - ON_REGISTRATION_SUCCESS); + ON_REGISTRATION_SUCCESS, + true); } @Test @@ -107,6 +108,7 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes "await on client state (PskBS two section)", expectedStatusesRegistrationBsSuccess, true, - ON_REGISTRATION_SUCCESS); + ON_REGISTRATION_SUCCESS, + true); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java index cfc55fae9a..16c34550c2 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java @@ -64,7 +64,8 @@ public class RpkLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTes "await on client state (Rpk_Lwm2m)", expectedStatusesRegistrationLwm2mSuccess, false, - ON_REGISTRATION_SUCCESS); + ON_REGISTRATION_SUCCESS, + true); } @Test @@ -124,6 +125,7 @@ public class RpkLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTes "await on client state (RpkBS two section)", expectedStatusesRegistrationBsSuccess, true, - ON_REGISTRATION_SUCCESS); + ON_REGISTRATION_SUCCESS, + true); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java index 6e9dc615e5..57e26c060e 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java @@ -64,7 +64,8 @@ public class X509_NoTrustLwM2MIntegrationTest extends AbstractSecurityLwM2MInteg "await on client state (X509_Trust_Lwm2m)", expectedStatusesRegistrationLwm2mSuccess, false, - ON_REGISTRATION_SUCCESS); + ON_REGISTRATION_SUCCESS, + true); } @Test @@ -124,6 +125,7 @@ public class X509_NoTrustLwM2MIntegrationTest extends AbstractSecurityLwM2MInteg "await on client state (X509NoTrust two section)", expectedStatusesRegistrationBsSuccess, true, - ON_REGISTRATION_SUCCESS); + ON_REGISTRATION_SUCCESS, + true); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java index 59c7360d20..cd0cec1c16 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java @@ -58,7 +58,8 @@ public class X509_TrustLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegra "await on client state (X509_Trust_Lwm2m)", expectedStatusesRegistrationLwm2mSuccess, false, - ON_REGISTRATION_SUCCESS); + ON_REGISTRATION_SUCCESS, + true); } // Bootstrap + Lwm2m @@ -84,6 +85,7 @@ public class X509_TrustLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegra "await on client state (X509Trust two section)", expectedStatusesRegistrationBsSuccess, true, - ON_REGISTRATION_SUCCESS); + ON_REGISTRATION_SUCCESS, + true); } } diff --git a/application/src/test/resources/logback.xml b/application/src/test/resources/logback-test.xml similarity index 100% rename from application/src/test/resources/logback.xml rename to application/src/test/resources/logback-test.xml diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java index 9b04efa646..fddd8ad946 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java @@ -297,11 +297,22 @@ public class LwM2mClient implements Serializable { } public ObjectModel getObjectModel(String pathIdVer, LwM2mModelProvider modelProvider) { - LwM2mPath pathIds = new LwM2mPath(fromVersionedIdToObjectId(pathIdVer)); - String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId()); - String verRez = getVerFromPathIdVerOrId(pathIdVer); - return verRez != null && verRez.equals(verSupportedObject) ? modelProvider.getObjectModel(registration) - .getObjectModel(pathIds.getObjectId()) : null; + try { + LwM2mPath pathIds = new LwM2mPath(fromVersionedIdToObjectId(pathIdVer)); + String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId()); + String verRez = getVerFromPathIdVerOrId(pathIdVer); + return verRez != null && verRez.equals(verSupportedObject) ? modelProvider.getObjectModel(registration) + .getObjectModel(pathIds.getObjectId()) : null; + } catch (Exception e) { + if (registration == null) { + log.error("[{}] Failed Registration is null, GetObjectModelRegistration. ", this.endpoint, e); + } else if (registration.getSupportedObject() == null) { + log.error("[{}] Failed SupportedObject in Registration, GetObjectModelRegistration.", this.endpoint, e); + } else { + log.error("[{}] Failed ModelProvider.getObjectModel [{}] in Registration. ", this.endpoint, registration.getSupportedObject(), e); + } + return null; + } } @@ -423,7 +434,7 @@ public class LwM2mClient implements Serializable { private ContentFormat calculateDefaultContentFormat(Registration registration) { if (registration == null) { return ContentFormat.DEFAULT; - } else{ + } else { return TbLwM2mVersion.fromVersion(registration.getLwM2mVersion()).getContentFormat(); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java index a4c92de9b1..c489c28b31 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java @@ -374,6 +374,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { } private Lwm2mDeviceProfileTransportConfiguration doGetAndCache(UUID profileId) { + Lwm2mDeviceProfileTransportConfiguration result = profiles.get(profileId); if (result == null) { log.debug("Fetching profile [{}]", profileId); @@ -381,7 +382,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { if (deviceProfile != null) { result = profileUpdate(deviceProfile); } else { - log.info("Device profile was not found! Most probably device profile [{}] has been removed from the database.", profileId); + log.warn("Device profile was not found! Most probably device profile [{}] has been removed from the database.", profileId); } } return result; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2mUplinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2mUplinkMsgHandler.java index 283f1d852c..05ce126c7e 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2mUplinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2mUplinkMsgHandler.java @@ -486,7 +486,7 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl new TbLwM2MLatchCallback<>(latch, new TbLwM2MReadCallback(this, logService, lwM2MClient, versionedId)))); latch.await(); } catch (InterruptedException e) { - log.error("[{}] Failed to await Read requests!", lwM2MClient.getEndpoint()); + log.error("[{}] Failed to await Read requests!", lwM2MClient.getEndpoint(), e); } catch (Exception e) { log.error("[{}] Failed to process read requests!", lwM2MClient.getEndpoint(), e); logService.log(lwM2MClient, "Failed to process read requests. Possible profile misconfiguration."); @@ -504,7 +504,7 @@ public class DefaultLwM2mUplinkMsgHandler extends LwM2MExecutorAwareService impl latch.await(); } catch (InterruptedException e) { - log.error("[{}] Failed to await Observe requests!", lwM2MClient.getEndpoint()); + log.error("[{}] Failed to await Observe requests!", lwM2MClient.getEndpoint(), e); } catch (Exception e) { log.error("[{}] Failed to process observe requests!", lwM2MClient.getEndpoint(), e); logService.log(lwM2MClient, "Failed to process observe requests. Possible profile misconfiguration.");