Lwm2m Fix bug review edit tests
This commit is contained in:
parent
16a520cd80
commit
0a9553b83c
@ -261,6 +261,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest
|
|||||||
client = new LwM2MTestClient(this.executor, this.endpoint);
|
client = new LwM2MTestClient(this.executor, this.endpoint);
|
||||||
int clientPort = SocketUtils.findAvailableTcpPort();
|
int clientPort = SocketUtils.findAvailableTcpPort();
|
||||||
client.init(security, coapConfig, clientPort);
|
client.init(security, coapConfig, clientPort);
|
||||||
|
client.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clientDestroy() {
|
private void clientDestroy() {
|
||||||
|
|||||||
@ -250,8 +250,6 @@ public class LwM2MTestClient {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.client.addObserver(observer);
|
this.client.addObserver(observer);
|
||||||
|
|
||||||
client.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
@ -278,4 +276,10 @@ public class LwM2MTestClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
if (client != null) {
|
||||||
|
client.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,63 +50,7 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resources;
|
|||||||
@DaoSqlTest
|
@DaoSqlTest
|
||||||
public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest {
|
public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest {
|
||||||
|
|
||||||
protected final String RPC_TRANSPORT_CONFIGURATION = "{\n" +
|
protected String RPC_TRANSPORT_CONFIGURATION;
|
||||||
" \"type\": \"LWM2M\",\n" +
|
|
||||||
" \"observeAttr\": {\n" +
|
|
||||||
" \"keyName\": {\n" +
|
|
||||||
" \"" + "/" + DEVICE + "/" + objectInstanceId_0 + "/" + resourceId_9 + "\": \"" + resourceIdName_3_9 + "\",\n" +
|
|
||||||
" \"" + "/" + DEVICE + "/" + objectInstanceId_0 + "/" + resourceId_14 + "\": \"" + resourceIdName_3_14 + "\",\n" +
|
|
||||||
" \"" + "/" + BINARY_APP_DATA_CONTAINER + "/" + objectInstanceId_0 + "/" + resourceId_0 + "\": \"" + resourceIdName_19_0_0 + "\",\n" +
|
|
||||||
" \"" + "/" + BINARY_APP_DATA_CONTAINER + "/" + objectInstanceId_1 + "/" + resourceId_0 + "\": \"" + resourceIdName_19_1_0 + "\"\n" +
|
|
||||||
" },\n" +
|
|
||||||
" \"observe\": [\n" +
|
|
||||||
" \"" + "/" + DEVICE + "/" + objectInstanceId_0 + "/" + resourceId_9 + "\",\n" +
|
|
||||||
" \"" + "/" + BINARY_APP_DATA_CONTAINER + "/" + objectInstanceId_0 + "/" + resourceId_0 + "\"\n" +
|
|
||||||
" ],\n" +
|
|
||||||
" \"attribute\": [\n" +
|
|
||||||
" ],\n" +
|
|
||||||
" \"telemetry\": [\n" +
|
|
||||||
" \"" + "/" + DEVICE + "/" + objectInstanceId_0 + "/" + resourceId_9 + "\",\n" +
|
|
||||||
" \"" + "/" + DEVICE + "/" + objectInstanceId_0 + "/" + resourceId_14 + "\",\n" +
|
|
||||||
" \"" + "/" + BINARY_APP_DATA_CONTAINER + "/" + objectInstanceId_0 + "/" + resourceId_0 + "\",\n" +
|
|
||||||
" \"" + "/" + BINARY_APP_DATA_CONTAINER + "/" + objectInstanceId_1 + "/" + resourceId_0 + "\"\n" +
|
|
||||||
" ],\n" +
|
|
||||||
" \"attributeLwm2m\": {}\n" +
|
|
||||||
" },\n" +
|
|
||||||
" \"bootstrap\": {\n" +
|
|
||||||
" \"servers\": {\n" +
|
|
||||||
" \"binding\": \"U\",\n" +
|
|
||||||
" \"shortId\": 123,\n" +
|
|
||||||
" \"lifetime\": 300,\n" +
|
|
||||||
" \"notifIfDisabled\": true,\n" +
|
|
||||||
" \"defaultMinPeriod\": 1\n" +
|
|
||||||
" },\n" +
|
|
||||||
" \"lwm2mServer\": {\n" +
|
|
||||||
" \"host\": \"localhost\",\n" +
|
|
||||||
" \"port\": 5686,\n" +
|
|
||||||
" \"serverId\": 123,\n" +
|
|
||||||
" \"serverPublicKey\": \"\",\n" +
|
|
||||||
" \"bootstrapServerIs\": false,\n" +
|
|
||||||
" \"clientHoldOffTime\": 1,\n" +
|
|
||||||
" \"bootstrapServerAccountTimeout\": 0\n" +
|
|
||||||
" },\n" +
|
|
||||||
" \"bootstrapServer\": {\n" +
|
|
||||||
" \"host\": \"localhost\",\n" +
|
|
||||||
" \"port\": 5687,\n" +
|
|
||||||
" \"serverId\": 111,\n" +
|
|
||||||
" \"securityMode\": \"NO_SEC\",\n" +
|
|
||||||
" \"serverPublicKey\": \"\",\n" +
|
|
||||||
" \"bootstrapServerIs\": true,\n" +
|
|
||||||
" \"clientHoldOffTime\": 1,\n" +
|
|
||||||
" \"bootstrapServerAccountTimeout\": 0\n" +
|
|
||||||
" }\n" +
|
|
||||||
" },\n" +
|
|
||||||
" \"clientLwM2mSettings\": {\n" +
|
|
||||||
" \"clientOnlyObserveAfterConnect\": 1,\n" +
|
|
||||||
" \"fwUpdateStrategy\": 1,\n" +
|
|
||||||
" \"swUpdateStrategy\": 1\n" +
|
|
||||||
" }\n" +
|
|
||||||
"}";
|
|
||||||
|
|
||||||
protected static final String ENDPOINT_RPC = "deviceEndpointRpc";
|
protected static final String ENDPOINT_RPC = "deviceEndpointRpc";
|
||||||
protected ScheduledExecutorService executor;
|
protected ScheduledExecutorService executor;
|
||||||
@ -137,13 +81,6 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg
|
|||||||
@Before
|
@Before
|
||||||
public void beforeTest() throws Exception {
|
public void beforeTest() throws Exception {
|
||||||
init();
|
init();
|
||||||
createDeviceProfile(RPC_TRANSPORT_CONFIGURATION);
|
|
||||||
|
|
||||||
Thread.sleep(1000);
|
|
||||||
|
|
||||||
NoSecClientCredentials credentials = createNoSecClientCredentials(ENDPOINT_RPC);
|
|
||||||
final Device device = createDevice(credentials);
|
|
||||||
deviceId = device.getId().getId().toString();
|
|
||||||
createNewClient (SECURITY, COAP_CONFIG);
|
createNewClient (SECURITY, COAP_CONFIG);
|
||||||
|
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
@ -182,6 +119,75 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg
|
|||||||
objectInstanceIdVer_3 = (String) expectedObjectIdVerInstances.stream().filter(predicate_3).findFirst().get();
|
objectInstanceIdVer_3 = (String) expectedObjectIdVerInstances.stream().filter(predicate_3).findFirst().get();
|
||||||
objectInstanceIdVer_5 = (String) expectedObjectIdVerInstances.stream().filter(path -> ((String) path).contains("/" + FIRMWARE)).findFirst().get();
|
objectInstanceIdVer_5 = (String) expectedObjectIdVerInstances.stream().filter(path -> ((String) path).contains("/" + FIRMWARE)).findFirst().get();
|
||||||
objectInstanceIdVer_9 = (String) expectedObjectIdVerInstances.stream().filter(path -> ((String) path).contains("/" + SOFTWARE_MANAGEMENT)).findFirst().get();
|
objectInstanceIdVer_9 = (String) expectedObjectIdVerInstances.stream().filter(path -> ((String) path).contains("/" + SOFTWARE_MANAGEMENT)).findFirst().get();
|
||||||
|
|
||||||
|
RPC_TRANSPORT_CONFIGURATION = "{\n" +
|
||||||
|
" \"type\": \"LWM2M\",\n" +
|
||||||
|
" \"observeAttr\": {\n" +
|
||||||
|
" \"keyName\": {\n" +
|
||||||
|
" \"" + objectIdVer_3 + "/" + objectInstanceId_0 + "/" + resourceId_9 + "\": \"" + resourceIdName_3_9 + "\",\n" +
|
||||||
|
" \"" + objectIdVer_3 + "/" + objectInstanceId_0 + "/" + resourceId_14 + "\": \"" + resourceIdName_3_14 + "\",\n" +
|
||||||
|
" \"" + objectIdVer_19 + "/" + objectInstanceId_0 + "/" + resourceId_0 + "\": \"" + resourceIdName_19_0_0 + "\",\n" +
|
||||||
|
" \"" + objectIdVer_19 + "/" + objectInstanceId_1 + "/" + resourceId_0 + "\": \"" + resourceIdName_19_1_0 + "\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"observe\": [\n" +
|
||||||
|
" \"" + objectIdVer_3 + "/" + objectInstanceId_0 + "/" + resourceId_9 + "\",\n" +
|
||||||
|
" \"" + objectIdVer_19 + "/" + objectInstanceId_0 + "/" + resourceId_0 + "\"\n" +
|
||||||
|
" ],\n" +
|
||||||
|
" \"attribute\": [\n" +
|
||||||
|
" ],\n" +
|
||||||
|
" \"telemetry\": [\n" +
|
||||||
|
" \"" + objectIdVer_3 + "/" + objectInstanceId_0 + "/" + resourceId_9 + "\",\n" +
|
||||||
|
" \"" + objectIdVer_3 + "/" + objectInstanceId_0 + "/" + resourceId_14 + "\",\n" +
|
||||||
|
" \"" + objectIdVer_19 + "/" + objectInstanceId_0 + "/" + resourceId_0 + "\",\n" +
|
||||||
|
" \"" + objectIdVer_19 + "/" + objectInstanceId_1 + "/" + resourceId_0 + "\"\n" +
|
||||||
|
" ],\n" +
|
||||||
|
" \"attributeLwm2m\": {}\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"bootstrap\": {\n" +
|
||||||
|
" \"servers\": {\n" +
|
||||||
|
" \"binding\": \"U\",\n" +
|
||||||
|
" \"shortId\": 123,\n" +
|
||||||
|
" \"lifetime\": 300,\n" +
|
||||||
|
" \"notifIfDisabled\": true,\n" +
|
||||||
|
" \"defaultMinPeriod\": 1\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"lwm2mServer\": {\n" +
|
||||||
|
" \"host\": \"localhost\",\n" +
|
||||||
|
" \"port\": 5686,\n" +
|
||||||
|
" \"serverId\": 123,\n" +
|
||||||
|
" \"serverPublicKey\": \"\",\n" +
|
||||||
|
" \"bootstrapServerIs\": false,\n" +
|
||||||
|
" \"clientHoldOffTime\": 1,\n" +
|
||||||
|
" \"bootstrapServerAccountTimeout\": 0\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"bootstrapServer\": {\n" +
|
||||||
|
" \"host\": \"localhost\",\n" +
|
||||||
|
" \"port\": 5687,\n" +
|
||||||
|
" \"serverId\": 111,\n" +
|
||||||
|
" \"securityMode\": \"NO_SEC\",\n" +
|
||||||
|
" \"serverPublicKey\": \"\",\n" +
|
||||||
|
" \"bootstrapServerIs\": true,\n" +
|
||||||
|
" \"clientHoldOffTime\": 1,\n" +
|
||||||
|
" \"bootstrapServerAccountTimeout\": 0\n" +
|
||||||
|
" }\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"clientLwM2mSettings\": {\n" +
|
||||||
|
" \"clientOnlyObserveAfterConnect\": 1,\n" +
|
||||||
|
" \"fwUpdateStrategy\": 1,\n" +
|
||||||
|
" \"swUpdateStrategy\": 1\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}";
|
||||||
|
createDeviceProfile(RPC_TRANSPORT_CONFIGURATION);
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
NoSecClientCredentials credentials = createNoSecClientCredentials(ENDPOINT_RPC);
|
||||||
|
final Device device = createDevice(credentials);
|
||||||
|
deviceId = device.getId().getId().toString();
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
client.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String pathIdVerToObjectId(String pathIdVer) {
|
protected String pathIdVerToObjectId(String pathIdVer) {
|
||||||
@ -192,4 +198,5 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg
|
|||||||
}
|
}
|
||||||
return pathIdVer;
|
return pathIdVer;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -121,7 +121,7 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
|
|||||||
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||||
assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText());
|
assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText());
|
||||||
String actualValues = rpcActualResult.get("error").asText();
|
String actualValues = rpcActualResult.get("error").asText();
|
||||||
String expected = "Resource value is: String. Value of Multi-Instance Resource must be in Json format!";
|
String expected = "is bad. Value of Multi-Instance Resource must be in Json format!";
|
||||||
assertTrue(actualValues.contains(expected));
|
assertTrue(actualValues.contains(expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,6 @@ package org.thingsboard.server.transport.lwm2m.server.attributes;
|
|||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.leshan.core.model.ResourceModel;
|
import org.eclipse.leshan.core.model.ResourceModel;
|
||||||
@ -223,8 +222,15 @@ public class DefaultLwM2MAttributesService implements LwM2MAttributesService {
|
|||||||
if (!resourceModel.multiple || !(newValProto instanceof JsonElement)) {
|
if (!resourceModel.multiple || !(newValProto instanceof JsonElement)) {
|
||||||
this.pushUpdateToClientIfNeeded(lwM2MClient, oldResourceValue, newValProto, pathIdVer, logFailedUpdateOfNonChangedValue, resourceModel.type);
|
this.pushUpdateToClientIfNeeded(lwM2MClient, oldResourceValue, newValProto, pathIdVer, logFailedUpdateOfNonChangedValue, resourceModel.type);
|
||||||
} else {
|
} else {
|
||||||
|
try {
|
||||||
pushUpdateMultiToClientIfNeeded(lwM2MClient, resourceModel, (JsonElement) newValProto,
|
pushUpdateMultiToClientIfNeeded(lwM2MClient, resourceModel, (JsonElement) newValProto,
|
||||||
(Map<Integer, LwM2mResourceInstance>) oldResourceValue, pathIdVer, logFailedUpdateOfNonChangedValue);
|
(Map<Integer, LwM2mResourceInstance>) oldResourceValue, pathIdVer, logFailedUpdateOfNonChangedValue);
|
||||||
|
} catch (Exception e){
|
||||||
|
log.error("Failed update resource ["+lwM2MClient.getEndpoint()+"] onAttributesUpdate:", e);
|
||||||
|
String logMsg = String.format("%s: Failed update resource onAttributesUpdate %s.",
|
||||||
|
LOG_LWM2M_ERROR, e.getMessage());
|
||||||
|
logService.log(lwM2MClient, logMsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -250,8 +256,9 @@ public class DefaultLwM2MAttributesService implements LwM2MAttributesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void pushUpdateMultiToClientIfNeeded(LwM2mClient client, ResourceModel resourceModel, JsonElement newValProto,
|
private void pushUpdateMultiToClientIfNeeded(LwM2mClient client, ResourceModel resourceModel, JsonElement newValProto,
|
||||||
Map<Integer, LwM2mResourceInstance> valueOld, String versionedId, boolean logFailedUpdateOfNonChangedValue) {
|
Map<Integer, LwM2mResourceInstance> valueOld, String versionedId,
|
||||||
Map newValues = convertMultiResourceValuesFromJson((JsonObject) newValProto, resourceModel.type, versionedId);
|
boolean logFailedUpdateOfNonChangedValue) throws Exception {
|
||||||
|
Map newValues = convertMultiResourceValuesFromJson(newValProto, resourceModel.type, versionedId);
|
||||||
if (newValues.size() > 0 && valueOld != null && valueOld.size() > 0) {
|
if (newValues.size() > 0 && valueOld != null && valueOld.size() > 0) {
|
||||||
valueOld.values().stream().forEach((v) -> {
|
valueOld.values().stream().forEach((v) -> {
|
||||||
if (newValues.containsKey(v.getId())) {
|
if (newValues.containsKey(v.getId())) {
|
||||||
|
|||||||
@ -334,8 +334,8 @@ public class LwM2mClient implements Serializable {
|
|||||||
Map values = convertMultiResourceValuesFromRpcBody(value, resourceModel.type, pathRezIdVer);
|
Map values = convertMultiResourceValuesFromRpcBody(value, resourceModel.type, pathRezIdVer);
|
||||||
resource = LwM2mMultipleResource.newResource(resourceId, (Map<Integer, ?>) values, resourceModel.type);
|
resource = LwM2mMultipleResource.newResource(resourceId, (Map<Integer, ?>) values, resourceModel.type);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new IllegalArgumentException("Resource id=" + resourceId + ", value = " + value + ", class = " +
|
throw new IllegalArgumentException("Resource id=" + resourceId + ", class = " +
|
||||||
value.getClass().getSimpleName() + "is bad. Value of Multi-Instance Resource must be in Json format!");
|
value.getClass().getSimpleName() + ", value = " + value + " is bad. Value of Multi-Instance Resource must be in Json format!");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Object valueRez = value instanceof Integer ? ((Integer) value).longValue() : value;
|
Object valueRez = value instanceof Integer ? ((Integer) value).longValue() : value;
|
||||||
|
|||||||
@ -378,9 +378,10 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
|
|||||||
resultIds.getObjectInstanceId(), resultIds.getResourceId(),
|
resultIds.getObjectInstanceId(), resultIds.getResourceId(),
|
||||||
value, resourceModelWrite.type);
|
value, resourceModelWrite.type);
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
callback.onValidationError(toString(request), "Resource id=" + resultIds.toString() + ", value = " +
|
callback.onValidationError(toString(request), "Resource id=" + resultIds.toString() +
|
||||||
request.getValue() + ", class = " + request.getValue().getClass().getSimpleName() +
|
", class = " + request.getValue().getClass().getSimpleName() +
|
||||||
"is bad. Value of Multi-Instance Resource must be in Json format!");
|
", value = " + request.getValue() + " is bad. " +
|
||||||
|
"Value of Multi-Instance Resource must be in Json format!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -408,9 +409,11 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
|
|||||||
validateVersionedId(client, request);
|
validateVersionedId(client, request);
|
||||||
CreateRequest downlink = null;
|
CreateRequest downlink = null;
|
||||||
LwM2mPath resultIds = new LwM2mPath(request.getObjectId());
|
LwM2mPath resultIds = new LwM2mPath(request.getObjectId());
|
||||||
ObjectModel objectModel = client.getObjectModel(request.getObjectId(), this.config.getModelProvider());
|
ObjectModel objectModel = client.getObjectModel(request.getVersionedId(), this.config.getModelProvider());
|
||||||
// POST /{Object ID}/{Object Instance ID} && Resources is Mandatory
|
// POST /{Object ID}/{Object Instance ID} && Resources is Mandatory
|
||||||
|
if (objectModel != null) {
|
||||||
if (objectModel.multiple) {
|
if (objectModel.multiple) {
|
||||||
|
|
||||||
// LwM2M CBOR, SenML CBOR, SenML JSON, or TLV (see [LwM2M-CORE])
|
// LwM2M CBOR, SenML CBOR, SenML JSON, or TLV (see [LwM2M-CORE])
|
||||||
ContentFormat contentFormat = getWriteRequestContentFormat(client, request, this.config.getModelProvider());
|
ContentFormat contentFormat = getWriteRequestContentFormat(client, request, this.config.getModelProvider());
|
||||||
if (resultIds.isObject() || resultIds.isObjectInstance()) {
|
if (resultIds.isObject() || resultIds.isObjectInstance()) {
|
||||||
@ -440,11 +443,14 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
|
|||||||
sendSimpleRequest(client, downlink, request.getTimeout(), callback);
|
sendSimpleRequest(client, downlink, request.getTimeout(), callback);
|
||||||
} else {
|
} else {
|
||||||
callback.onValidationError(toString(request), "Path " + request.getVersionedId() +
|
callback.onValidationError(toString(request), "Path " + request.getVersionedId() +
|
||||||
". This operation can only be used for created new ObjectInstance !");
|
". Object must be Multiple !");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Path " + request.getVersionedId() +
|
throw new IllegalArgumentException("Path " + request.getVersionedId() + ". Object must be Multiple !");
|
||||||
". Object must be Multiple !");
|
}
|
||||||
|
} else {
|
||||||
|
callback.onValidationError(toString(request), "Resource " + request.getVersionedId() +
|
||||||
|
" is not configured in the device profile!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.transport.lwm2m.server.rpc;
|
package org.thingsboard.server.transport.lwm2m.server.rpc;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -260,8 +261,8 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler {
|
|||||||
Map value = convertMultiResourceValuesFromRpcBody(requestBody.getValue(), resourceModel.type, versionedId);
|
Map value = convertMultiResourceValuesFromRpcBody(requestBody.getValue(), resourceModel.type, versionedId);
|
||||||
requestBody.setValue(value);
|
requestBody.setValue(value);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new IllegalArgumentException("Resource id=" + versionedId + ", value = " + requestBody.getValue() + ", class = " +
|
throw new IllegalArgumentException("Resource id=" + versionedId + ", class = " +
|
||||||
requestBody.getValue().getClass().getSimpleName() + "is bad. Value of Multi-Instance Resource must be in Json format!");
|
requestBody.getValue().getClass().getSimpleName() + ", value = " + requestBody.getValue() + " is bad. Value of Multi-Instance Resource must be in Json format!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -300,21 +301,28 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler {
|
|||||||
String versionedId;
|
String versionedId;
|
||||||
try {
|
try {
|
||||||
// validate key.toString()
|
// validate key.toString()
|
||||||
new LwM2mPath(fromVersionedIdToObjectId(key.toString()));
|
LwM2mPath path = new LwM2mPath(fromVersionedIdToObjectId(key.toString()));
|
||||||
|
if (path.isResource() || path.isResourceInstance()) {
|
||||||
versionedId = key.toString();
|
versionedId = key.toString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalArgumentException(String.format("nodes: %s is not validate value. " +
|
||||||
|
"The WriteComposite operation is only used for SingleResources or/and ResourceInstance.", nodes.toString()));
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
versionedId = clientContext.getObjectIdByKeyNameFromProfile(client, key.toString());
|
versionedId = clientContext.getObjectIdByKeyNameFromProfile(client, key.toString());
|
||||||
}
|
}
|
||||||
// validate value. Must be only primitive, not Json
|
// validate value. Must be only primitive, not JsonObject or JsonArray
|
||||||
try {
|
try {
|
||||||
JsonUtils.parse(value.toString());
|
JsonElement element = JsonUtils.parse(value.toString());
|
||||||
|
if (!element.isJsonNull() && !element.isJsonPrimitive()) {
|
||||||
throw new IllegalArgumentException(String.format("nodes: %s is not validate value. " +
|
throw new IllegalArgumentException(String.format("nodes: %s is not validate value. " +
|
||||||
"The WriteComposite operation is only used for SingleResources or/and ResourceInstance.", nodes.toString()));
|
"The WriteComposite operation is only used for SingleResources or/and ResourceInstance.", nodes.toString()));
|
||||||
|
}
|
||||||
|
else if (versionedId != null) {
|
||||||
|
newNodes.put(fromVersionedIdToObjectId(versionedId), value);
|
||||||
|
}
|
||||||
} catch (JsonSyntaxException jse) {
|
} catch (JsonSyntaxException jse) {
|
||||||
// if (value instanceof LinkedHashMap) {
|
|
||||||
// throw new IllegalArgumentException(String.format("nodes: %s is not validate value. " +
|
|
||||||
// "The WriteComposite operation is only used for SingleResources or/and ResourceInstance.", nodes.toString()));
|
|
||||||
// }
|
|
||||||
if (versionedId != null) {
|
if (versionedId != null) {
|
||||||
newNodes.put(fromVersionedIdToObjectId(versionedId), value);
|
newNodes.put(fromVersionedIdToObjectId(versionedId), value);
|
||||||
}
|
}
|
||||||
@ -356,8 +364,8 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler {
|
|||||||
return targetId;
|
return targetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] getIdsFromParameters(LwM2mClient client, TransportProtos.ToDeviceRpcRequestMsg rpcRequst) {
|
private String[] getIdsFromParameters(LwM2mClient client, TransportProtos.ToDeviceRpcRequestMsg rpcRequest) {
|
||||||
RpcReadCompositeRequest requestParams = JacksonUtil.fromString(rpcRequst.getParams(), RpcReadCompositeRequest.class);
|
RpcReadCompositeRequest requestParams = JacksonUtil.fromString(rpcRequest.getParams(), RpcReadCompositeRequest.class);
|
||||||
if (requestParams.getKeys() != null && requestParams.getKeys().length > 0) {
|
if (requestParams.getKeys() != null && requestParams.getKeys().length > 0) {
|
||||||
Set<String> targetIds = ConcurrentHashMap.newKeySet();
|
Set<String> targetIds = ConcurrentHashMap.newKeySet();
|
||||||
for (String key : requestParams.getKeys()) {
|
for (String key : requestParams.getKeys()) {
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
package org.thingsboard.server.transport.lwm2m.utils;
|
package org.thingsboard.server.transport.lwm2m.utils;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonElement;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.leshan.core.attributes.Attribute;
|
import org.eclipse.leshan.core.attributes.Attribute;
|
||||||
@ -214,12 +214,12 @@ public class LwM2mTransportUtil {
|
|||||||
String[] keyArray = path.split(LWM2M_SEPARATOR_PATH);
|
String[] keyArray = path.split(LWM2M_SEPARATOR_PATH);
|
||||||
if (keyArray.length > 1) {
|
if (keyArray.length > 1) {
|
||||||
String[] keyArrayVer = keyArray[1].split(LWM2M_SEPARATOR_KEY);
|
String[] keyArrayVer = keyArray[1].split(LWM2M_SEPARATOR_KEY);
|
||||||
return keyArrayVer.length == 2 ? keyArrayVer[1] : null;
|
return keyArrayVer.length == 2 ? keyArrayVer[1] : LWM2M_OBJECT_VERSION_DEFAULT;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return LWM2M_OBJECT_VERSION_DEFAULT;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String validPathIdVer(String pathIdVer, Registration registration) throws
|
public static String validPathIdVer(String pathIdVer, Registration registration) throws
|
||||||
@ -355,10 +355,11 @@ public class LwM2mTransportUtil {
|
|||||||
|
|
||||||
public static Map convertMultiResourceValuesFromRpcBody(Object value, ResourceModel.Type type, String versionedId) throws Exception {
|
public static Map convertMultiResourceValuesFromRpcBody(Object value, ResourceModel.Type type, String versionedId) throws Exception {
|
||||||
String valueJsonStr = JsonUtils.riteValueAsString(value);
|
String valueJsonStr = JsonUtils.riteValueAsString(value);
|
||||||
return convertMultiResourceValuesFromJson((JsonObject) JsonUtils.parse(valueJsonStr), type, versionedId);
|
JsonElement element = JsonUtils.parse(valueJsonStr);
|
||||||
|
return convertMultiResourceValuesFromJson(element, type, versionedId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map convertMultiResourceValuesFromJson(JsonObject newValProto, ResourceModel.Type type, String versionedId) {
|
public static Map convertMultiResourceValuesFromJson(JsonElement newValProto, ResourceModel.Type type, String versionedId) throws Exception{
|
||||||
Map newValues = equalsMultiResourceValuesResourceType(type);
|
Map newValues = equalsMultiResourceValuesResourceType(type);
|
||||||
newValProto.getAsJsonObject().entrySet().forEach((obj) -> {
|
newValProto.getAsJsonObject().entrySet().forEach((obj) -> {
|
||||||
newValues.put(Integer.valueOf(obj.getKey()), LwM2mValueConverterImpl.getInstance().convertValue(obj.getValue().getAsString(),
|
newValues.put(Integer.valueOf(obj.getKey()), LwM2mValueConverterImpl.getInstance().convertValue(obj.getValue().getAsString(),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user