From 29a551d048538e94819954601d2b34925a2c75c9 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Fri, 4 Feb 2022 15:59:12 +0200 Subject: [PATCH] lwm2m: fix bug: add afterClass "await (3 sec, closed all ports lwm2server and bootstrapServer)" --- .../lwm2m/AbstractLwM2MIntegrationTest.java | 82 ++++-- .../transport/lwm2m/Lwm2mTestHelper.java | 27 -- .../lwm2m/client/LwM2MTestClient.java | 32 +-- .../transport/lwm2m/client/Lwm2mServer.java | 235 ++++++++++++++++++ .../rpc/AbstractRpcLwM2MIntegrationTest.java | 14 +- .../sql/RpcLwm2mIntegrationDiscoverTest.java | 2 +- .../sql/RpcLwm2mIntegrationObserveTest.java | 2 +- .../AbstractSecurityLwM2MIntegrationTest.java | 43 +--- .../LwM2MTransportBootstrapService.java | 10 +- ...LwM2MBootstrapConfigStoreTaskProvider.java | 2 +- .../server/DefaultLwM2mTransportService.java | 10 +- .../lwm2m/server/LwM2MNetworkConfig.java | 10 - 12 files changed, 347 insertions(+), 122 deletions(-) create mode 100644 application/src/test/java/org/thingsboard/server/transport/lwm2m/client/Lwm2mServer.java 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 a3468166bc..fd785e9de0 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 @@ -19,8 +19,10 @@ import com.fasterxml.jackson.core.type.TypeReference; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.eclipse.californium.elements.config.Configuration; +import org.eclipse.leshan.client.californium.LeshanClient; import org.eclipse.leshan.client.object.Security; import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.springframework.util.SocketUtils; @@ -64,6 +66,8 @@ 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 java.io.IOException; +import java.net.ServerSocket; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; @@ -73,7 +77,9 @@ import java.util.List; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import static org.awaitility.Awaitility.await; 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; @@ -97,6 +103,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest public static final int securityPort = 5686; public static final int portBs = 5687; public static final int securityPortBs = 5688; + public static final int[] SERVERS_PORT_NUMBERS = {port, securityPort, portBs, securityPortBs}; public static final String host = "localhost"; public static final String hostBs = "localhost"; @@ -156,16 +163,29 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest protected DeviceProfile deviceProfile; protected ScheduledExecutorService executor; protected TbTestWebSocketClient wsClient; - protected LwM2MTestClient client; + protected LwM2MTestClient lwM2MTestClient; private String[] resources; - public AbstractLwM2MIntegrationTest() { + @Before + public void startInit() throws Exception { + init(); + } + + @After + public void after() { + wsClient.close(); + clientDestroy(); + executor.shutdownNow(); } - public void init() throws Exception { + @AfterClass + public static void afterClass () { + awaitServersDestroy(); + } + + private void init () throws Exception { executor = Executors.newScheduledThreadPool(10, ThingsBoardThreadFactory.forName("test-lwm2m-scheduled")); loginTenantAdmin(); - for (String resourceName : this.resources) { TbResource lwModel = new TbResource(); lwModel.setResourceType(ResourceType.LWM2M_MODEL); @@ -181,18 +201,6 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest wsClient = buildAndConnectWebSocketClient(); } - @Before - public void beforeTest() throws Exception { - this.init(); - } - - @After - public void after() { - wsClient.close(); - clientDestroy(); - executor.shutdownNow(); - } - public void basicTestConnectionObserveTelemetry(Security security, LwM2MDeviceCredentials deviceCredentials, Configuration coapConfig, @@ -277,15 +285,20 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest } public void createNewClient(Security security, Configuration coapConfig, boolean isRpc, String endpoint, boolean isBootstrap, Security securityBs) throws Exception { - clientDestroy(); - client = new LwM2MTestClient(this.executor, endpoint); + this.clientDestroy(); + lwM2MTestClient = new LwM2MTestClient(this.executor, endpoint); int clientPort = SocketUtils.findAvailableUdpPort(); - client.init(security, coapConfig, clientPort, isRpc, isBootstrap, this.shortServerId, this.shortServerIdBs, securityBs); + lwM2MTestClient.init(security, coapConfig, clientPort, isRpc, isBootstrap, this.shortServerId, this.shortServerIdBs, securityBs); } private void clientDestroy() { - if (client != null) { - client.destroy(); + try { + if (lwM2MTestClient != null) { + lwM2MTestClient.destroy(); + awaitClientDestroy(lwM2MTestClient.getLeshanClient()); + } + } catch (Exception e) { + log.error("", e); } } @@ -338,4 +351,31 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest credentials.setBootstrap(bootstrapCredentials); return credentials; } + + private static void awaitServersDestroy() { + await("One of servers ports number is not free") + .atMost(3000, TimeUnit.MILLISECONDS) + .until(() -> isServerPortsAvailable() == null); + } + + + private static String isServerPortsAvailable() { + for (int port : SERVERS_PORT_NUMBERS) { + try (ServerSocket serverSocket = new ServerSocket(port)) { + serverSocket.close(); + Assert.assertEquals(true, serverSocket.isClosed()); + } catch (IOException e) { + log.warn(String.format("Port %n still in use", port)); + return (String.format("Port %n still in use", port)); + } + } + return null; + } + + private static void awaitClientDestroy(LeshanClient leshanClient) { + await("Destroy LeshanClient: delete All is registered Servers.") + .atMost(2000, TimeUnit.MILLISECONDS) + .until(() -> leshanClient.getRegisteredServers().size() == 0); + } + } 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 b8e3017236..f662b61d91 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 @@ -17,33 +17,6 @@ package org.thingsboard.server.transport.lwm2m; public class Lwm2mTestHelper { -// // Server -// public static final int SECURE_PORT = 5686; -// public static final int SECURE_PORT_BS = 5688; -// -//// public static final String HOST = "localhost"; -//// public static final int PORT = 5685; -////public static final String URI = "coap://" + HOST + ":" + PORT; -//public static final String SECURE_URI = "coaps://" + HOST + ":" + SECURE_PORT; -// public static final Configuration COAP_CONFIG = new Configuration().set(EXCHANGE_LIFETIME , 200, TimeUnit.SECONDS).set(COAP_PORT, PORT).set(COAP_SECURE_PORT, SECURE_PORT); -// public static final Security SECURITY_NO_SEC = noSec(URI, SHORT_SERVER_ID); -// -// public static final int PORT_BS = 5687; -// -// public static final String HOST_BS = "localhost"; -// public static final int SHORT_SERVER_ID = 123; -// public static final int SHORT_SERVER_ID_BS = 111; -// -// -// public static final Configuration SECURE_COAP_CONFIG = COAP_CONFIG.set(COAP_SECURE_PORT, SECURE_PORT); -// public static final Configuration COAP_CONFIG_BS = new Configuration().set(COAP_PORT, PORT_BS); -// -// -// public static final String URI_BS = "coap://" + HOST_BS + ":" + PORT_BS; -// -// public static final String SECURE_URI_BS = "coaps://" + HOST_BS + ":" + SECURE_PORT_BS; - - // Models public static final String[] resources = new String[]{"0.xml", "1.xml", "2.xml", "3.xml", "5.xml", "6.xml", "9.xml", "19.xml", "3303.xml"}; public static final int BINARY_APP_DATA_CONTAINER = 19; 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 c079513841..6e055783fe 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 @@ -43,7 +43,6 @@ import org.eclipse.leshan.core.request.RegisterRequest; import org.eclipse.leshan.core.request.UpdateRequest; import org.junit.Assert; import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; - import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; @@ -92,12 +91,12 @@ public class LwM2MTestClient { private final ScheduledExecutorService executor; private final String endpoint; - private LeshanClient client; + private LeshanClient leshanClient; private Security lwm2mSecurity; private Security lwm2mSecurityBs; - private Server lwm2mServer; - private Server lwm2mServerBs; + private Lwm2mServer lwm2mServer; + private Lwm2mServer lwm2mServerBs; private SimpleLwM2MDevice lwM2MDevice; private FwLwM2MDevice fwLwM2MDevice; private SwLwM2MDevice swLwM2MDevice; @@ -108,7 +107,7 @@ public class LwM2MTestClient { private Set clientStates; public void init(Security security, Configuration coapConfig, int port, boolean isRpc, boolean isBootstrap, int shortServerId, int shortServerIdBs, Security securityBs) throws InvalidDDFFileException, IOException { - Assert.assertNull("client already initialized", client); + Assert.assertNull("client already initialized", leshanClient); List models = new ArrayList<>(); for (String resourceName : resources) { models.addAll(ObjectLoader.loadDdfFile(LwM2MTestClient.class.getClassLoader().getResourceAsStream("lwm2m/" + resourceName), resourceName)); @@ -125,14 +124,14 @@ public class LwM2MTestClient { initializer.setInstancesForObject(SECURITY, instances); } if (isBootstrap) { - initializer.setInstancesForObject(SERVER, lwm2mServerBs = new Server(shortServerIdBs, 300)); + initializer.setInstancesForObject(SERVER, lwm2mServerBs = new Lwm2mServer(shortServerIdBs, 300)); } else { if (securityBs == null) { - initializer.setInstancesForObject(SERVER, lwm2mServer = new Server(shortServerId, 300)); + initializer.setInstancesForObject(SERVER, lwm2mServer = new Lwm2mServer(shortServerId, 300)); } else { - lwm2mServerBs = new Server(shortServerIdBs, 300); + lwm2mServerBs = new Lwm2mServer(shortServerIdBs, 300); lwm2mServerBs.setId(0); - lwm2mServer =new Server(shortServerId, 300); + lwm2mServer = new Lwm2mServer(shortServerId, 300); lwm2mServer.setId(1); LwM2mInstanceEnabler[] instances = new LwM2mInstanceEnabler[]{lwm2mServerBs, lwm2mServer}; initializer.setClassForObject(SERVER, Server.class); @@ -170,7 +169,7 @@ public class LwM2MTestClient { clientState = ON_INIT; clientStates = new HashSet<>(); clientStates.add(clientState); - client = builder.build(); + leshanClient = builder.build(); LwM2mClientObserver observer = new LwM2mClientObserver() { @Override @@ -275,15 +274,16 @@ public class LwM2MTestClient { clientStates.add(clientState); } }; - this.client.addObserver(observer); + this.leshanClient.addObserver(observer); + if (!isRpc) { - client.start(); + leshanClient.start(); } } public void destroy() { - if (client != null) { - client.destroy(true); + if (leshanClient != null) { + leshanClient.destroy(true); } if (lwm2mSecurityBs != null) { lwm2mSecurityBs = null; @@ -315,8 +315,8 @@ public class LwM2MTestClient { } public void start() { - if (client != null) { - client.start(); + if (leshanClient != null) { + leshanClient.start(); } } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/Lwm2mServer.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/Lwm2mServer.java new file mode 100644 index 0000000000..d4bac0a683 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/Lwm2mServer.java @@ -0,0 +1,235 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.transport.lwm2m.client; + +import lombok.extern.slf4j.Slf4j; +import org.eclipse.leshan.client.resource.BaseInstanceEnabler; +import org.eclipse.leshan.client.resource.LwM2mInstanceEnabler; +import org.eclipse.leshan.client.servers.ServerIdentity; +import org.eclipse.leshan.core.model.ObjectModel; +import org.eclipse.leshan.core.model.ResourceModel.Type; +import org.eclipse.leshan.core.node.LwM2mResource; +import org.eclipse.leshan.core.request.BindingMode; +import org.eclipse.leshan.core.response.ExecuteResponse; +import org.eclipse.leshan.core.response.ReadResponse; +import org.eclipse.leshan.core.response.WriteResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import java.util.Objects; + +/** + * A simple {@link LwM2mInstanceEnabler} for the Server (1) object. + */ +@Slf4j +public class Lwm2mServer extends BaseInstanceEnabler { + + private static final Logger LOG = LoggerFactory.getLogger(Lwm2mServer.class); + + private final static List supportedResources = Arrays.asList(0, 1, 2, 3, 6, 7, 8, 22); + + private int shortServerId; + private long lifetime; + private Long defaultMinPeriod; + private Long defaultMaxPeriod; + private EnumSet binding; + private BindingMode preferredTransport; + private boolean notifyWhenDisable; + + public Lwm2mServer() { + // should only be used at bootstrap time + } + + public Lwm2mServer(int shortServerId, long lifetime, EnumSet binding, boolean notifyWhenDisable, + BindingMode preferredTransport) { + this.shortServerId = shortServerId; + this.lifetime = lifetime; + this.binding = binding; + this.notifyWhenDisable = notifyWhenDisable; + this.preferredTransport = preferredTransport; + } + + public Lwm2mServer(int shortServerId, long lifetime) { + this(shortServerId, lifetime, EnumSet.of(BindingMode.U), false, BindingMode.U); + } + + @Override + public ReadResponse read(ServerIdentity identity, int resourceid) { + if (!identity.isSystem()) + LOG.debug("Read on Server resource /{}/{}/{}", getModel().id, getId(), resourceid); + + switch (resourceid) { + case 0: // short server ID + return ReadResponse.success(resourceid, shortServerId); + + case 1: // lifetime + return ReadResponse.success(resourceid, lifetime); + + case 2: // default min period + if (null == defaultMinPeriod) + return ReadResponse.notFound(); + return ReadResponse.success(resourceid, defaultMinPeriod); + + case 3: // default max period + if (null == defaultMaxPeriod) + return ReadResponse.notFound(); + return ReadResponse.success(resourceid, defaultMaxPeriod); + + case 6: // notification storing when disable or offline + return ReadResponse.success(resourceid, notifyWhenDisable); + + case 7: // binding + return ReadResponse.success(resourceid, BindingMode.toString(binding)); + + case 22: // preferred transport + if (preferredTransport == null) + return ReadResponse.notFound(); + return ReadResponse.success(resourceid, preferredTransport.toString()); + + default: + return super.read(identity, resourceid); + } + } + + @Override + public WriteResponse write(ServerIdentity identity, boolean replace, int resourceid, LwM2mResource value) { + if (!identity.isSystem()) + log.debug("Write on Server resource /{}/{}/{}", getModel().id, getId(), resourceid); + + switch (resourceid) { + case 0: + if (value.getType() != Type.INTEGER) { + return WriteResponse.badRequest("invalid type"); + } + int previousShortServerId = shortServerId; + shortServerId = ((Long) value.getValue()).intValue(); + if (previousShortServerId != shortServerId) + fireResourceChange(resourceid); + return WriteResponse.success(); + + case 1: + if (value.getType() != Type.INTEGER) { + return WriteResponse.badRequest("invalid type"); + } + long previousLifetime = lifetime; + lifetime = (Long) value.getValue(); + if (previousLifetime != lifetime) + fireResourceChange(resourceid); + return WriteResponse.success(); + + case 2: + if (value.getType() != Type.INTEGER) { + return WriteResponse.badRequest("invalid type"); + } + Long previousDefaultMinPeriod = defaultMinPeriod; + defaultMinPeriod = (Long) value.getValue(); + if (!Objects.equals(previousDefaultMinPeriod, defaultMinPeriod)) + fireResourceChange(resourceid); + return WriteResponse.success(); + + case 3: + if (value.getType() != Type.INTEGER) { + return WriteResponse.badRequest("invalid type"); + } + Long previousDefaultMaxPeriod = defaultMaxPeriod; + defaultMaxPeriod = (Long) value.getValue(); + if (!Objects.equals(previousDefaultMaxPeriod, defaultMaxPeriod)) + fireResourceChange(resourceid); + return WriteResponse.success(); + + case 6: // notification storing when disable or offline + if (value.getType() != Type.BOOLEAN) { + return WriteResponse.badRequest("invalid type"); + } + boolean previousNotifyWhenDisable = notifyWhenDisable; + notifyWhenDisable = (boolean) value.getValue(); + if (previousNotifyWhenDisable != notifyWhenDisable) + fireResourceChange(resourceid); + return WriteResponse.success(); + + case 7: // binding + if (value.getType() != Type.STRING) { + return WriteResponse.badRequest("invalid type"); + } + try { + EnumSet previousBinding = binding; + binding = BindingMode.parse((String) value.getValue()); + if (!Objects.equals(previousBinding, binding)) + fireResourceChange(resourceid); + return WriteResponse.success(); + } catch (IllegalArgumentException e) { + return WriteResponse.badRequest("invalid value"); + } + case 22: // preferredTransport + if (value.getType() != Type.STRING) { + return WriteResponse.badRequest("invalid type"); + } + try { + BindingMode previousPreferedTransport = preferredTransport; + preferredTransport = BindingMode.valueOf((String) value.getValue()); + if (!Objects.equals(previousPreferedTransport, preferredTransport)) + fireResourceChange(resourceid); + return WriteResponse.success(); + } catch (IllegalArgumentException e) { + return WriteResponse.badRequest("invalid value"); + } + + default: + return super.write(identity, replace, resourceid, value); + } + } + + @Override + public ExecuteResponse execute(ServerIdentity identity, int resourceid, String params) { + log.info("Execute on Server resource /{}/{}/{}", getModel().id, getId(), resourceid); + if (resourceid == 8) { + getLwM2mClient().triggerRegistrationUpdate(identity); + return ExecuteResponse.success(); + } else if (resourceid == 9) { + boolean success = getLwM2mClient().triggerClientInitiatedBootstrap(true); + if (success) { + return ExecuteResponse.success(); + } + else { + return ExecuteResponse.badRequest("probably no bootstrap server configured"); + } + } else { + return super.execute(identity, resourceid, params); + } + } + + @Override + public void reset(int resourceid) { + switch (resourceid) { + case 2: + defaultMinPeriod = null; + break; + case 3: + defaultMaxPeriod = null; + break; + default: + super.reset(resourceid); + } + } + + @Override + public List getAvailableResourceIds(ObjectModel model) { + return supportedResources; + } +} 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 1105e94ccd..669d8de55a 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 @@ -76,16 +76,18 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg } @Before - public void beforeTest() throws Exception { + public void startInitRPC() throws Exception { + initRpc(); + } + + private void initRpc () throws Exception { String endpoint = DEVICE_ENDPOINT_RPC_PREF + endpointSequence.incrementAndGet(); - init(); createNewClient(SECURITY_NO_SEC, COAP_CONFIG, true, endpoint, false, null); - expectedObjects = ConcurrentHashMap.newKeySet(); expectedObjectIdVers = ConcurrentHashMap.newKeySet(); expectedInstances = ConcurrentHashMap.newKeySet(); expectedObjectIdVerInstances = ConcurrentHashMap.newKeySet(); - client.getClient().getObjectTree().getObjectEnablers().forEach((key, val) -> { + lwM2MTestClient.getLeshanClient().getObjectTree().getObjectEnablers().forEach((key, val) -> { if (key > 0) { String objectVerId = "/" + key; if (!val.getObjectModel().version.equals("1.0")) { @@ -100,7 +102,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg }); } }); - String ver_Id_0 = client.getClient().getObjectTree().getModel().getObjectModel(OBJECT_ID_0).version; + 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 { @@ -145,7 +147,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg final Device device = createDevice(deviceCredentials, endpoint); deviceId = device.getId().getId().toString(); - client.start(); + lwM2MTestClient.start(); } protected String pathIdVerToObjectId(String pathIdVer) { diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationDiscoverTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationDiscoverTest.java index a4870b3486..5fd3c09d06 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationDiscoverTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationDiscoverTest.java @@ -124,7 +124,7 @@ public class RpcLwm2mIntegrationDiscoverTest extends AbstractRpcLwM2MIntegration String expectedInstance = (String) expectedInstances.stream().findFirst().get(); 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(); + int expectedResource = lwM2MTestClient.getLeshanClient().getObjectTree().getObjectEnablers().get(expectedPath.getObjectId()).getObjectModel().resources.entrySet().stream().findAny().get().getKey(); String expected = expectedInstance + "/" + expectedResource; String actualResult = sendDiscover(expected); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); 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 6aab036aa8..d9631928a7 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 @@ -70,7 +70,7 @@ public class RpcLwm2mIntegrationObserveTest extends AbstractRpcLwM2MIntegrationT public void testObserveWithBadVersion_Result_BadRequest_ErrorMsg_BadVersionMustBe1_0() throws Exception { String expectedInstance = (String) expectedInstances.stream().filter(path -> !((String)path).contains("_")).findFirst().get(); LwM2mPath expectedPath = new LwM2mPath(expectedInstance); - int expectedResource = client.getClient().getObjectTree().getObjectEnablers().get(expectedPath.getObjectId()).getObjectModel().resources.entrySet().stream().findAny().get().getKey(); + int expectedResource = lwM2MTestClient.getLeshanClient().getObjectTree().getObjectEnablers().get(expectedPath.getObjectId()).getObjectModel().resources.entrySet().stream().findAny().get().getKey(); String expectedId = "/" + expectedPath.getObjectId() + "_1.2" + "/" + expectedPath.getObjectInstanceId() + "/" + expectedResource; String actualResult = sendObserve("Observe", expectedId); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); 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 2f1d528573..fa4b601ed0 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,12 +15,10 @@ */ 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; @@ -63,9 +61,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_BOOTSTRAP_SUCCESS; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_STARTED; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_SUCCESS; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; @@ -193,22 +189,12 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M createDeviceProfile(transportConfiguration); final Device device = createDevice(deviceCredentials, endpoint); device.getId().getId().toString(); - client.start(); + lwM2MTestClient.start(); await(awaitAlias) .atMost(1000, TimeUnit.MILLISECONDS) - .until(() -> finishState.equals(client.getClientState())); - Assert.assertEquals(expectedStatuses, client.getClientStates()); - - client.destroy(); - if (ON_BOOTSTRAP_SUCCESS != finishState) { - expectedStatuses.add(ON_DEREGISTRATION_STARTED); - expectedStatuses.add(ON_DEREGISTRATION_SUCCESS); - await(awaitAlias) - .atMost(1000, TimeUnit.MILLISECONDS) - .until(() -> ON_DEREGISTRATION_SUCCESS.equals(client.getClientState())); - Assert.assertEquals(expectedStatuses, client.getClientStates()); - } + .until(() -> finishState.equals(lwM2MTestClient.getClientState())); + Assert.assertEquals(expectedStatuses, lwM2MTestClient.getClientStates()); } @@ -242,30 +228,21 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M createDeviceProfile(transportConfiguration); final Device device = createDevice(deviceCredentials, endpoint); String deviceId = device.getId().getId().toString(); - client.start(); + lwM2MTestClient.start(); await(awaitAlias) .atMost(1000, TimeUnit.MILLISECONDS) - .until(() -> ON_REGISTRATION_SUCCESS.equals(client.getClientState())); - Assert.assertEquals(expectedStatusesLwm2m, client.getClientStates()); + .until(() -> ON_REGISTRATION_SUCCESS.equals(lwM2MTestClient.getClientState())); + Assert.assertEquals(expectedStatusesLwm2m, lwM2MTestClient.getClientStates()); String executedPath = getObjectIdVer_1() + "/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()); - + sendRPCSecurityExecuteById(executedPath, deviceId, endpoint); expectedStatusesBs.add(ON_DEREGISTRATION_STARTED); expectedStatusesBs.add(ON_DEREGISTRATION_SUCCESS); await(awaitAlias) .atMost(1000, TimeUnit.MILLISECONDS) - .until(() -> ON_REGISTRATION_SUCCESS.equals(client.getClientState())); - Assert.assertEquals(expectedStatusesBs, client.getClientStates()); - - client.destroy(); - await(awaitAlias) - .atMost(1000, TimeUnit.MILLISECONDS) - .until(() -> ON_DEREGISTRATION_SUCCESS.equals(client.getClientState())); - Assert.assertEquals(expectedStatusesBs, client.getClientStates()); + .until(() -> ON_REGISTRATION_SUCCESS.equals(lwM2MTestClient.getClientState())); + Assert.assertEquals(expectedStatusesBs, lwM2MTestClient.getClientStates()); } protected List getBootstrapServerCredentialsSecure(LwM2MSecurityMode mode, LwM2MProfileBootstrapConfigType bootstrapConfigType) { @@ -423,7 +400,7 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M } private String getObjectIdVer_1() { - String ver_Id_0 = client.getClient().getObjectTree().getModel().getObjectModel(OBJECT_ID_1).version; + 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; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java index ff40289884..fc7893768b 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java @@ -67,9 +67,13 @@ public class LwM2MTransportBootstrapService { @PreDestroy public void shutdown() { - log.info("Stopping LwM2M transport bootstrap server!"); - server.destroy(); - log.info("LwM2M transport bootstrap server stopped!"); + try { + log.info("Stopping LwM2M transport bootstrap server!"); + server.destroy(); + log.info("LwM2M transport bootstrap server stopped!"); + } catch (Exception e) { + log.error("", e); + } } public LeshanBootstrapServer getLhBootstrapServer() { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java index cf4809f11a..b2b856b807 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java @@ -173,7 +173,7 @@ public class LwM2MBootstrapConfigStoreTaskProvider implements BootstrapTaskProvi if (shId instanceof Long) { shortId = ((Long) shId).intValue(); } else { - shortId = ((Integer) shId).intValue(); + shortId = (int) shId; } serverInstances.put(shortId, instance.getId()); }); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java index 8f6fe7cdb2..e8d6ffb7fa 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java @@ -99,9 +99,13 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService { @PreDestroy public void shutdown() { - log.info("Stopping LwM2M transport server!"); - server.destroy(); - log.info("LwM2M transport server stopped!"); + try { + log.info("Stopping LwM2M transport server!"); + server.destroy(); + log.info("LwM2M transport server stopped!"); + } catch (Exception e) { + log.error("", e); + } } private LeshanServer getLhServer() { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MNetworkConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MNetworkConfig.java index f3ab8d2cb8..8aed4ef9b4 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MNetworkConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MNetworkConfig.java @@ -31,16 +31,6 @@ public class LwM2MNetworkConfig { Configuration coapConfig = new Configuration(); coapConfig.set(CoapConfig.COAP_PORT, serverPortNoSec); coapConfig.set(CoapConfig.COAP_SECURE_PORT, serverSecurePort); - /** - Example:Property for large packet: - #NetworkConfig config = new Configuration(); - #config.sett(CoapConfig.MAX_MESSAGE_SIZE,32); - #config.set(CoapConfig.PREFERRED_BLOCK_SIZE,32); - #config.set(CoapConfig.MAX_RESOURCE_BODY_SIZE,2048); - #config.set(CoapConfig.MAX_RETRANSMIT,3); - #config.set(CoapConfig.MAX_TRANSMIT_WAIT,120000); - */ - /** Property to indicate if the response should always include the Block2 option \ when client request early blockwise negociation but the response can be sent on one packet.