Browse Source

lwm2m: fix bug: add afterClass "await (3 sec, closed all ports lwm2server and bootstrapServer)"

pull/5969/head
nickAS21 5 years ago
parent
commit
29a551d048
  1. 82
      application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java
  2. 27
      application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java
  3. 32
      application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java
  4. 235
      application/src/test/java/org/thingsboard/server/transport/lwm2m/client/Lwm2mServer.java
  5. 14
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java
  6. 2
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationDiscoverTest.java
  7. 2
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationObserveTest.java
  8. 43
      application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java
  9. 10
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java
  10. 2
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java
  11. 10
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java
  12. 10
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MNetworkConfig.java

82
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 lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.eclipse.californium.elements.config.Configuration; import org.eclipse.californium.elements.config.Configuration;
import org.eclipse.leshan.client.californium.LeshanClient;
import org.eclipse.leshan.client.object.Security; import org.eclipse.leshan.client.object.Security;
import org.junit.After; import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.springframework.util.SocketUtils; 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.service.telemetry.cmd.v2.LatestValueCmd;
import org.thingsboard.server.transport.lwm2m.client.LwM2MTestClient; import org.thingsboard.server.transport.lwm2m.client.LwM2MTestClient;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Base64; import java.util.Base64;
@ -73,7 +77,9 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; 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_PORT;
import static org.eclipse.californium.core.config.CoapConfig.COAP_SECURE_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.noSec;
@ -97,6 +103,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest
public static final int securityPort = 5686; public static final int securityPort = 5686;
public static final int portBs = 5687; public static final int portBs = 5687;
public static final int securityPortBs = 5688; 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 host = "localhost";
public static final String hostBs = "localhost"; public static final String hostBs = "localhost";
@ -156,16 +163,29 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest
protected DeviceProfile deviceProfile; protected DeviceProfile deviceProfile;
protected ScheduledExecutorService executor; protected ScheduledExecutorService executor;
protected TbTestWebSocketClient wsClient; protected TbTestWebSocketClient wsClient;
protected LwM2MTestClient client; protected LwM2MTestClient lwM2MTestClient;
private String[] resources; 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")); executor = Executors.newScheduledThreadPool(10, ThingsBoardThreadFactory.forName("test-lwm2m-scheduled"));
loginTenantAdmin(); loginTenantAdmin();
for (String resourceName : this.resources) { for (String resourceName : this.resources) {
TbResource lwModel = new TbResource(); TbResource lwModel = new TbResource();
lwModel.setResourceType(ResourceType.LWM2M_MODEL); lwModel.setResourceType(ResourceType.LWM2M_MODEL);
@ -181,18 +201,6 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest
wsClient = buildAndConnectWebSocketClient(); wsClient = buildAndConnectWebSocketClient();
} }
@Before
public void beforeTest() throws Exception {
this.init();
}
@After
public void after() {
wsClient.close();
clientDestroy();
executor.shutdownNow();
}
public void basicTestConnectionObserveTelemetry(Security security, public void basicTestConnectionObserveTelemetry(Security security,
LwM2MDeviceCredentials deviceCredentials, LwM2MDeviceCredentials deviceCredentials,
Configuration coapConfig, 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 { public void createNewClient(Security security, Configuration coapConfig, boolean isRpc, String endpoint, boolean isBootstrap, Security securityBs) throws Exception {
clientDestroy(); this.clientDestroy();
client = new LwM2MTestClient(this.executor, endpoint); lwM2MTestClient = new LwM2MTestClient(this.executor, endpoint);
int clientPort = SocketUtils.findAvailableUdpPort(); 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() { private void clientDestroy() {
if (client != null) { try {
client.destroy(); 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); credentials.setBootstrap(bootstrapCredentials);
return credentials; 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);
}
} }

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

@ -17,33 +17,6 @@ package org.thingsboard.server.transport.lwm2m;
public class Lwm2mTestHelper { 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 // 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 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; public static final int BINARY_APP_DATA_CONTAINER = 19;

32
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.eclipse.leshan.core.request.UpdateRequest;
import org.junit.Assert; import org.junit.Assert;
import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@ -92,12 +91,12 @@ public class LwM2MTestClient {
private final ScheduledExecutorService executor; private final ScheduledExecutorService executor;
private final String endpoint; private final String endpoint;
private LeshanClient client; private LeshanClient leshanClient;
private Security lwm2mSecurity; private Security lwm2mSecurity;
private Security lwm2mSecurityBs; private Security lwm2mSecurityBs;
private Server lwm2mServer; private Lwm2mServer lwm2mServer;
private Server lwm2mServerBs; private Lwm2mServer lwm2mServerBs;
private SimpleLwM2MDevice lwM2MDevice; private SimpleLwM2MDevice lwM2MDevice;
private FwLwM2MDevice fwLwM2MDevice; private FwLwM2MDevice fwLwM2MDevice;
private SwLwM2MDevice swLwM2MDevice; private SwLwM2MDevice swLwM2MDevice;
@ -108,7 +107,7 @@ public class LwM2MTestClient {
private Set<LwM2MClientState> clientStates; private Set<LwM2MClientState> clientStates;
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) throws InvalidDDFFileException, IOException {
Assert.assertNull("client already initialized", client); Assert.assertNull("client already initialized", leshanClient);
List<ObjectModel> models = new ArrayList<>(); List<ObjectModel> models = new ArrayList<>();
for (String resourceName : resources) { for (String resourceName : resources) {
models.addAll(ObjectLoader.loadDdfFile(LwM2MTestClient.class.getClassLoader().getResourceAsStream("lwm2m/" + resourceName), resourceName)); models.addAll(ObjectLoader.loadDdfFile(LwM2MTestClient.class.getClassLoader().getResourceAsStream("lwm2m/" + resourceName), resourceName));
@ -125,14 +124,14 @@ public class LwM2MTestClient {
initializer.setInstancesForObject(SECURITY, instances); initializer.setInstancesForObject(SECURITY, instances);
} }
if (isBootstrap) { if (isBootstrap) {
initializer.setInstancesForObject(SERVER, lwm2mServerBs = new Server(shortServerIdBs, 300)); initializer.setInstancesForObject(SERVER, lwm2mServerBs = new Lwm2mServer(shortServerIdBs, 300));
} else { } else {
if (securityBs == null) { if (securityBs == null) {
initializer.setInstancesForObject(SERVER, lwm2mServer = new Server(shortServerId, 300)); initializer.setInstancesForObject(SERVER, lwm2mServer = new Lwm2mServer(shortServerId, 300));
} else { } else {
lwm2mServerBs = new Server(shortServerIdBs, 300); lwm2mServerBs = new Lwm2mServer(shortServerIdBs, 300);
lwm2mServerBs.setId(0); lwm2mServerBs.setId(0);
lwm2mServer =new Server(shortServerId, 300); lwm2mServer = new Lwm2mServer(shortServerId, 300);
lwm2mServer.setId(1); lwm2mServer.setId(1);
LwM2mInstanceEnabler[] instances = new LwM2mInstanceEnabler[]{lwm2mServerBs, lwm2mServer}; LwM2mInstanceEnabler[] instances = new LwM2mInstanceEnabler[]{lwm2mServerBs, lwm2mServer};
initializer.setClassForObject(SERVER, Server.class); initializer.setClassForObject(SERVER, Server.class);
@ -170,7 +169,7 @@ public class LwM2MTestClient {
clientState = ON_INIT; clientState = ON_INIT;
clientStates = new HashSet<>(); clientStates = new HashSet<>();
clientStates.add(clientState); clientStates.add(clientState);
client = builder.build(); leshanClient = builder.build();
LwM2mClientObserver observer = new LwM2mClientObserver() { LwM2mClientObserver observer = new LwM2mClientObserver() {
@Override @Override
@ -275,15 +274,16 @@ public class LwM2MTestClient {
clientStates.add(clientState); clientStates.add(clientState);
} }
}; };
this.client.addObserver(observer); this.leshanClient.addObserver(observer);
if (!isRpc) { if (!isRpc) {
client.start(); leshanClient.start();
} }
} }
public void destroy() { public void destroy() {
if (client != null) { if (leshanClient != null) {
client.destroy(true); leshanClient.destroy(true);
} }
if (lwm2mSecurityBs != null) { if (lwm2mSecurityBs != null) {
lwm2mSecurityBs = null; lwm2mSecurityBs = null;
@ -315,8 +315,8 @@ public class LwM2MTestClient {
} }
public void start() { public void start() {
if (client != null) { if (leshanClient != null) {
client.start(); leshanClient.start();
} }
} }
} }

235
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<Integer> 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<BindingMode> binding;
private BindingMode preferredTransport;
private boolean notifyWhenDisable;
public Lwm2mServer() {
// should only be used at bootstrap time
}
public Lwm2mServer(int shortServerId, long lifetime, EnumSet<BindingMode> 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<BindingMode> 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<Integer> getAvailableResourceIds(ObjectModel model) {
return supportedResources;
}
}

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

@ -76,16 +76,18 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg
} }
@Before @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(); String endpoint = DEVICE_ENDPOINT_RPC_PREF + endpointSequence.incrementAndGet();
init();
createNewClient(SECURITY_NO_SEC, COAP_CONFIG, true, endpoint, false, null); createNewClient(SECURITY_NO_SEC, COAP_CONFIG, true, endpoint, false, null);
expectedObjects = ConcurrentHashMap.newKeySet(); expectedObjects = ConcurrentHashMap.newKeySet();
expectedObjectIdVers = ConcurrentHashMap.newKeySet(); expectedObjectIdVers = ConcurrentHashMap.newKeySet();
expectedInstances = ConcurrentHashMap.newKeySet(); expectedInstances = ConcurrentHashMap.newKeySet();
expectedObjectIdVerInstances = ConcurrentHashMap.newKeySet(); expectedObjectIdVerInstances = ConcurrentHashMap.newKeySet();
client.getClient().getObjectTree().getObjectEnablers().forEach((key, val) -> { lwM2MTestClient.getLeshanClient().getObjectTree().getObjectEnablers().forEach((key, val) -> {
if (key > 0) { if (key > 0) {
String objectVerId = "/" + key; String objectVerId = "/" + key;
if (!val.getObjectModel().version.equals("1.0")) { 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)) { if ("1.0".equals(ver_Id_0)) {
objectIdVer_0 = "/" + OBJECT_ID_0; objectIdVer_0 = "/" + OBJECT_ID_0;
} else { } else {
@ -145,7 +147,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg
final Device device = createDevice(deviceCredentials, endpoint); final Device device = createDevice(deviceCredentials, endpoint);
deviceId = device.getId().getId().toString(); deviceId = device.getId().getId().toString();
client.start(); lwM2MTestClient.start();
} }
protected String pathIdVerToObjectId(String pathIdVer) { protected String pathIdVerToObjectId(String pathIdVer) {

2
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 expectedInstance = (String) expectedInstances.stream().findFirst().get();
String expectedObjectInstanceId = pathIdVerToObjectId(expectedInstance); String expectedObjectInstanceId = pathIdVerToObjectId(expectedInstance);
LwM2mPath expectedPath = new LwM2mPath(expectedObjectInstanceId); 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 expected = expectedInstance + "/" + expectedResource;
String actualResult = sendDiscover(expected); String actualResult = sendDiscover(expected);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);

2
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 { public void testObserveWithBadVersion_Result_BadRequest_ErrorMsg_BadVersionMustBe1_0() throws Exception {
String expectedInstance = (String) expectedInstances.stream().filter(path -> !((String)path).contains("_")).findFirst().get(); String expectedInstance = (String) expectedInstances.stream().filter(path -> !((String)path).contains("_")).findFirst().get();
LwM2mPath expectedPath = new LwM2mPath(expectedInstance); 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 expectedId = "/" + expectedPath.getObjectId() + "_1.2" + "/" + expectedPath.getObjectInstanceId() + "/" + expectedResource;
String actualResult = sendObserve("Observe", expectedId); String actualResult = sendObserve("Observe", expectedId);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);

43
application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java

@ -15,12 +15,10 @@
*/ */
package org.thingsboard.server.transport.lwm2m.security; package org.thingsboard.server.transport.lwm2m.security;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.eclipse.californium.elements.config.Configuration; import org.eclipse.californium.elements.config.Configuration;
import org.eclipse.leshan.client.object.Security; import org.eclipse.leshan.client.object.Security;
import org.eclipse.leshan.core.ResponseCode;
import org.eclipse.leshan.core.util.Hex; import org.eclipse.leshan.core.util.Hex;
import org.junit.Assert; import org.junit.Assert;
import org.springframework.test.web.servlet.MvcResult; 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.awaitility.Awaitility.await;
import static org.eclipse.leshan.client.object.Security.noSecBootstap; 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.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_STARTED;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_SUCCESS; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_SUCCESS;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_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); createDeviceProfile(transportConfiguration);
final Device device = createDevice(deviceCredentials, endpoint); final Device device = createDevice(deviceCredentials, endpoint);
device.getId().getId().toString(); device.getId().getId().toString();
client.start(); lwM2MTestClient.start();
await(awaitAlias) await(awaitAlias)
.atMost(1000, TimeUnit.MILLISECONDS) .atMost(1000, TimeUnit.MILLISECONDS)
.until(() -> finishState.equals(client.getClientState())); .until(() -> finishState.equals(lwM2MTestClient.getClientState()));
Assert.assertEquals(expectedStatuses, client.getClientStates()); Assert.assertEquals(expectedStatuses, lwM2MTestClient.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());
}
} }
@ -242,30 +228,21 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M
createDeviceProfile(transportConfiguration); createDeviceProfile(transportConfiguration);
final Device device = createDevice(deviceCredentials, endpoint); final Device device = createDevice(deviceCredentials, endpoint);
String deviceId = device.getId().getId().toString(); String deviceId = device.getId().getId().toString();
client.start(); lwM2MTestClient.start();
await(awaitAlias) await(awaitAlias)
.atMost(1000, TimeUnit.MILLISECONDS) .atMost(1000, TimeUnit.MILLISECONDS)
.until(() -> ON_REGISTRATION_SUCCESS.equals(client.getClientState())); .until(() -> ON_REGISTRATION_SUCCESS.equals(lwM2MTestClient.getClientState()));
Assert.assertEquals(expectedStatusesLwm2m, client.getClientStates()); Assert.assertEquals(expectedStatusesLwm2m, lwM2MTestClient.getClientStates());
String executedPath = getObjectIdVer_1() + "/0/" + RESOURCE_ID_9; String executedPath = getObjectIdVer_1() + "/0/" + RESOURCE_ID_9;
String actualResult = sendRPCSecurityExecuteById(executedPath, deviceId, endpoint); 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_STARTED);
expectedStatusesBs.add(ON_DEREGISTRATION_SUCCESS); expectedStatusesBs.add(ON_DEREGISTRATION_SUCCESS);
await(awaitAlias) await(awaitAlias)
.atMost(1000, TimeUnit.MILLISECONDS) .atMost(1000, TimeUnit.MILLISECONDS)
.until(() -> ON_REGISTRATION_SUCCESS.equals(client.getClientState())); .until(() -> ON_REGISTRATION_SUCCESS.equals(lwM2MTestClient.getClientState()));
Assert.assertEquals(expectedStatusesBs, client.getClientStates()); Assert.assertEquals(expectedStatusesBs, lwM2MTestClient.getClientStates());
client.destroy();
await(awaitAlias)
.atMost(1000, TimeUnit.MILLISECONDS)
.until(() -> ON_DEREGISTRATION_SUCCESS.equals(client.getClientState()));
Assert.assertEquals(expectedStatusesBs, client.getClientStates());
} }
protected List<LwM2MBootstrapServerCredential> getBootstrapServerCredentialsSecure(LwM2MSecurityMode mode, LwM2MProfileBootstrapConfigType bootstrapConfigType) { protected List<LwM2MBootstrapServerCredential> getBootstrapServerCredentialsSecure(LwM2MSecurityMode mode, LwM2MProfileBootstrapConfigType bootstrapConfigType) {
@ -423,7 +400,7 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M
} }
private String getObjectIdVer_1() { 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; String objectIdVer_1;
if ("1.0".equals(ver_Id_0)) { if ("1.0".equals(ver_Id_0)) {
objectIdVer_1 = "/" + OBJECT_ID_1; objectIdVer_1 = "/" + OBJECT_ID_1;

10
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java

@ -67,9 +67,13 @@ public class LwM2MTransportBootstrapService {
@PreDestroy @PreDestroy
public void shutdown() { public void shutdown() {
log.info("Stopping LwM2M transport bootstrap server!"); try {
server.destroy(); log.info("Stopping LwM2M transport bootstrap server!");
log.info("LwM2M transport bootstrap server stopped!"); server.destroy();
log.info("LwM2M transport bootstrap server stopped!");
} catch (Exception e) {
log.error("", e);
}
} }
public LeshanBootstrapServer getLhBootstrapServer() { public LeshanBootstrapServer getLhBootstrapServer() {

2
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) { if (shId instanceof Long) {
shortId = ((Long) shId).intValue(); shortId = ((Long) shId).intValue();
} else { } else {
shortId = ((Integer) shId).intValue(); shortId = (int) shId;
} }
serverInstances.put(shortId, instance.getId()); serverInstances.put(shortId, instance.getId());
}); });

10
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java

@ -99,9 +99,13 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
@PreDestroy @PreDestroy
public void shutdown() { public void shutdown() {
log.info("Stopping LwM2M transport server!"); try {
server.destroy(); log.info("Stopping LwM2M transport server!");
log.info("LwM2M transport server stopped!"); server.destroy();
log.info("LwM2M transport server stopped!");
} catch (Exception e) {
log.error("", e);
}
} }
private LeshanServer getLhServer() { private LeshanServer getLhServer() {

10
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(); Configuration coapConfig = new Configuration();
coapConfig.set(CoapConfig.COAP_PORT, serverPortNoSec); coapConfig.set(CoapConfig.COAP_PORT, serverPortNoSec);
coapConfig.set(CoapConfig.COAP_SECURE_PORT, serverSecurePort); 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 \ 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. when client request early blockwise negociation but the response can be sent on one packet.

Loading…
Cancel
Save