|
|
|
@ -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()); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|