diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServiceImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServiceImpl.java index 4ca6fb4f34..3943bc2a51 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServiceImpl.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServiceImpl.java @@ -717,7 +717,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { * @return - value of Resource or null */ private String getResourceValueToString(LwM2mClient lwM2MClient, String path) { - LwM2mPath pathIds =new LwM2mPath(convertToObjectIdFromIdVer(path)); + LwM2mPath pathIds = new LwM2mPath(convertToObjectIdFromIdVer(path)); ResourceValue resourceValue = this.returnResourceValueFromLwM2MClient(lwM2MClient, path); return resourceValue == null ? null : this.converter.convertValue(resourceValue.getResourceValue(), this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModelType(lwM2MClient.getRegistration(), pathIds), ResourceModel.Type.STRING, pathIds).toString(); @@ -831,8 +831,10 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { // #5.1 if (!observeOld.equals(observeNew)) { - Set observeSetOld = new Gson().fromJson(observeOld, new TypeToken>() {}.getType()); - Set observeSetNew = new Gson().fromJson(observeNew, new TypeToken>() {}.getType()); + Set observeSetOld = new Gson().fromJson(observeOld, new TypeToken>() { + }.getType()); + Set observeSetNew = new Gson().fromJson(observeNew, new TypeToken>() { + }.getType()); //#5.2 add // path Attr/Telemetry includes newObserve attributeSetOld.addAll(telemetrySetOld); @@ -968,7 +970,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { LwM2mClientProfile profile = lwM2mClientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); Registration registration = lwM2mClientContext.getLwM2MClient(sessionInfo).getRegistration(); return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() - .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModelByVer(registration, e.getKey())).findFirst().map(Map.Entry::getKey) + .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModel(registration, e.getKey(), false)).findFirst().map(Map.Entry::getKey) .orElse(""); } @@ -988,7 +990,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { try { LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo); attributesResponse.getSharedAttributeListList().forEach(attr -> { - String path =this.getPathAttributeUpdate(sessionInfo, attr.getKv().getKey()); + String path = this.getPathAttributeUpdate(sessionInfo, attr.getKv().getKey()); if (path != null) { // #1.1 if (lwM2MClient.getDelayedRequests().containsKey(path) && attr.getTs() > lwM2MClient.getDelayedRequests().get(path).getTs()) { @@ -1117,7 +1119,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { ConcurrentMap keyNamesIsWritable = keyNamesMap.entrySet() .stream() - .filter(e -> (attrSet.contains(e.getKey()) && resourceIsWritable(lwM2MClient.getRegistration(), e.getKey()))) + .filter(e -> (attrSet.contains(e.getKey()) && validateResourceInModel(lwM2MClient.getRegistration(), e.getKey(), true))) .collect(Collectors.toConcurrentMap(Map.Entry::getKey, Map.Entry::getValue)); Set namesIsWritable = ConcurrentHashMap.newKeySet(); @@ -1130,17 +1132,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { return "LWM2M"; } - private boolean resourceIsWritable(Registration registration, String pathKey) { - return validateResourceInModelByVer(registration, pathKey) && - lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(registration, - new LwM2mPath(convertToObjectIdFromIdVer(pathKey))).operations.isWritable(); - } - - private boolean validateResourceInModelByVer(Registration registration, String pathKey) { + private boolean validateResourceInModel(Registration registration, String pathKey, boolean isWritable) { + ResourceModel resourceModel = lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(registration, + new LwM2mPath(convertToObjectIdFromIdVer(pathKey))); Integer objectId = validateObjectIdFromKey(pathKey); String objectVer = validateObjectVerFromKey(pathKey); - LwM2mPath lwM2mPath = new LwM2mPath(convertToObjectIdFromIdVer(pathKey)); - return objectId != null && objectVer != null && objectVer.equals(registration.getSupportedVersion(objectId)) && - lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(registration, lwM2mPath) != null; + return resourceModel != null && (isWritable ? + objectId != null && objectVer != null && objectVer.equals(registration.getSupportedVersion(objectId)) && resourceModel.operations.isWritable() : + objectId != null && objectVer != null && objectVer.equals(registration.getSupportedVersion(objectId))); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java index 209f7aa68a..fc35668fef 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java @@ -22,6 +22,7 @@ import org.eclipse.leshan.core.model.ObjectModel; import org.eclipse.leshan.core.model.ResourceModel; import org.eclipse.leshan.server.model.LwM2mModelProvider; import org.eclipse.leshan.server.registration.Registration; +import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; @@ -30,6 +31,7 @@ import java.util.Base64; import java.util.Collection; import java.util.Iterator; import java.util.Map; +import java.util.Optional; import static org.thingsboard.server.common.data.ResourceType.LWM2M_MODEL; import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; @@ -83,6 +85,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider { if (objectModel != null) return objectModel.resources.get(resourceId); else + log.warn("TbResources (Object model) with id [{}/{}] not found on the server", objectId, resourceId); return null; } catch (Exception e) { log.error("", e); @@ -116,17 +119,15 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider { private ObjectModel getObjectModelDynamic(Integer objectId, String version) { String key = getKeyIdVer(objectId, version); - String xmlB64 = lwM2mTransportContextServer.getTransportResourceCache().get( - this.tenantId, - LWM2M_MODEL, - key). - getData(); - return xmlB64 != null && !xmlB64.isEmpty() ? - lwM2mTransportContextServer.parseFromXmlToObjectModel( - Base64.getDecoder().decode(xmlB64), - key + ".xml", - new DefaultDDFFileValidator()) : - null; + + Optional tbResource = lwM2mTransportContextServer + .getTransportResourceCache() + .get(this.tenantId, LWM2M_MODEL, key); + + return tbResource.map(resource -> lwM2mTransportContextServer.parseFromXmlToObjectModel( + Base64.getDecoder().decode(resource.getData()), + key + ".xml", + new DefaultDDFFileValidator())).orElse(null); } } } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportResourceCache.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportResourceCache.java index 5f793511c6..7c72318de7 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportResourceCache.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportResourceCache.java @@ -15,13 +15,15 @@ */ package org.thingsboard.server.common.transport; -import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.ResourceType; +import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.id.TenantId; +import java.util.Optional; + public interface TransportResourceCache { - TbResource get(TenantId tenantId, ResourceType resourceType, String resourceId); + Optional get(TenantId tenantId, ResourceType resourceType, String resourceId); void update(TenantId tenantId, ResourceType resourceType, String resourceI); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportResourceCache.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportResourceCache.java index 17d898508a..83439530c0 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportResourceCache.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportResourceCache.java @@ -19,8 +19,8 @@ import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; -import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.ResourceType; +import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.transport.TransportResourceCache; import org.thingsboard.server.common.transport.TransportService; @@ -53,7 +53,7 @@ public class DefaultTransportResourceCache implements TransportResourceCache { } @Override - public TbResource get(TenantId tenantId, ResourceType resourceType, String resourceKey) { + public Optional get(TenantId tenantId, ResourceType resourceType, String resourceKey) { ResourceCompositeKey compositeKey = new ResourceCompositeKey(tenantId, resourceType, resourceKey); TbResource resource; @@ -79,7 +79,7 @@ public class DefaultTransportResourceCache implements TransportResourceCache { } } - return resource; + return Optional.ofNullable(resource); } private TbResource fetchResource(ResourceCompositeKey compositeKey) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseTbResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseTbResourceService.java index 91de57c849..0f1b39a459 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseTbResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseTbResourceService.java @@ -87,7 +87,7 @@ public class BaseTbResourceService implements TbResourceService { String resourceKey = objectModel.id + LWM2M_SEPARATOR_KEY + objectModel.getVersion(); String name = objectModel.name; resource.setResourceKey(resourceKey); - resource.setTitle(name); + resource.setTitle(name + " id=" +objectModel.id + " v" + objectModel.getVersion()); resource.setSearchText(resourceKey + LWM2M_SEPARATOR_SEARCH_TEXT + name); } else { throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText())); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseTbResourceServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseTbResourceServiceTest.java index d17fcc88ff..21842af176 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseTbResourceServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseTbResourceServiceTest.java @@ -123,7 +123,7 @@ public abstract class BaseTbResourceServiceTest extends AbstractServiceTest { Assert.assertNotNull(savedResource.getId()); Assert.assertTrue(savedResource.getCreatedTime() > 0); Assert.assertEquals(resource.getTenantId(), savedResource.getTenantId()); - Assert.assertEquals("My first resource", savedResource.getTitle()); + Assert.assertEquals("My first resource id=0 v1.0", savedResource.getTitle()); Assert.assertEquals("0_1.0", savedResource.getResourceKey()); Assert.assertEquals(resource.getData(), savedResource.getData());