Merge pull request #10844 from thingsboard/fix_bug_defaultContentFormat
fix bug lwm2m Content Format M14
This commit is contained in:
		
						commit
						30d0e3b03e
					
				@ -178,6 +178,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte
 | 
			
		||||
    private String[] resources;
 | 
			
		||||
    protected String deviceId;
 | 
			
		||||
    protected boolean isWriteAttribute = false;
 | 
			
		||||
    protected boolean supportFormatOnly_SenMLJSON_SenMLCBOR = false;
 | 
			
		||||
 | 
			
		||||
    @Before
 | 
			
		||||
    public void startInit() throws Exception {
 | 
			
		||||
@ -318,8 +319,8 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte
 | 
			
		||||
        try (ServerSocket socket = new ServerSocket(0)) {
 | 
			
		||||
            int clientPort = socket.getLocalPort();
 | 
			
		||||
            lwM2MTestClient.init(security, securityBs, clientPort, isRpc,
 | 
			
		||||
                    this.defaultLwM2mUplinkMsgHandlerTest, this.clientContextTest, isWriteAttribute
 | 
			
		||||
                    , clientDtlsCidLength, queueMode);
 | 
			
		||||
                    this.defaultLwM2mUplinkMsgHandlerTest, this.clientContextTest, isWriteAttribute,
 | 
			
		||||
                    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.node.codec.DefaultLwM2mDecoder;
 | 
			
		||||
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.ContentFormat;
 | 
			
		||||
import org.eclipse.leshan.core.request.DeregisterRequest;
 | 
			
		||||
import org.eclipse.leshan.core.request.RegisterRequest;
 | 
			
		||||
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.mockito.Mockito;
 | 
			
		||||
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.SERVER;
 | 
			
		||||
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.serverIdBs;
 | 
			
		||||
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,
 | 
			
		||||
                     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);
 | 
			
		||||
        this.defaultLwM2mUplinkMsgHandlerTest = defaultLwM2mUplinkMsgHandler;
 | 
			
		||||
        this.clientContext = clientContext;
 | 
			
		||||
@ -274,12 +285,28 @@ public class LwM2MTestClient {
 | 
			
		||||
        builder.setEndpointsProviders(endpointsProvider.toArray(new LwM2mClientEndpointsProvider[endpointsProvider.size()]));
 | 
			
		||||
        builder.setDataSenders(new ManualDataSender());
 | 
			
		||||
        builder.setRegistrationEngineFactory(engineFactory);
 | 
			
		||||
        boolean supportOldFormat =  true;
 | 
			
		||||
        if (supportOldFormat) {
 | 
			
		||||
        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;
 | 
			
		||||
            builder.setDecoder(new DefaultLwM2mDecoder(supportOldFormat));
 | 
			
		||||
            builder.setEncoder(new DefaultLwM2mEncoder(new LwM2mValueConverterImpl(), supportOldFormat));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        builder.setRegistrationEngineFactory(engineFactory);
 | 
			
		||||
        builder.setSharedExecutor(executor);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -86,6 +86,9 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg
 | 
			
		||||
        if (this.getClass().getSimpleName().equals("RpcLwm2mIntegrationDiscoverWriteAttributesTest")){
 | 
			
		||||
            isWriteAttribute = true;
 | 
			
		||||
        }
 | 
			
		||||
        if (this.getClass().getSimpleName().equals("RpcLwm2mIntegrationWriteCborTest")){
 | 
			
		||||
            supportFormatOnly_SenMLJSON_SenMLCBOR = true;
 | 
			
		||||
        }
 | 
			
		||||
        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 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;
 | 
			
		||||
@ -107,6 +108,32 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
 | 
			
		||||
        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
 | 
			
		||||
     * 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.ReentrantLock;
 | 
			
		||||
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.transport.lwm2m.utils.LwM2MTransportUtil.LWM2M_OBJECT_VERSION_DEFAULT;
 | 
			
		||||
@ -417,14 +416,14 @@ public class LwM2mClient {
 | 
			
		||||
 | 
			
		||||
    private static Set<ContentFormat> clientSupportContentFormat(Registration registration) {
 | 
			
		||||
        Set<ContentFormat> contentFormats = new HashSet<>();
 | 
			
		||||
        contentFormats.add(ContentFormat.DEFAULT);
 | 
			
		||||
        Attribute ct = Arrays.stream(registration.getObjectLinks())
 | 
			
		||||
                .filter(link -> link.getUriReference().equals("/"))
 | 
			
		||||
                .findFirst()
 | 
			
		||||
                .map(link -> link.getAttributes().get("ct")).orElse(null);
 | 
			
		||||
        if (ct != null) {
 | 
			
		||||
            Set codes = Stream.of(ct.getValue()).collect(Collectors.toSet());
 | 
			
		||||
            contentFormats.addAll(codes);
 | 
			
		||||
        if (ct != null && ct.getValue() instanceof Collection<?>) {
 | 
			
		||||
            contentFormats.addAll((Collection<? extends ContentFormat>) ct.getValue());
 | 
			
		||||
        } else {
 | 
			
		||||
            contentFormats.add(ContentFormat.DEFAULT);
 | 
			
		||||
        }
 | 
			
		||||
        return contentFormats;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -98,7 +98,6 @@ import java.util.Set;
 | 
			
		||||
import java.util.TreeSet;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
import java.util.concurrent.RejectedExecutionException;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicReference;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
import java.util.function.Predicate;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
@ -742,16 +741,18 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
 | 
			
		||||
 | 
			
		||||
    private static ContentFormat getRequestContentFormat(LwM2mClient client, String versionedId, LwM2mModelProvider modelProvider) {
 | 
			
		||||
        LwM2mPath pathIds = new LwM2mPath(fromVersionedIdToObjectId(versionedId));
 | 
			
		||||
        if (pathIds.isResource() || pathIds.isResourceInstance()) {
 | 
			
		||||
        if (pathIds.isResourceInstance() || pathIds.isResource()) {
 | 
			
		||||
            ResourceModel resourceModel = client.getResourceModel(versionedId, modelProvider);
 | 
			
		||||
            if (resourceModel != null && (pathIds.isResourceInstance() || (pathIds.isResource() && !resourceModel.multiple))) {
 | 
			
		||||
                ContentFormat[] desiredFormats;
 | 
			
		||||
                if (OBJLNK.equals(resourceModel.type)) {
 | 
			
		||||
                    return ContentFormat.LINK;
 | 
			
		||||
                    desiredFormats =  new ContentFormat[]{ContentFormat.LINK, ContentFormat.CBOR, ContentFormat.SENML_CBOR, ContentFormat.SENML_JSON};
 | 
			
		||||
                } else if (OPAQUE.equals(resourceModel.type)) {
 | 
			
		||||
                    return ContentFormat.OPAQUE;
 | 
			
		||||
                } else {
 | 
			
		||||
                    return findFirstContentFormatForComp(client.getClientSupportContentFormats(), client.getDefaultContentFormat(), ContentFormat.CBOR, ContentFormat.SENML_CBOR, ContentFormat.SENML_JSON);
 | 
			
		||||
                }
 | 
			
		||||
                    desiredFormats =  new ContentFormat[]{ContentFormat.OPAQUE, ContentFormat.CBOR, ContentFormat.SENML_CBOR, ContentFormat.SENML_JSON};
 | 
			
		||||
                 } else {
 | 
			
		||||
                    desiredFormats =  new ContentFormat[]{ContentFormat.CBOR, ContentFormat.SENML_CBOR, ContentFormat.SENML_JSON};
 | 
			
		||||
               }
 | 
			
		||||
                return findFirstContentFormatForComp(client.getClientSupportContentFormats(), client.getDefaultContentFormat(), desiredFormats);
 | 
			
		||||
            } else {
 | 
			
		||||
                return getContentFormatForComplex(client);
 | 
			
		||||
            }
 | 
			
		||||
@ -762,9 +763,9 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
 | 
			
		||||
 | 
			
		||||
    private static ContentFormat getContentFormatForComplex(LwM2mClient client) {
 | 
			
		||||
        if (LwM2m.LwM2mVersion.V1_0.equals(client.getRegistration().getLwM2mVersion())) {
 | 
			
		||||
            return ContentFormat.TLV;
 | 
			
		||||
            return client.getDefaultContentFormat();
 | 
			
		||||
        } else if (LwM2m.LwM2mVersion.V1_1.equals(client.getRegistration().getLwM2mVersion())) {
 | 
			
		||||
            ContentFormat result = findFirstContentFormatForComp(client.getClientSupportContentFormats(), null, ContentFormat.SENML_CBOR, ContentFormat.SENML_JSON, ContentFormat.TLV, ContentFormat.JSON);
 | 
			
		||||
            ContentFormat result = findFirstContentFormatForComp(client.getClientSupportContentFormats(), client.getDefaultContentFormat(), ContentFormat.SENML_CBOR, ContentFormat.SENML_JSON, ContentFormat.TLV, ContentFormat.JSON);
 | 
			
		||||
            if (result != null) {
 | 
			
		||||
                return result;
 | 
			
		||||
            } else {
 | 
			
		||||
@ -783,37 +784,21 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ContentFormat findFirstContentFormatForComposite (Set<?> clientSupportContentFormats) {
 | 
			
		||||
        ContentFormat contentFormat = findFirstContentFormatForComp(clientSupportContentFormats, null, ContentFormat.SENML_JSON, ContentFormat.SENML_CBOR);
 | 
			
		||||
    private ContentFormat findFirstContentFormatForComposite (Set<ContentFormat> clientSupportContentFormats) {
 | 
			
		||||
        ContentFormat contentFormat = findFirstContentFormatForComp(clientSupportContentFormats, null, ContentFormat.SENML_CBOR, ContentFormat.SENML_JSON);
 | 
			
		||||
        if (contentFormat != null) {
 | 
			
		||||
            return contentFormat;
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new RuntimeException("This device does not support Composite Operation");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    private static ContentFormat findFirstContentFormatForComp(Set<?> clientSupportContentFormats, ContentFormat defaultValue, ContentFormat... desiredFormats) {
 | 
			
		||||
        AtomicReference<ContentFormat> compositeContentFormat = new AtomicReference<>();
 | 
			
		||||
        clientSupportContentFormats.forEach(c -> {
 | 
			
		||||
            if (c instanceof Collection) {
 | 
			
		||||
                for (ContentFormat contentFormat : desiredFormats) {
 | 
			
		||||
                    if (((Collection<?>) c).contains(contentFormat)) {
 | 
			
		||||
                        compositeContentFormat.set(contentFormat);
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else if (compositeContentFormat.get() == null && c instanceof ContentFormat) {
 | 
			
		||||
                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;
 | 
			
		||||
    private static ContentFormat findFirstContentFormatForComp(Set<ContentFormat> clientSupportContentFormats, ContentFormat defaultValue, ContentFormat... desiredFormats) {
 | 
			
		||||
        List desiredFormatsList =  Arrays.asList(desiredFormats);
 | 
			
		||||
        for (ContentFormat c : clientSupportContentFormats) {
 | 
			
		||||
            if (desiredFormatsList.contains(c)) {
 | 
			
		||||
                return c;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
        return defaultValue;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user