From ff9fcbbac06022e903b9b59891003fccaabf208d Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Mon, 29 Aug 2022 11:31:26 +0300 Subject: [PATCH] Fixed LWM2M transport serialization. Extended CoAP, SNMP, LWM2M device profiles edge test. Part #2 --- .../thingsboard/server/edge/BaseEdgeTest.java | 125 +++++++++++++++++- .../lwm2m/AbstractLwM2MIntegrationTest.java | 4 +- .../profile/lwm2m/ObjectAttributes.java | 4 +- .../profile/lwm2m/OtherConfiguration.java | 2 + .../lwm2m/TelemetryMappingConfiguration.java | 3 +- .../LwM2MBootstrapServerCredential.java | 4 +- .../LwM2MBootstrapServersConfiguration.java | 27 ---- 7 files changed, 133 insertions(+), 36 deletions(-) delete mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServersConfiguration.java diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java index 0e05e59264..a5b36d5f47 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -75,6 +75,11 @@ import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTrans import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.SimpleAlarmConditionSpec; import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration; +import org.thingsboard.server.common.data.device.profile.lwm2m.OtherConfiguration; +import org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryMappingConfiguration; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.AbstractLwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.NoSecLwM2MBootstrapServerCredential; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; @@ -151,7 +156,9 @@ import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg; import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.queue.util.DataDecodingEncodingService; import org.thingsboard.server.transport.AbstractTransportIntegrationTest; +import org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -185,6 +192,9 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { @Autowired private EdgeEventService edgeEventService; + @Autowired + private DataDecodingEncodingService dataDecodingEncodingService; + @Autowired private TbClusterService clusterService; @@ -462,7 +472,31 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits()); Assert.assertEquals(DeviceTransportType.SNMP.name(), deviceProfileUpdateMsg.getTransportType()); - // TODO: add custom validation + Optional deviceProfileDataOpt = + dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray()); + + Assert.assertTrue(deviceProfileDataOpt.isPresent()); + DeviceProfileData deviceProfileData = deviceProfileDataOpt.get(); + + Assert.assertTrue(deviceProfileData.getTransportConfiguration() instanceof SnmpDeviceProfileTransportConfiguration); + SnmpDeviceProfileTransportConfiguration transportConfiguration = + (SnmpDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration(); + Assert.assertEquals(Integer.valueOf(1000), transportConfiguration.getTimeoutMs()); + Assert.assertEquals(Integer.valueOf(3), transportConfiguration.getRetries()); + + Assert.assertFalse(transportConfiguration.getCommunicationConfigs().isEmpty()); + SnmpCommunicationConfig communicationConfig = transportConfiguration.getCommunicationConfigs().get(0); + Assert.assertTrue(communicationConfig instanceof TelemetryQueryingSnmpCommunicationConfig); + TelemetryQueryingSnmpCommunicationConfig snmpCommunicationConfig = + (TelemetryQueryingSnmpCommunicationConfig) communicationConfig; + + Assert.assertEquals(Long.valueOf(500L), snmpCommunicationConfig.getQueryingFrequencyMs()); + Assert.assertFalse(snmpCommunicationConfig.getMappings().isEmpty()); + + SnmpMapping snmpMapping = snmpCommunicationConfig.getMappings().get(0); + Assert.assertEquals("temperature", snmpMapping.getKey()); + Assert.assertEquals("1.3.3.5.6.7.8.9.1", snmpMapping.getOid()); + Assert.assertEquals(DataType.DOUBLE, snmpMapping.getDataType()); removeDeviceProfileAndDoBasicAssert(deviceProfile); } @@ -479,7 +513,42 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits()); Assert.assertEquals(DeviceTransportType.LWM2M.name(), deviceProfileUpdateMsg.getTransportType()); - // TODO: add custom validation + Optional deviceProfileDataOpt = + dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray()); + + Assert.assertTrue(deviceProfileDataOpt.isPresent()); + DeviceProfileData deviceProfileData = deviceProfileDataOpt.get(); + + Assert.assertTrue(deviceProfileData.getTransportConfiguration() instanceof Lwm2mDeviceProfileTransportConfiguration); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = + (Lwm2mDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration(); + + OtherConfiguration clientLwM2mSettings = transportConfiguration.getClientLwM2mSettings(); + Assert.assertEquals(PowerMode.DRX, clientLwM2mSettings.getPowerMode()); + Assert.assertEquals(Integer.valueOf(1), clientLwM2mSettings.getFwUpdateStrategy()); + Assert.assertEquals(Integer.valueOf(1), clientLwM2mSettings.getSwUpdateStrategy()); + Assert.assertEquals(Integer.valueOf(1), clientLwM2mSettings.getClientOnlyObserveAfterConnect()); + + Assert.assertTrue(transportConfiguration.isBootstrapServerUpdateEnable()); + + Assert.assertFalse(transportConfiguration.getBootstrap().isEmpty()); + LwM2MBootstrapServerCredential lwM2MBootstrapServerCredential = transportConfiguration.getBootstrap().get(0); + Assert.assertTrue(lwM2MBootstrapServerCredential instanceof NoSecLwM2MBootstrapServerCredential); + NoSecLwM2MBootstrapServerCredential noSecLwM2MBootstrapServerCredential = (NoSecLwM2MBootstrapServerCredential) lwM2MBootstrapServerCredential; + + Assert.assertEquals("PUBLIC_KEY", noSecLwM2MBootstrapServerCredential.getServerPublicKey()); + Assert.assertEquals(Integer.valueOf(123), noSecLwM2MBootstrapServerCredential.getShortServerId()); + Assert.assertTrue(noSecLwM2MBootstrapServerCredential.isBootstrapServerIs()); + Assert.assertEquals("localhost", noSecLwM2MBootstrapServerCredential.getHost()); + Assert.assertEquals(Integer.valueOf(5687), noSecLwM2MBootstrapServerCredential.getPort()); + + TelemetryMappingConfiguration observeAttr = transportConfiguration.getObserveAttr(); + Assert.assertEquals("batteryLevel", observeAttr.getKeyName().get("/3_1.0/0/9")); + Assert.assertTrue(observeAttr.getObserve().isEmpty()); + Assert.assertTrue(observeAttr.getAttribute().isEmpty()); + Assert.assertFalse(observeAttr.getTelemetry().isEmpty()); + Assert.assertTrue(observeAttr.getTelemetry().contains("/3_1.0/0/9")); + Assert.assertTrue(observeAttr.getAttributeLwm2m().isEmpty()); removeDeviceProfileAndDoBasicAssert(deviceProfile); } @@ -496,7 +565,36 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits()); Assert.assertEquals(DeviceTransportType.COAP.name(), deviceProfileUpdateMsg.getTransportType()); - // TODO: add custom validation + Optional deviceProfileDataOpt = + dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray()); + + Assert.assertTrue(deviceProfileDataOpt.isPresent()); + DeviceProfileData deviceProfileData = deviceProfileDataOpt.get(); + + Assert.assertTrue(deviceProfileData.getTransportConfiguration() instanceof CoapDeviceProfileTransportConfiguration); + CoapDeviceProfileTransportConfiguration transportConfiguration = + (CoapDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration(); + + PowerSavingConfiguration clientSettings = transportConfiguration.getClientSettings(); + + Assert.assertEquals(PowerMode.DRX, clientSettings.getPowerMode()); + Assert.assertEquals(Long.valueOf(1L), clientSettings.getEdrxCycle()); + Assert.assertEquals(Long.valueOf(1L), clientSettings.getPsmActivityTimer()); + Assert.assertEquals(Long.valueOf(1L), clientSettings.getPagingTransmissionWindow()); + + Assert.assertTrue(transportConfiguration.getCoapDeviceTypeConfiguration() instanceof DefaultCoapDeviceTypeConfiguration); + DefaultCoapDeviceTypeConfiguration coapDeviceTypeConfiguration = + (DefaultCoapDeviceTypeConfiguration) transportConfiguration.getCoapDeviceTypeConfiguration(); + + Assert.assertTrue(coapDeviceTypeConfiguration.getTransportPayloadTypeConfiguration() instanceof ProtoTransportPayloadConfiguration); + + ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = + (ProtoTransportPayloadConfiguration) coapDeviceTypeConfiguration.getTransportPayloadTypeConfiguration(); + + Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_TELEMETRY_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceTelemetryProtoSchema()); + Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_ATTRIBUTES_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceAttributesProtoSchema()); + Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_RPC_RESPONSE_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceRpcResponseProtoSchema()); + Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_RPC_REQUEST_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceRpcRequestProtoSchema()); removeDeviceProfileAndDoBasicAssert(deviceProfile); } @@ -539,8 +637,27 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { } private Lwm2mDeviceProfileTransportConfiguration createLwm2mDeviceProfileTransportConfiguration() { - // TODO: add custom configuration Lwm2mDeviceProfileTransportConfiguration transportConfiguration = new Lwm2mDeviceProfileTransportConfiguration(); + + OtherConfiguration clientLwM2mSettings = JacksonUtil.fromString(AbstractLwM2MIntegrationTest.CLIENT_LWM2M_SETTINGS, OtherConfiguration.class); + transportConfiguration.setClientLwM2mSettings(clientLwM2mSettings); + + transportConfiguration.setBootstrapServerUpdateEnable(true); + + TelemetryMappingConfiguration observeAttrConfiguration = + JacksonUtil.fromString(AbstractLwM2MIntegrationTest.OBSERVE_ATTRIBUTES_WITH_PARAMS, TelemetryMappingConfiguration.class); + transportConfiguration.setObserveAttr(observeAttrConfiguration); + + List bootstrap = new ArrayList<>(); + AbstractLwM2MBootstrapServerCredential bootstrapServerCredential = new NoSecLwM2MBootstrapServerCredential(); + bootstrapServerCredential.setServerPublicKey("PUBLIC_KEY"); + bootstrapServerCredential.setShortServerId(123); + bootstrapServerCredential.setBootstrapServerIs(true); + bootstrapServerCredential.setHost("localhost"); + bootstrapServerCredential.setPort(5687); + bootstrap.add(bootstrapServerCredential); + transportConfiguration.setBootstrap(bootstrap); + return transportConfiguration; } 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 9f04d382fb..ac272d0bb4 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 @@ -144,7 +144,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractControllerTes " \"attributeLwm2m\": {}\n" + " }"; - protected final String OBSERVE_ATTRIBUTES_WITH_PARAMS = + public static final String OBSERVE_ATTRIBUTES_WITH_PARAMS = " {\n" + " \"keyName\": {\n" + @@ -159,7 +159,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractControllerTes " \"attributeLwm2m\": {}\n" + " }"; - protected final String CLIENT_LWM2M_SETTINGS = + public static final String CLIENT_LWM2M_SETTINGS = " {\n" + " \"edrxCycle\": null,\n" + " \"powerMode\": \"DRX\",\n" + diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/ObjectAttributes.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/ObjectAttributes.java index bcaedaa801..889b96b658 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/ObjectAttributes.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/ObjectAttributes.java @@ -18,9 +18,11 @@ package org.thingsboard.server.common.data.device.profile.lwm2m; import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data; +import java.io.Serializable; + @Data @JsonInclude(JsonInclude.Include.NON_NULL) -public class ObjectAttributes { +public class ObjectAttributes implements Serializable { private Long dim; private String ver; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/OtherConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/OtherConfiguration.java index 73caea088d..13bf9f4793 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/OtherConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/OtherConfiguration.java @@ -18,10 +18,12 @@ package org.thingsboard.server.common.data.device.profile.lwm2m; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.device.data.PowerMode; import org.thingsboard.server.common.data.device.data.PowerSavingConfiguration; +@EqualsAndHashCode(callSuper = true) @Data @NoArgsConstructor @AllArgsConstructor diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/TelemetryMappingConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/TelemetryMappingConfiguration.java index cb6f4e7695..17dda44b41 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/TelemetryMappingConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/TelemetryMappingConfiguration.java @@ -19,13 +19,14 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.io.Serializable; import java.util.Map; import java.util.Set; @Data @NoArgsConstructor @AllArgsConstructor -public class TelemetryMappingConfiguration { +public class TelemetryMappingConfiguration implements Serializable { private Map keyName; private Set observe; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServerCredential.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServerCredential.java index 6a563c8418..6367036ecb 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServerCredential.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServerCredential.java @@ -21,6 +21,8 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; +import java.io.Serializable; + @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, property = "securityMode") @@ -31,7 +33,7 @@ import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurity @JsonSubTypes.Type(value = X509LwM2MBootstrapServerCredential.class, name = "X509") }) @JsonIgnoreProperties(ignoreUnknown = true) -public interface LwM2MBootstrapServerCredential { +public interface LwM2MBootstrapServerCredential extends Serializable { @JsonIgnore LwM2MSecurityMode getSecurityMode(); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServersConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServersConfiguration.java deleted file mode 100644 index e5bdec684a..0000000000 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServersConfiguration.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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.common.data.device.profile.lwm2m.bootstrap; - -import lombok.Data; - -import java.util.List; - -@Data -public class LwM2MBootstrapServersConfiguration { - - List bootstrap; - -}