lwm2m: add test FW with objectId = 19
This commit is contained in:
parent
f722618aa0
commit
ed25c79655
@ -102,6 +102,7 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClient
|
||||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_UPDATE_SUCCESS;
|
||||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType;
|
||||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE;
|
||||
import static org.thingsboard.server.transport.lwm2m.ota.AbstractOtaLwM2MIntegrationTest.CLIENT_LWM2M_SETTINGS_19;
|
||||
|
||||
@TestPropertySource(properties = {
|
||||
"transport.lwm2m.enabled=true",
|
||||
@ -382,6 +383,16 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte
|
||||
transportConfiguration.setBootstrap(bootstrapServerCredentials);
|
||||
return transportConfiguration;
|
||||
}
|
||||
protected Lwm2mDeviceProfileTransportConfiguration getTransportConfiguration19(String observeAttr, List<LwM2MBootstrapServerCredential> bootstrapServerCredentials) {
|
||||
Lwm2mDeviceProfileTransportConfiguration transportConfiguration = new Lwm2mDeviceProfileTransportConfiguration();
|
||||
TelemetryMappingConfiguration observeAttrConfiguration = JacksonUtil.fromString(observeAttr, TelemetryMappingConfiguration.class);
|
||||
OtherConfiguration clientLwM2mSettings = JacksonUtil.fromString(CLIENT_LWM2M_SETTINGS_19, OtherConfiguration.class);
|
||||
transportConfiguration.setBootstrapServerUpdateEnable(true);
|
||||
transportConfiguration.setObserveAttr(observeAttrConfiguration);
|
||||
transportConfiguration.setClientLwM2mSettings(clientLwM2mSettings);
|
||||
transportConfiguration.setBootstrap(bootstrapServerCredentials);
|
||||
return transportConfiguration;
|
||||
}
|
||||
|
||||
protected List<LwM2MBootstrapServerCredential> getBootstrapServerCredentialsNoSec(LwM2MProfileBootstrapConfigType bootstrapConfigType) {
|
||||
List<LwM2MBootstrapServerCredential> bootstrap = new ArrayList<>();
|
||||
|
||||
@ -84,8 +84,8 @@ public class LwM2mBinaryAppDataContainer extends BaseInstanceEnabler implements
|
||||
try {
|
||||
if (id != null) this.setId(id);
|
||||
executorService.scheduleWithFixedDelay(() -> {
|
||||
fireResourceChange(0);
|
||||
fireResourceChange(2);
|
||||
// fireResourceChange(0);
|
||||
// fireResourceChange(2);
|
||||
}
|
||||
, 1, 1, TimeUnit.SECONDS); // 1 sec
|
||||
// , 1800000, 1800000, TimeUnit.MILLISECONDS); // 30 MIN
|
||||
|
||||
@ -16,10 +16,14 @@
|
||||
package org.thingsboard.server.transport.lwm2m.ota;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.github.dockerjava.zerodep.shaded.org.apache.commons.codec.binary.Hex;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.leshan.core.ResponseCode;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.OtaPackageInfo;
|
||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||
@ -31,25 +35,29 @@ import org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.rest.client.utils.RestJsonConverter.toTimeseries;
|
||||
import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE;
|
||||
import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE;
|
||||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_11;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.*;
|
||||
|
||||
@Slf4j
|
||||
@DaoSqlTest
|
||||
public abstract class AbstractOtaLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest {
|
||||
|
||||
private final String[] RESOURCES_OTA = new String[]{"3.xml", "5.xml", "9.xml"};
|
||||
private final String[] RESOURCES_OTA = new String[]{"3.xml", "5.xml", "9.xml", "19.xml"};
|
||||
protected static final String CLIENT_ENDPOINT_WITHOUT_FW_INFO = "WithoutFirmwareInfoDevice";
|
||||
protected static final String CLIENT_ENDPOINT_OTA5 = "Ota5_Device";
|
||||
protected static final String CLIENT_ENDPOINT_OTA9 = "Ota9_Device";
|
||||
protected List<OtaPackageUpdateStatus> expectedStatuses;
|
||||
|
||||
|
||||
protected final String OBSERVE_ATTRIBUTES_WITH_PARAMS_OTA5 =
|
||||
|
||||
" {\n" +
|
||||
@ -78,6 +86,54 @@ public abstract class AbstractOtaLwM2MIntegrationTest extends AbstractLwM2MInteg
|
||||
" \"attributeLwm2m\": {}\n" +
|
||||
" }";
|
||||
|
||||
protected final String OBSERVE_ATTRIBUTES_WITH_PARAMS_OTA5_19 =
|
||||
|
||||
" {\n" +
|
||||
" \"keyName\": {\n" +
|
||||
" \"/5_1.2/0/3\": \"state\",\n" +
|
||||
" \"/5_1.2/0/5\": \"updateResult\",\n" +
|
||||
" \"/5_1.2/0/6\": \"pkgname\",\n" +
|
||||
" \"/5_1.2/0/7\": \"pkgversion\",\n" +
|
||||
" \"/5_1.2/0/9\": \"firmwareUpdateDeliveryMethod\",\n" +
|
||||
" \"/19_1.1/0/0\": \"dataRead\",\n" +
|
||||
" \"/19_1.1/65534/0\": \"dataFotaAttr\"\n" +
|
||||
" },\n" +
|
||||
" \"observe\": [\n" +
|
||||
" \"/5_1.2/0/3\",\n" +
|
||||
" \"/5_1.2/0/5\",\n" +
|
||||
" \"/5_1.2/0/6\",\n" +
|
||||
" \"/5_1.2/0/7\",\n" +
|
||||
" \"/5_1.2/0/9\",\n" +
|
||||
" \"/19_1.1/0/0\",\n" +
|
||||
" \"/19_1.1/65534/0\"\n" +
|
||||
" ],\n" +
|
||||
" \"attribute\": [],\n" +
|
||||
" \"telemetry\": [\n" +
|
||||
" \"/5_1.2/0/3\",\n" +
|
||||
" \"/5_1.2/0/5\",\n" +
|
||||
" \"/5_1.2/0/6\",\n" +
|
||||
" \"/5_1.2/0/7\",\n" +
|
||||
" \"/5_1.2/0/9\",\n" +
|
||||
" \"/19_1.1/0/0\",\n" +
|
||||
" \"/19_1.1/65534/0\"\n" +
|
||||
" ],\n" +
|
||||
" \"attributeLwm2m\": {}\n" +
|
||||
" }";
|
||||
|
||||
public static final String CLIENT_LWM2M_SETTINGS_19 =
|
||||
" {\n" +
|
||||
" \"useObject19ForOta\": true,\n" +
|
||||
" \"edrxCycle\": null,\n" +
|
||||
" \"powerMode\": \"DRX\",\n" +
|
||||
" \"fwUpdateResource\": null,\n" +
|
||||
" \"fwUpdateStrategy\": 1,\n" +
|
||||
" \"psmActivityTimer\": null,\n" +
|
||||
" \"swUpdateResource\": null,\n" +
|
||||
" \"swUpdateStrategy\": 1,\n" +
|
||||
" \"pagingTransmissionWindow\": null,\n" +
|
||||
" \"clientOnlyObserveAfterConnect\": 1\n" +
|
||||
" }";
|
||||
|
||||
protected final String OBSERVE_ATTRIBUTES_WITH_PARAMS_OTA9 =
|
||||
|
||||
" {\n" +
|
||||
@ -159,6 +215,13 @@ public abstract class AbstractOtaLwM2MIntegrationTest extends AbstractLwM2MInteg
|
||||
log.warn("Fetched telemetry by API for deviceId {}, list size {}, tsKvEntries {}", deviceId, tsKvEntries.size(), tsKvEntries);
|
||||
return tsKvEntries;
|
||||
}
|
||||
protected List<TsKvEntry> getFwSwParamsObject19TelemetryFromAPI(UUID deviceId) throws Exception {
|
||||
String type_state = "dataFotaAttr";
|
||||
final List<TsKvEntry> tsKvEntries = toTimeseries(doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + deviceId + "/values/timeseries?orderBy=ASC&keys=" + type_state + "&startTs=0&endTs=" + System.currentTimeMillis(), new TypeReference<>() {
|
||||
}));
|
||||
log.warn("Fetched telemetry by API for deviceId {}, list size {}, tsKvEntries {}", deviceId, tsKvEntries.size(), tsKvEntries);
|
||||
return tsKvEntries;
|
||||
}
|
||||
|
||||
protected boolean predicateForStatuses(List<TsKvEntry> ts) {
|
||||
List<OtaPackageUpdateStatus> statuses = ts.stream()
|
||||
@ -169,4 +232,27 @@ public abstract class AbstractOtaLwM2MIntegrationTest extends AbstractLwM2MInteg
|
||||
log.warn("{}", statuses);
|
||||
return statuses.containsAll(expectedStatuses);
|
||||
}
|
||||
|
||||
protected void resultReadOtaParams_19(String resourceIdVer, OtaPackageInfo otaPackageInfo) throws Exception {
|
||||
String actualResult = sendRPCById(resourceIdVer);
|
||||
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||
assertEquals(ResponseCode.CONTENT.getName(), rpcActualResult.get("result").asText());
|
||||
String valStr = rpcActualResult.get("value").asText();
|
||||
String start = "{ id=0 value=";
|
||||
String valHexDec = valStr.substring(valStr.indexOf(start) + start.length(), (valStr.indexOf("}")));
|
||||
String valNode = new String(Hex.decodeHex((valHexDec).toCharArray()));
|
||||
ObjectNode actualResultVal = JacksonUtil.fromString(valNode, ObjectNode.class);
|
||||
assert actualResultVal != null;
|
||||
assertEquals(otaPackageInfo.getTitle(), actualResultVal.get(OTA_INFO_19_TITLE).asText());
|
||||
assertEquals(otaPackageInfo.getVersion(), actualResultVal.get(OTA_INFO_19_VERSION).asText());
|
||||
assertEquals(otaPackageInfo.getChecksum(), actualResultVal.get(OTA_INFO_19_FILE_CHECKSUM256).asText());
|
||||
assertEquals(otaPackageInfo.getFileName(), actualResultVal.get(OTA_INFO_19_FILE_NAME).asText());
|
||||
assertEquals(Optional.of(otaPackageInfo.getDataSize()), Optional.of((long) actualResultVal.get(OTA_INFO_19_FILE_SIZE).asInt()));
|
||||
}
|
||||
|
||||
private String sendRPCById(String path) throws Exception {
|
||||
String setRpcRequest = "{\"method\": \"Read\", \"params\": {\"id\": \"" + path + "\"}}";
|
||||
return doPostAsync("/api/plugins/rpc/twoway/" + lwM2MTestClient.getDeviceIdStr(), setRpcRequest, String.class, status().isOk());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -16,17 +16,25 @@
|
||||
package org.thingsboard.server.transport.lwm2m.ota.sql;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.github.dockerjava.zerodep.shaded.org.apache.commons.codec.binary.Hex;
|
||||
import jakarta.validation.constraints.AssertTrue;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.eclipse.leshan.core.ResponseCode;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
import org.thingsboard.server.common.data.OtaPackageInfo;
|
||||
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials;
|
||||
import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.kv.KvEntry;
|
||||
import org.thingsboard.server.common.data.kv.TsKvEntry;
|
||||
import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus;
|
||||
import org.thingsboard.server.transport.lwm2m.ota.AbstractOtaLwM2MIntegrationTest;
|
||||
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@ -36,6 +44,9 @@ import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
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.rest.client.utils.RestJsonConverter.toTimeseries;
|
||||
import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED;
|
||||
import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADING;
|
||||
@ -44,7 +55,9 @@ import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.INIT
|
||||
import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.QUEUED;
|
||||
import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATED;
|
||||
import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING;
|
||||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.*;
|
||||
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_INSTANCE_ID;
|
||||
|
||||
@Slf4j
|
||||
public class Ota5LwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest {
|
||||
@ -107,4 +120,50 @@ public class Ota5LwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ObjectId = 19
|
||||
* {
|
||||
* "title" : "BC68J01",
|
||||
* "version" : "10",
|
||||
* "fileChecksumSHA256" : "f2a08d4963e981c78f2a99f62d8439af4437a72ea7267a8c01d013c072c01ded",
|
||||
* "fileSize" : 59832,
|
||||
* "fileName" : "FW_BC68JAR01A10_TO_BC68JAR01A09_09.bin",
|
||||
* "packageType" : "FIRMWARE"
|
||||
* }
|
||||
* to base64
|
||||
* /5/0/5 -> Update Result (Res); 5/0/3 -> State;
|
||||
* => ((Res>=0 && Res<=9) && State=0)
|
||||
* => Write to Package/Write to Package URI -> DOWNLOADING ((Res>=0 && Res<=9) && State=1)
|
||||
* => Download Finished -> DOWNLOADED ((Res==0 || Res=8) && State=2)
|
||||
* => Executable resource Update is triggered / Initiate Firmware Update -> UPDATING (Res=0 && State=3)
|
||||
* => Update Successful [Res==1]
|
||||
* => Start / Res=0 -> "IDLE" ....
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testFirmwareUpdateByObject5WithObject19_Ok() throws Exception {
|
||||
Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration19(OBSERVE_ATTRIBUTES_WITH_PARAMS_OTA5_19, getBootstrapServerCredentialsNoSec(NONE));
|
||||
DeviceProfile deviceProfile = createLwm2mDeviceProfile("profileFor" + this.CLIENT_ENDPOINT_OTA5, transportConfiguration);
|
||||
LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(this.CLIENT_ENDPOINT_OTA5));
|
||||
final Device device = createLwm2mDevice(deviceCredentials, this.CLIENT_ENDPOINT_OTA5, deviceProfile.getId());
|
||||
createNewClient(SECURITY_NO_SEC, null, false, this.CLIENT_ENDPOINT_OTA5, device.getId().getId().toString());
|
||||
awaitObserveReadAll(6, device.getId().getId().toString());
|
||||
|
||||
OtaPackageInfo otaPackageInfo = createFirmware("fw.v.1.5.0-update", deviceProfile.getId());
|
||||
device.setFirmwareId(otaPackageInfo.getId());
|
||||
final Device savedDevice = doPost("/api/device", device, Device.class);
|
||||
|
||||
assertThat(savedDevice).as("saved device").isNotNull();
|
||||
assertThat(getDeviceFromAPI(device.getId().getId())).as("fetched device").isEqualTo(savedDevice);
|
||||
|
||||
expectedStatuses = Arrays.asList(QUEUED, INITIATED, DOWNLOADING, DOWNLOADED, UPDATING, UPDATED);
|
||||
List<TsKvEntry> ts = await("await on timeseries for FW")
|
||||
.atMost(TIMEOUT, TimeUnit.SECONDS)
|
||||
.until(() -> getFwSwStateTelemetryFromAPI(device.getId().getId(), "fw_state"), this::predicateForStatuses);
|
||||
|
||||
String ver_Id_19 = lwM2MTestClient.getLeshanClient().getObjectTree().getModel().getObjectModel(BINARY_APP_DATA_CONTAINER).version;
|
||||
String resourceIdVer = "/" + BINARY_APP_DATA_CONTAINER + "_" + ver_Id_19 + "/" + FW_INSTANCE_ID + "/" + RESOURCE_ID_0;
|
||||
resultReadOtaParams_19(resourceIdVer, otaPackageInfo);
|
||||
log.warn("Object5: Got the ts: {}", ts);
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,12 +108,14 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
|
||||
public static final String FW_RESULT_ID = "/5/0/5";
|
||||
public static final String FW_NAME_ID = "/5/0/6";
|
||||
public static final String FW_VER_ID = "/5/0/7";
|
||||
public static final String FW_INFO_19_INSTANCE_ID = "/19/65534";
|
||||
public static final String SW_INFO_19_INSTANCE_ID = "/19/65535";
|
||||
public static final int FW_INSTANCE_ID = 65534;
|
||||
public static final String FW_INFO_19_INSTANCE_ID = "/19/" + FW_INSTANCE_ID;
|
||||
public static final int SW_INSTANCE_ID = 65535;
|
||||
public static final String SW_INFO_19_INSTANCE_ID = "/19/" + SW_INSTANCE_ID;
|
||||
public static final String OTA_INFO_19_TITLE = "title";
|
||||
public static final String OTA_INFO_19_VERSION = "version";
|
||||
public static final String OTA_INFO_19_FILE_CHECKSUM256 = "fileChecksumSHA256";
|
||||
public static final String OTA_INFO_19_FILE_SIZE = "fileSize";
|
||||
public static final String OTA_INFO_19_FILE_CHECKSUM256 = "checksum";
|
||||
public static final String OTA_INFO_19_FILE_SIZE = "dataSize";
|
||||
public static final String OTA_INFO_19_FILE_NAME = "fileName";
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user