lwm2m: fix bug Content Format M14
This commit is contained in:
parent
e755d0072e
commit
684ad858b2
@ -178,6 +178,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte
|
|||||||
private String[] resources;
|
private String[] resources;
|
||||||
protected String deviceId;
|
protected String deviceId;
|
||||||
protected boolean isWriteAttribute = false;
|
protected boolean isWriteAttribute = false;
|
||||||
|
protected boolean supportFormatOnly_SenMLJSON_SenMLCBOR = false;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void startInit() throws Exception {
|
public void startInit() throws Exception {
|
||||||
@ -318,8 +319,8 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte
|
|||||||
try (ServerSocket socket = new ServerSocket(0)) {
|
try (ServerSocket socket = new ServerSocket(0)) {
|
||||||
int clientPort = socket.getLocalPort();
|
int clientPort = socket.getLocalPort();
|
||||||
lwM2MTestClient.init(security, securityBs, clientPort, isRpc,
|
lwM2MTestClient.init(security, securityBs, clientPort, isRpc,
|
||||||
this.defaultLwM2mUplinkMsgHandlerTest, this.clientContextTest, isWriteAttribute
|
this.defaultLwM2mUplinkMsgHandlerTest, this.clientContextTest, isWriteAttribute,
|
||||||
, clientDtlsCidLength, queueMode);
|
clientDtlsCidLength, queueMode, supportFormatOnly_SenMLJSON_SenMLCBOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -47,10 +47,19 @@ import org.eclipse.leshan.core.model.ObjectModel;
|
|||||||
import org.eclipse.leshan.core.model.StaticModel;
|
import org.eclipse.leshan.core.model.StaticModel;
|
||||||
import org.eclipse.leshan.core.node.codec.DefaultLwM2mDecoder;
|
import org.eclipse.leshan.core.node.codec.DefaultLwM2mDecoder;
|
||||||
import org.eclipse.leshan.core.node.codec.DefaultLwM2mEncoder;
|
import org.eclipse.leshan.core.node.codec.DefaultLwM2mEncoder;
|
||||||
|
import org.eclipse.leshan.core.node.codec.NodeDecoder;
|
||||||
|
import org.eclipse.leshan.core.node.codec.NodeEncoder;
|
||||||
|
import org.eclipse.leshan.core.node.codec.cbor.LwM2mNodeCborDecoder;
|
||||||
|
import org.eclipse.leshan.core.node.codec.cbor.LwM2mNodeCborEncoder;
|
||||||
|
import org.eclipse.leshan.core.node.codec.senml.LwM2mNodeSenMLDecoder;
|
||||||
|
import org.eclipse.leshan.core.node.codec.senml.LwM2mNodeSenMLEncoder;
|
||||||
import org.eclipse.leshan.core.request.BootstrapRequest;
|
import org.eclipse.leshan.core.request.BootstrapRequest;
|
||||||
|
import org.eclipse.leshan.core.request.ContentFormat;
|
||||||
import org.eclipse.leshan.core.request.DeregisterRequest;
|
import org.eclipse.leshan.core.request.DeregisterRequest;
|
||||||
import org.eclipse.leshan.core.request.RegisterRequest;
|
import org.eclipse.leshan.core.request.RegisterRequest;
|
||||||
import org.eclipse.leshan.core.request.UpdateRequest;
|
import org.eclipse.leshan.core.request.UpdateRequest;
|
||||||
|
import org.eclipse.leshan.senml.cbor.upokecenter.SenMLCborUpokecenterEncoderDecoder;
|
||||||
|
import org.eclipse.leshan.senml.json.jackson.SenMLJsonJacksonEncoderDecoder;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
|
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
|
||||||
@ -78,6 +87,7 @@ import static org.eclipse.leshan.core.LwM2mId.LOCATION;
|
|||||||
import static org.eclipse.leshan.core.LwM2mId.SECURITY;
|
import static org.eclipse.leshan.core.LwM2mId.SECURITY;
|
||||||
import static org.eclipse.leshan.core.LwM2mId.SERVER;
|
import static org.eclipse.leshan.core.LwM2mId.SERVER;
|
||||||
import static org.eclipse.leshan.core.LwM2mId.SOFTWARE_MANAGEMENT;
|
import static org.eclipse.leshan.core.LwM2mId.SOFTWARE_MANAGEMENT;
|
||||||
|
import static org.eclipse.leshan.core.node.codec.DefaultLwM2mEncoder.getDefaultPathEncoder;
|
||||||
import static org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest.serverId;
|
import static org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest.serverId;
|
||||||
import static org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest.serverIdBs;
|
import static org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest.serverIdBs;
|
||||||
import static org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest.shortServerId;
|
import static org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest.shortServerId;
|
||||||
@ -130,7 +140,8 @@ public class LwM2MTestClient {
|
|||||||
|
|
||||||
public void init(Security security, Security securityBs, int port, boolean isRpc,
|
public void init(Security security, Security securityBs, int port, boolean isRpc,
|
||||||
LwM2mUplinkMsgHandler defaultLwM2mUplinkMsgHandler,
|
LwM2mUplinkMsgHandler defaultLwM2mUplinkMsgHandler,
|
||||||
LwM2mClientContext clientContext, boolean isWriteAttribute, Integer cIdLength, boolean queueMode) throws InvalidDDFFileException, IOException {
|
LwM2mClientContext clientContext, boolean isWriteAttribute, Integer cIdLength, boolean queueMode,
|
||||||
|
boolean supportFormatOnly_SenMLJSON_SenMLCBOR) throws InvalidDDFFileException, IOException {
|
||||||
Assert.assertNull("client already initialized", leshanClient);
|
Assert.assertNull("client already initialized", leshanClient);
|
||||||
this.defaultLwM2mUplinkMsgHandlerTest = defaultLwM2mUplinkMsgHandler;
|
this.defaultLwM2mUplinkMsgHandlerTest = defaultLwM2mUplinkMsgHandler;
|
||||||
this.clientContext = clientContext;
|
this.clientContext = clientContext;
|
||||||
@ -274,12 +285,28 @@ public class LwM2MTestClient {
|
|||||||
builder.setEndpointsProviders(endpointsProvider.toArray(new LwM2mClientEndpointsProvider[endpointsProvider.size()]));
|
builder.setEndpointsProviders(endpointsProvider.toArray(new LwM2mClientEndpointsProvider[endpointsProvider.size()]));
|
||||||
builder.setDataSenders(new ManualDataSender());
|
builder.setDataSenders(new ManualDataSender());
|
||||||
builder.setRegistrationEngineFactory(engineFactory);
|
builder.setRegistrationEngineFactory(engineFactory);
|
||||||
|
Map<ContentFormat, NodeDecoder> decoders = new HashMap<>();
|
||||||
|
Map<ContentFormat, NodeEncoder> encoders = new HashMap<>();
|
||||||
|
if (supportFormatOnly_SenMLJSON_SenMLCBOR) {
|
||||||
|
// decoders.put(ContentFormat.OPAQUE, new LwM2mNodeOpaqueDecoder());
|
||||||
|
decoders.put(ContentFormat.CBOR, new LwM2mNodeCborDecoder());
|
||||||
|
decoders.put(ContentFormat.SENML_JSON, new LwM2mNodeSenMLDecoder(new SenMLJsonJacksonEncoderDecoder(), true));
|
||||||
|
decoders.put(ContentFormat.SENML_CBOR, new LwM2mNodeSenMLDecoder(new SenMLCborUpokecenterEncoderDecoder(), false));
|
||||||
|
builder.setDecoder(new DefaultLwM2mDecoder(decoders));
|
||||||
|
|
||||||
|
// encoders.put(ContentFormat.OPAQUE, new LwM2mNodeOpaqueEncoder());
|
||||||
|
encoders.put(ContentFormat.CBOR, new LwM2mNodeCborEncoder());
|
||||||
|
encoders.put(ContentFormat.SENML_JSON, new LwM2mNodeSenMLEncoder(new SenMLJsonJacksonEncoderDecoder()));
|
||||||
|
encoders.put(ContentFormat.SENML_CBOR, new LwM2mNodeSenMLEncoder(new SenMLCborUpokecenterEncoderDecoder()));
|
||||||
|
builder.setEncoder(new DefaultLwM2mEncoder(new LwM2mValueConverterImpl(), false));
|
||||||
|
builder.setEncoder(new DefaultLwM2mEncoder(encoders, getDefaultPathEncoder(), new LwM2mValueConverterImpl()));
|
||||||
|
} else {
|
||||||
boolean supportOldFormat = true;
|
boolean supportOldFormat = true;
|
||||||
if (supportOldFormat) {
|
|
||||||
builder.setDecoder(new DefaultLwM2mDecoder(supportOldFormat));
|
builder.setDecoder(new DefaultLwM2mDecoder(supportOldFormat));
|
||||||
builder.setEncoder(new DefaultLwM2mEncoder(new LwM2mValueConverterImpl(), supportOldFormat));
|
builder.setEncoder(new DefaultLwM2mEncoder(new LwM2mValueConverterImpl(), supportOldFormat));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
builder.setRegistrationEngineFactory(engineFactory);
|
builder.setRegistrationEngineFactory(engineFactory);
|
||||||
builder.setSharedExecutor(executor);
|
builder.setSharedExecutor(executor);
|
||||||
|
|
||||||
|
|||||||
@ -86,6 +86,9 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg
|
|||||||
if (this.getClass().getSimpleName().equals("RpcLwm2mIntegrationDiscoverWriteAttributesTest")){
|
if (this.getClass().getSimpleName().equals("RpcLwm2mIntegrationDiscoverWriteAttributesTest")){
|
||||||
isWriteAttribute = true;
|
isWriteAttribute = true;
|
||||||
}
|
}
|
||||||
|
if (this.getClass().getSimpleName().equals("RpcLwm2mIntegrationWriteCborTest")){
|
||||||
|
supportFormatOnly_SenMLJSON_SenMLCBOR = true;
|
||||||
|
}
|
||||||
initRpc();
|
initRpc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2024 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.transport.lwm2m.rpc.sql;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import org.eclipse.leshan.core.ResponseCode;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.thingsboard.common.util.JacksonUtil;
|
||||||
|
import org.thingsboard.server.transport.lwm2m.rpc.AbstractRpcLwM2MIntegrationTest;
|
||||||
|
|
||||||
|
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.RESOURCE_ID_0;
|
||||||
|
|
||||||
|
public class RpcLwm2mIntegrationWriteCborTest extends AbstractRpcLwM2MIntegrationTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client with ContentFormat ={}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource:
|
||||||
|
* <Type>Opaque</Type>
|
||||||
|
* Input type String (HexDec)
|
||||||
|
* WriteReplace {"id": "/19_1.1/0/0","value": {"0":"01234567890CAB"}}
|
||||||
|
* return Hex.decodeHex(((String)value).toCharArray()) - ok [1, 35, 69, 103, -119, 12, -85, -1]
|
||||||
|
* {"result":"CHANGED"} -> Actual Value Equals expectedValue0
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWriteReplaceValueMultipleResource_InputFormatData_Ok_Result_CHANGED_Value_Equals_expectedValue0() throws Exception {
|
||||||
|
String expectedPath = objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0;
|
||||||
|
int resourceInstanceId0 = 0;
|
||||||
|
String expectedValue0 = "01234567890CABFF";
|
||||||
|
String expectedValue = "{\"" + resourceInstanceId0 + "\":\"" + expectedValue0 + "\"}";
|
||||||
|
String actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedValue);
|
||||||
|
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||||
|
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||||
|
String expectedPath0 = expectedPath + "/" + resourceInstanceId0;
|
||||||
|
actualResult = sendRPCReadById(expectedPath0);
|
||||||
|
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||||
|
String actualValues = rpcActualResult.get("value").asText();
|
||||||
|
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length()/2 + "Bytes, type=OPAQUE]";
|
||||||
|
assertTrue(actualValues.contains(expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource:
|
||||||
|
* <Type>Opaque</Type>
|
||||||
|
* Input type String (not HexDec)
|
||||||
|
* return Hex.decodeHex(((String)value).toCharArray()) - error
|
||||||
|
* return Base64.getDecoder().decode(((String) value).getBytes()) - ok;
|
||||||
|
* WriteReplace {"id": "/19_1.1/0/0","value": {"0":"01234567890"}}
|
||||||
|
* {"result":"CHANGED"} -> Actual Value Not Equals expectedValue0
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWriteReplaceValueMultipleResource_Error_InputFormatData_Result_CHANGED_Value_Not_Equals_expectedValue0() throws Exception {
|
||||||
|
String expectedPath = objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0;
|
||||||
|
int resourceInstanceId0 = 0;
|
||||||
|
String expectedValue0 = "01234567890";
|
||||||
|
String expectedValue = "{\"" + resourceInstanceId0 + "\":\"" + expectedValue0 + "\"}";
|
||||||
|
String actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedValue);
|
||||||
|
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||||
|
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||||
|
String expectedPath0 = expectedPath + "/" + resourceInstanceId0;
|
||||||
|
actualResult = sendRPCReadById(expectedPath0);
|
||||||
|
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||||
|
String actualValues = rpcActualResult.get("value").asText();
|
||||||
|
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length()/2 + "Bytes, type=OPAQUE]";
|
||||||
|
assertFalse(actualValues.contains(expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String sendRPCWriteObjectById(String method, String path, Object value) throws Exception {
|
||||||
|
String setRpcRequest = "{\"method\": \"" + method + "\", \"params\": {\"id\": \"" + path + "\", \"value\": " + value + " }}";
|
||||||
|
return doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setRpcRequest, String.class, status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String sendRPCReadById(String id) throws Exception {
|
||||||
|
String setRpcRequest = "{\"method\": \"Read\", \"params\": {\"id\": \"" + id + "\"}}";
|
||||||
|
return doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setRpcRequest, String.class, status().isOk());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,6 +23,7 @@ import org.thingsboard.common.util.JacksonUtil;
|
|||||||
import org.thingsboard.server.transport.lwm2m.rpc.AbstractRpcLwM2MIntegrationTest;
|
import org.thingsboard.server.transport.lwm2m.rpc.AbstractRpcLwM2MIntegrationTest;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
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_0;
|
||||||
@ -107,6 +108,32 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
|
|||||||
assertTrue(actualValues.contains(expected));
|
assertTrue(actualValues.contains(expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource:
|
||||||
|
* <Type>Opaque</Type>
|
||||||
|
* Input type String (not HexDec)
|
||||||
|
* return Hex.decodeHex(((String)value).toCharArray()) - error
|
||||||
|
* return Base64.getDecoder().decode(((String) value).getBytes()) - ok;
|
||||||
|
* WriteReplace {"id": "/19_1.1/0/0","value": {"0":"01234567890"}}
|
||||||
|
* {"result":"CHANGED"} -> Actual Value Not Equals expectedValue0
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWriteReplaceValueMultipleResource_Error_InputFormatData_Result_CHANGED_Value_Not_Equals_expectedValue0() throws Exception {
|
||||||
|
String expectedPath = objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0;
|
||||||
|
int resourceInstanceId0 = 0;
|
||||||
|
String expectedValue0 = "01234567890";
|
||||||
|
String expectedValue = "{\"" + resourceInstanceId0 + "\":\"" + expectedValue0 + "\"}";
|
||||||
|
String actualResult = sendRPCWriteObjectById("WriteReplace", expectedPath, expectedValue);
|
||||||
|
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||||
|
assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText());
|
||||||
|
String expectedPath0 = expectedPath + "/" + resourceInstanceId0;
|
||||||
|
actualResult = sendRPCReadById(expectedPath0);
|
||||||
|
rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
|
||||||
|
String actualValues = rpcActualResult.get("value").asText();
|
||||||
|
String expected = "LwM2mResourceInstance [id=" + resourceInstanceId0 + ", value=" + expectedValue0.length()/2 + "Bytes, type=OPAQUE]";
|
||||||
|
assertFalse(actualValues.contains(expected));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bad: singleResource, operation="R" - only read
|
* bad: singleResource, operation="R" - only read
|
||||||
* WriteReplace {"id":"/3/0/9","value":90}
|
* WriteReplace {"id":"/3/0/9","value":90}
|
||||||
|
|||||||
@ -61,7 +61,6 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
|
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
|
||||||
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LWM2M_OBJECT_VERSION_DEFAULT;
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LWM2M_OBJECT_VERSION_DEFAULT;
|
||||||
@ -417,14 +416,14 @@ public class LwM2mClient {
|
|||||||
|
|
||||||
private static Set<ContentFormat> clientSupportContentFormat(Registration registration) {
|
private static Set<ContentFormat> clientSupportContentFormat(Registration registration) {
|
||||||
Set<ContentFormat> contentFormats = new HashSet<>();
|
Set<ContentFormat> contentFormats = new HashSet<>();
|
||||||
contentFormats.add(ContentFormat.DEFAULT);
|
|
||||||
Attribute ct = Arrays.stream(registration.getObjectLinks())
|
Attribute ct = Arrays.stream(registration.getObjectLinks())
|
||||||
.filter(link -> link.getUriReference().equals("/"))
|
.filter(link -> link.getUriReference().equals("/"))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.map(link -> link.getAttributes().get("ct")).orElse(null);
|
.map(link -> link.getAttributes().get("ct")).orElse(null);
|
||||||
if (ct != null) {
|
if (ct != null && ct.getValue() instanceof Collection<?>) {
|
||||||
Set codes = Stream.of(ct.getValue()).collect(Collectors.toSet());
|
contentFormats.addAll((Collection<? extends ContentFormat>) ct.getValue());
|
||||||
contentFormats.addAll(codes);
|
} else {
|
||||||
|
contentFormats.add(ContentFormat.DEFAULT);
|
||||||
}
|
}
|
||||||
return contentFormats;
|
return contentFormats;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -98,7 +98,6 @@ import java.util.Set;
|
|||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -115,8 +114,6 @@ import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.OBJE
|
|||||||
import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.SERVER_URI;
|
import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.SERVER_URI;
|
||||||
import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.SHORT_SERVER_ID;
|
import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.SHORT_SERVER_ID;
|
||||||
import static org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes.STEP;
|
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.transport.lwm2m.utils.LwM2MTransportUtil.convertMultiResourceValuesFromRpcBody;
|
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.createModelsDefault;
|
||||||
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.fromVersionedIdToObjectId;
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.fromVersionedIdToObjectId;
|
||||||
@ -742,19 +739,8 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
|
|||||||
|
|
||||||
private static ContentFormat getRequestContentFormat(LwM2mClient client, String versionedId, LwM2mModelProvider modelProvider) {
|
private static ContentFormat getRequestContentFormat(LwM2mClient client, String versionedId, LwM2mModelProvider modelProvider) {
|
||||||
LwM2mPath pathIds = new LwM2mPath(fromVersionedIdToObjectId(versionedId));
|
LwM2mPath pathIds = new LwM2mPath(fromVersionedIdToObjectId(versionedId));
|
||||||
if (pathIds.isResource() || pathIds.isResourceInstance()) {
|
if (pathIds.isResourceInstance()) {
|
||||||
ResourceModel resourceModel = client.getResourceModel(versionedId, modelProvider);
|
|
||||||
if (resourceModel != null && (pathIds.isResourceInstance() || (pathIds.isResource() && !resourceModel.multiple))) {
|
|
||||||
if (OBJLNK.equals(resourceModel.type)) {
|
|
||||||
return ContentFormat.LINK;
|
|
||||||
} else if (OPAQUE.equals(resourceModel.type)) {
|
|
||||||
return ContentFormat.OPAQUE;
|
|
||||||
} else {
|
|
||||||
return findFirstContentFormatForComp(client.getClientSupportContentFormats(), client.getDefaultContentFormat(), ContentFormat.CBOR, ContentFormat.SENML_CBOR, ContentFormat.SENML_JSON);
|
return findFirstContentFormatForComp(client.getClientSupportContentFormats(), client.getDefaultContentFormat(), ContentFormat.CBOR, ContentFormat.SENML_CBOR, ContentFormat.SENML_JSON);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return getContentFormatForComplex(client);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return getContentFormatForComplex(client);
|
return getContentFormatForComplex(client);
|
||||||
}
|
}
|
||||||
@ -783,37 +769,21 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ContentFormat findFirstContentFormatForComposite (Set<?> clientSupportContentFormats) {
|
private ContentFormat findFirstContentFormatForComposite (Set<ContentFormat> clientSupportContentFormats) {
|
||||||
ContentFormat contentFormat = findFirstContentFormatForComp(clientSupportContentFormats, null, ContentFormat.SENML_JSON, ContentFormat.SENML_CBOR);
|
ContentFormat contentFormat = findFirstContentFormatForComp(clientSupportContentFormats, null, ContentFormat.SENML_CBOR, ContentFormat.SENML_JSON);
|
||||||
if (contentFormat != null) {
|
if (contentFormat != null) {
|
||||||
return contentFormat;
|
return contentFormat;
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("This device does not support Composite Operation");
|
throw new RuntimeException("This device does not support Composite Operation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static ContentFormat findFirstContentFormatForComp(Set<?> clientSupportContentFormats, ContentFormat defaultValue, ContentFormat... desiredFormats) {
|
private static ContentFormat findFirstContentFormatForComp(Set<ContentFormat> clientSupportContentFormats, ContentFormat defaultValue, ContentFormat... desiredFormats) {
|
||||||
AtomicReference<ContentFormat> compositeContentFormat = new AtomicReference<>();
|
List desiredFormatsList = Arrays.asList(desiredFormats);
|
||||||
clientSupportContentFormats.forEach(c -> {
|
for (ContentFormat c : clientSupportContentFormats) {
|
||||||
if (c instanceof Collection) {
|
if (desiredFormatsList.contains(c)) {
|
||||||
for (ContentFormat contentFormat : desiredFormats) {
|
return c;
|
||||||
if (((Collection<?>) c).contains(contentFormat)) {
|
|
||||||
compositeContentFormat.set(contentFormat);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (compositeContentFormat.get() == null && c instanceof ContentFormat) {
|
return defaultValue;
|
||||||
compositeContentFormat.set(Arrays.stream(desiredFormats).filter(f -> f.equals(c)).findFirst().get());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return compositeContentFormat.get() != null ? compositeContentFormat.get() : defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> boolean containsObserveComposite(List<T> l1, List<T> l2) {
|
|
||||||
for (T elem : l1) {
|
|
||||||
if (l2.contains(elem)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user