lwm2m: add Base64 from java.util and add Test FW to objectId=19 jsonNode

This commit is contained in:
nickAS21 2025-04-18 19:24:45 +03:00
parent 33ec93c32d
commit d8435246dd
4 changed files with 65 additions and 13 deletions

View File

@ -16,26 +16,22 @@
package org.thingsboard.server.transport.lwm2m.rpc.sql;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.hash.Hashing;
import org.eclipse.leshan.client.resource.LwM2mObjectEnabler;
import org.eclipse.leshan.core.ResponseCode;
import org.eclipse.leshan.core.node.LwM2mPath;
import org.junit.Test;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.script.api.tbel.TbUtils;
import org.thingsboard.server.transport.lwm2m.rpc.AbstractRpcLwM2MIntegrationTest;
import java.util.Base64;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INSTANCE_ID_0;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INSTANCE_ID_1;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INSTANCE_ID_2;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_0;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_14;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_15;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_9;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_NAME_3_14;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_INSTANCE_ID_2;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.*;
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.*;
public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTest {
@ -77,6 +73,28 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
String expected = "LwM2mSingleResource [id=" + RESOURCE_ID_14 + ", value=" + expectedValue + ", type=STRING]";
assertTrue(actualValues.contains(expected));
}
@Test
public void testWriteReplaceValueMultipleResource_Result_CHANGED_Multi_Instance_Resource_must_One_ValueJsonNodeToBase64() throws Exception {
LwM2mObjectEnabler lwM2mObjectEnabler = lwM2MTestClient.getLeshanClient().getObjectTree().getObjectEnabler(BINARY_APP_DATA_CONTAINER);
if (lwM2mObjectEnabler != null) {
String expectedPath = objectIdVer_19 + "/" + FW_INSTANCE_ID + "/";
String expectedValueStr = getJsonNodeBase64();
String expectedValue = "{\"" + RESOURCE_ID_0 + "\":{\"0\":\"" + expectedValueStr + "\"}}";
String actualResult = sendRPCreateById(expectedPath, expectedValue);
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.CREATED.getName(), rpcActualResult.get("result").asText());
actualResult = sendRPCReadById(expectedPath);
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
String actualValues = rpcActualResult.get("value").asText();
byte[] expectedValue0 = TbUtils.base64ToBytes(expectedValueStr);
String expectedInstance = "LwM2mObjectInstance [id=" + FW_INSTANCE_ID;
assertTrue(actualValues.contains(expectedInstance));
String expected = "{0=LwM2mMultipleResource [id=0, values={0=LwM2mResourceInstance [id=0, value=" + expectedValue0.length + "Bytes, type=OPAQUE]}";
assertTrue(actualValues.contains(expected));
}
}
@Test
public void testWriteReplaceValueMultipleResource_Result_CHANGED_Multi_Instance_Resource_must_One() throws Exception {
int resourceInstanceId0 = 0;
@ -525,4 +543,33 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
String setRpcRequest = "{\"method\": \"WriteComposite\", \"params\": {\"nodes\":" + nodes + "}}";
return doPostAsync("/api/plugins/rpc/twoway/" + lwM2MTestClient.getDeviceIdStr(), setRpcRequest, String.class, status().isOk());
}
/**
* ObjectId = 19/65533/0
* {
* "title" : "My firmware",
* "version" : "fw.v.1.5.0-update",
* "checksum" : "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a",
* "fileSize" : 1,
* "fileName" : "filename.txt"
* }
*/
private String getJsonNodeBase64() {
ObjectNode objectNodeInfoOta = JacksonUtil.newObjectNode();
byte[] firmwareChunk = new byte[]{1};
String fileChecksumSHA256 = Hashing.sha256().hashBytes(firmwareChunk).toString();
objectNodeInfoOta.put(OTA_INFO_19_TITLE, "My firmware");
objectNodeInfoOta.put(OTA_INFO_19_VERSION, "fw.v.1.5.0-update");
objectNodeInfoOta.put(OTA_INFO_19_FILE_CHECKSUM256, fileChecksumSHA256);
objectNodeInfoOta.put(OTA_INFO_19_FILE_SIZE, firmwareChunk.length);
objectNodeInfoOta.put(OTA_INFO_19_FILE_NAME, "filename.txt");
String objectNodeInfoOtaStr = JacksonUtil.toString(objectNodeInfoOta);
assert objectNodeInfoOtaStr != null;
return Base64.getEncoder().encodeToString(objectNodeInfoOtaStr.getBytes());
}
private String sendRPCreateById(String path, String value) throws Exception {
String setRpcRequest = "{\"method\": \"Create\", \"params\": {\"id\": \"" + path + "\", \"value\": " + value + " }}";
return doPostAsync("/api/plugins/rpc/twoway/" + lwM2MTestClient.getDeviceIdStr(), setRpcRequest, String.class, status().isOk());
}
}

View File

@ -99,7 +99,6 @@ import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static org.apache.commons.codec.binary.Base64.isBase64;
import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.DIMENSION;
import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.ENABLER_VERSION;
import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.EVALUATE_MAXIMUM_PERIOD;
@ -114,6 +113,7 @@ import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.SHOR
import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.STEP;
import static org.eclipse.leshan.core.model.ResourceModel.Type.OBJLNK;
import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE;
import static org.thingsboard.server.common.transport.util.JsonUtils.isBase64;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.convertMultiResourceValuesFromRpcBody;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.createModelsDefault;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.fromVersionedIdToObjectId;

View File

@ -701,8 +701,6 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
String objectNodeInfoOtaStr = JacksonUtil.toString(objectNodeInfoOta);
assert objectNodeInfoOtaStr != null;
String objectNodeInfoOtaBase64 = Base64.getEncoder().encodeToString(objectNodeInfoOtaStr.getBytes());
LwM2mPath pathOtaInstance = new LwM2mPath(targetId);
if (client.getRegistration().getAvailableInstances().contains(pathOtaInstance)) {
String versionId = targetIdVer + "/0/0";

View File

@ -23,10 +23,13 @@ import org.thingsboard.server.gen.transport.TransportProtos.KeyValueProto;
import java.util.List;
import java.util.Map;
import static org.apache.commons.codec.binary.Base64.isBase64;
import java.util.regex.Pattern;
public class JsonUtils {
private static final Pattern BASE64_PATTERN =
Pattern.compile("^[A-Za-z0-9+/]+={0,2}$");
public static JsonObject getJsonObject(List<KeyValueProto> tsKv) {
JsonObject json = new JsonObject();
for (KeyValueProto kv : tsKv) {
@ -84,4 +87,8 @@ public class JsonUtils {
return jsonObject;
}
public static boolean isBase64(String value) {
return value.length() % 4 == 0 && BASE64_PATTERN.matcher(value).matches();
}
}