From 4bc417456b04e08f988a0db718a619a931a842b2 Mon Sep 17 00:00:00 2001 From: nickAS21 <44275303+nickAS21@users.noreply.github.com> Date: Tue, 23 Mar 2021 10:09:41 +0200 Subject: [PATCH] lwm2m: back transport newKey start (#4278) * lwm2m: back transport newKey start * lwm2m: back transport newKey start1 * lwm2m: back transport newKey fix bug save * lwm2m: back transport newKey test All security - ok * lwm2m: back transport newKey fix bug updateAttrShared --- .../common/data/lwm2m/LwM2mConstants.java | 23 ++ common/transport/lwm2m/pom.xml | 4 + .../lwm2m/server/LwM2mServerListener.java | 4 +- .../lwm2m/server/LwM2mTransportHandler.java | 104 ++++---- .../lwm2m/server/LwM2mTransportRequest.java | 26 +- .../server/LwM2mTransportServiceImpl.java | 139 ++++++---- .../server/LwM2mVersionedModelProvider.java | 14 +- .../store/LwM2mInMemorySecurityStore.java | 251 ------------------ .../store/TbLwM2mStoreConfiguration.java | 11 +- .../server/dao/model/ModelConstants.java | 1 - .../dao/model/sql/TbResourceEntity.java | 3 +- .../dao/resource/BaseTbResourceService.java | 31 +-- .../server/dao/resource/TbResourceDao.java | 2 - .../dao/sql/resource/JpaTbResourceDao.java | 7 - 14 files changed, 215 insertions(+), 405 deletions(-) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mConstants.java delete mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/LwM2mInMemorySecurityStore.java diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mConstants.java new file mode 100644 index 0000000000..6170fd4bb3 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mConstants.java @@ -0,0 +1,23 @@ +/** + * Copyright © 2016-2021 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.common.data.lwm2m; + +public interface LwM2mConstants { + + String LWM2M_SEPARATOR_PATH = "/"; + String LWM2M_SEPARATOR_KEY = "_"; + String LWM2M_SEPARATOR_SEARCH_TEXT = ":"; +} diff --git a/common/transport/lwm2m/pom.xml b/common/transport/lwm2m/pom.xml index fe19dae329..aae103fc4f 100644 --- a/common/transport/lwm2m/pom.xml +++ b/common/transport/lwm2m/pom.xml @@ -40,6 +40,10 @@ org.thingsboard.common.transport transport-api + + org.thingsboard.common + data + org.springframework spring-context-support diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mServerListener.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mServerListener.java index f89f7ec952..ffe2f76602 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mServerListener.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mServerListener.java @@ -26,6 +26,8 @@ import org.eclipse.leshan.server.registration.RegistrationUpdate; import java.util.Collection; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToIdVerFromObjectId; + @Slf4j public class LwM2mServerListener { @@ -90,7 +92,7 @@ public class LwM2mServerListener { public void onResponse(Observation observation, Registration registration, ObserveResponse response) { if (registration != null) { try { - service.onObservationResponse(registration, observation.getPath().toString(), response); + service.onObservationResponse(registration, convertToIdVerFromObjectId(observation.getPath().toString(), registration), response); } catch (Exception e) { log.error("[{}] onResponse", e.toString()); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportHandler.java index 5b6ec23a6e..0f0707ddf8 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportHandler.java @@ -22,6 +22,7 @@ import com.google.gson.JsonSyntaxException; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.eclipse.californium.core.network.config.NetworkConfig; +import org.eclipse.leshan.core.model.ObjectModel; import org.eclipse.leshan.core.model.ResourceModel; import org.eclipse.leshan.core.node.LwM2mMultipleResource; import org.eclipse.leshan.core.node.LwM2mNode; @@ -32,6 +33,7 @@ import org.eclipse.leshan.core.node.LwM2mSingleResource; import org.eclipse.leshan.core.node.codec.CodecException; import org.eclipse.leshan.core.util.Hex; import org.eclipse.leshan.server.californium.LeshanServerBuilder; +import org.eclipse.leshan.server.registration.Registration; import org.nustaq.serialization.FSTConfiguration; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; @@ -47,14 +49,12 @@ import java.util.Date; import java.util.LinkedList; import java.util.Optional; +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; + @Slf4j -//@Component("LwM2MTransportHandler") -//@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' )|| ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") public class LwM2mTransportHandler { - // We choose a default timeout a bit higher to the MAX_TRANSMIT_WAIT(62-93s) which is the time from starting to - // send a Confirmable message to the time when an acknowledgement is no longer expected. - public static final String BASE_DEVICE_API_TOPIC = "v1/devices/me"; public static final String ATTRIBUTE = "attribute"; public static final String TELEMETRY = "telemetry"; @@ -84,6 +84,8 @@ public class LwM2mTransportHandler { public static final String LOG_LW2M_ERROR = "error"; public static final String LOG_LW2M_WARN = "warn"; + public static final int LWM2M_STRATEGY_1 = 1; + public static final int LWM2M_STRATEGY_2 = 2; public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized"; @@ -110,39 +112,6 @@ public class LwM2mTransportHandler { public static final String SERVICE_CHANNEL = "SERVICE"; public static final String RESPONSE_CHANNEL = "RESP"; -// @Autowired -// @Qualifier("LeshanServerCert") -// private LeshanServer lhServerCert; -// -// @Autowired -// @Qualifier("LeshanServerNoSecPskRpk") -// private LeshanServer lhServerNoSecPskRpk; - -// @Autowired -// @Qualifier("ServerListenerCert") -// private LwM2mServerListener serverListenerCert; -// -// @Autowired -// @Qualifier("ServerListenerNoSecPskRpk") -// private LwM2mServerListener serverListenerNoSecPskRpk; - - -// @PostConstruct -// public void init() { -// try { -// serverListenerCert.init(lhServerCert); -// this.lhServerCert.getRegistrationService().addListener(serverListenerCert.registrationListener); -// this.lhServerCert.getPresenceService().addListener(serverListenerCert.presenceListener); -// this.lhServerCert.getObservationService().addListener(serverListenerCert.observationListener); -// serverListenerNoSecPskRpk.init(lhServerNoSecPskRpk); -// this.lhServerNoSecPskRpk.getRegistrationService().addListener(serverListenerNoSecPskRpk.registrationListener); -// this.lhServerNoSecPskRpk.getPresenceService().addListener(serverListenerNoSecPskRpk.presenceListener); -// this.lhServerNoSecPskRpk.getObservationService().addListener(serverListenerNoSecPskRpk.observationListener); -// } catch (Exception e) { -// log.error("init [{}]", e.toString()); -// } -// } - public static NetworkConfig getCoapConfig(Integer serverPortNoSec, Integer serverSecurePort) { NetworkConfig coapConfig; File configFile = new File(NetworkConfig.DEFAULT_FILE_NAME); @@ -202,10 +171,10 @@ public class LwM2mTransportHandler { /** * @return deviceProfileBody with Observe&Attribute&Telemetry From Thingsboard - * Example: + * Example: * property: {"clientLwM2mSettings": { - * clientUpdateValueAfterConnect: false; - * } + * clientUpdateValueAfterConnect: false; + * } * property: "observeAttr" * {"keyName": { * "/3/0/1": "modelNumber", @@ -222,7 +191,7 @@ public class LwM2mTransportHandler { try { ObjectMapper mapper = new ObjectMapper(); String profileStr = mapper.writeValueAsString(profile); - JsonObject profileJson = (profileStr != null) ? validateJson(profileStr) : null; + JsonObject profileJson = (profileStr != null) ? validateJson(profileStr) : null; return (getValidateCredentialsBodyFromThingsboard(profileJson)) ? LwM2mTransportHandler.getNewProfileParameters(profileJson, deviceProfile.getTenantId()) : null; } catch (IOException e) { log.error("", e); @@ -246,9 +215,9 @@ public class LwM2mTransportHandler { return null; } - public static boolean getClientOnlyObserveAfterConnect (LwM2mClientProfile profile) { - return profile.getPostClientLwM2mSettings().getAsJsonObject().has("clientOnlyObserveAfterConnect") && - profile.getPostClientLwM2mSettings().getAsJsonObject().get("clientOnlyObserveAfterConnect").getAsBoolean(); + public static int getClientOnlyObserveAfterConnect(LwM2mClientProfile profile) { + return profile.getPostClientLwM2mSettings().getAsJsonObject().has("clientOnlyObserveAfterConnect") ? + profile.getPostClientLwM2mSettings().getAsJsonObject().get("clientOnlyObserveAfterConnect").getAsInt() : 1; } private static boolean getValidateCredentialsBodyFromThingsboard(JsonObject objectMsg) { @@ -346,4 +315,49 @@ public class LwM2mTransportHandler { } }; } + + public static String convertToObjectIdFromIdVer(String key) { + try { + String[] keyArray = key.split(LWM2M_SEPARATOR_PATH); + if (keyArray.length > 1 && keyArray[1].split(LWM2M_SEPARATOR_KEY).length == 2) { + keyArray[1] = keyArray[1].split(LWM2M_SEPARATOR_KEY)[0]; + return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); + } else { + return key; + } + } catch (Exception e) { + return null; + } + } + + public static String convertToIdVerFromObjectId(String path, Registration registration) { + String ver = registration.getSupportedObject().get(new LwM2mPath(path).getObjectId()); + try { + String[] keyArray = path.split(LWM2M_SEPARATOR_PATH); + if (keyArray.length > 1) { + keyArray[1] = keyArray[1] + LWM2M_SEPARATOR_KEY + ver; + return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); + } else { + return path; + } + } catch (Exception e) { + return null; + } + } + + public static Integer validateObjectIdFromKey(String key) { + try { + return Integer.parseInt(key.split(LWM2M_SEPARATOR_PATH)[1].split(LWM2M_SEPARATOR_KEY)[0]); + } catch (Exception e) { + return null; + } + } + + public static String validateObjectVerFromKey(String key) { + try { + return (key.split(LWM2M_SEPARATOR_PATH)[1].split(LWM2M_SEPARATOR_KEY)[1]); + } catch (Exception e) { + return ObjectModel.DEFAULT_VERSION; + } + } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java index fa7f0d68b8..094474d9c0 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java @@ -72,6 +72,8 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_ATTRIBUTES; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_UPDATE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.RESPONSE_CHANNEL; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToIdVerFromObjectId; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToObjectIdFromIdVer; @Slf4j @Service @@ -114,7 +116,7 @@ public class LwM2mTransportRequest { */ public void sendAllRequest(Registration registration, String target, String typeOper, String contentFormatParam, Observation observation, Object params, long timeoutInMs) { - LwM2mPath resultIds = new LwM2mPath(target); + LwM2mPath resultIds = new LwM2mPath(convertToObjectIdFromIdVer(target)); if (registration != null && resultIds.getObjectId() >= 0) { DownlinkRequest request = null; ContentFormat contentFormat = contentFormatParam != null ? ContentFormat.fromName(contentFormatParam.toUpperCase()) : null; @@ -229,9 +231,8 @@ public class LwM2mTransportRequest { private void sendRequest(Registration registration, DownlinkRequest request, long timeoutInMs) { LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); leshanServer.send(registration, request, timeoutInMs, (ResponseCallback) response -> { - if (!lwM2MClient.isInit()) { - lwM2MClient.initValue(this.serviceImpl, request.getPath().toString()); + lwM2MClient.initValue(this.serviceImpl, convertToIdVerFromObjectId(request.getPath().toString(), registration)); } if (isSuccess(((Response) response.getCoapResponse()).getCode())) { this.handleResponse(registration, request.getPath().toString(), response, request); @@ -251,7 +252,7 @@ public class LwM2mTransportRequest { } }, e -> { if (!lwM2MClient.isInit()) { - lwM2MClient.initValue(this.serviceImpl, request.getPath().toString()); + lwM2MClient.initValue(this.serviceImpl, convertToIdVerFromObjectId(request.getPath().toString(), registration)); } String msg = String.format("%s: sendRequest: Resource path - %s msg error - %s SendRequest to Client", LOG_LW2M_ERROR, request.getPath().toString(), e.toString()); @@ -310,21 +311,22 @@ public class LwM2mTransportRequest { * @param response - */ private void sendResponse(Registration registration, String path, LwM2mResponse response, DownlinkRequest request) { + String pathIdVer = convertToIdVerFromObjectId(path, registration); if (response instanceof ReadResponse) { - serviceImpl.onObservationResponse(registration, path, (ReadResponse) response); + serviceImpl.onObservationResponse(registration, pathIdVer, (ReadResponse) response); } else if (response instanceof CancelObservationResponse) { - log.info("[{}] Path [{}] CancelObservationResponse 3_Send", path, response); + log.info("[{}] Path [{}] CancelObservationResponse 3_Send", pathIdVer, response); } else if (response instanceof DeleteResponse) { - log.info("[{}] Path [{}] DeleteResponse 5_Send", path, response); + log.info("[{}] Path [{}] DeleteResponse 5_Send", pathIdVer, response); } else if (response instanceof DiscoverResponse) { - log.info("[{}] Path [{}] DiscoverResponse 6_Send", path, response); + log.info("[{}] Path [{}] DiscoverResponse 6_Send", pathIdVer, response); } else if (response instanceof ExecuteResponse) { - log.info("[{}] Path [{}] ExecuteResponse 7_Send", path, response); + log.info("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response); } else if (response instanceof WriteAttributesResponse) { - log.info("[{}] Path [{}] WriteAttributesResponse 8_Send", path, response); + log.info("[{}] Path [{}] WriteAttributesResponse 8_Send", pathIdVer, response); } else if (response instanceof WriteResponse) { - log.info("[{}] Path [{}] WriteAttributesResponse 9_Send", path, response); - serviceImpl.onWriteResponseOk(registration, path, (WriteRequest) request); + log.info("[{}] Path [{}] WriteAttributesResponse 9_Send", pathIdVer, response); + serviceImpl.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request); } } } 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 1af4e8bfd8..6fcfeaa4e6 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 @@ -88,10 +88,15 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LWM2M_STRATEGY_2; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_EXECUTE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_WRITE_REPLACE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.SERVICE_CHANNEL; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToIdVerFromObjectId; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToObjectIdFromIdVer; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getAckCallback; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validateObjectIdFromKey; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validateObjectVerFromKey; @Slf4j @Service @@ -290,19 +295,19 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { if (msg.getSharedUpdatedCount() > 0) { JsonElement el = JsonConverter.toJson(msg); el.getAsJsonObject().entrySet().forEach(de -> { - String path = this.getPathAttributeUpdate(sessionInfo, de.getKey()); + String pathIdVer = this.getPathAttributeUpdate(sessionInfo, de.getKey()); String value = de.getValue().getAsString(); LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); LwM2mClientProfile clientProfile = lwM2mClientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); - if (path != null && !path.isEmpty() && (this.validatePathInAttrProfile(clientProfile, path) || this.validatePathInTelemetryProfile(clientProfile, path))) { - ResourceModel resourceModel = lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(path)); + if (pathIdVer != null && !pathIdVer.isEmpty() && (this.validatePathInAttrProfile(clientProfile, pathIdVer) || this.validatePathInTelemetryProfile(clientProfile, pathIdVer))) { + ResourceModel resourceModel = lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(convertToObjectIdFromIdVer(pathIdVer))); if (resourceModel != null && resourceModel.operations.isWritable()) { - lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), path, POST_TYPE_OPER_WRITE_REPLACE, + lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), pathIdVer, POST_TYPE_OPER_WRITE_REPLACE, ContentFormat.TLV.getName(), null, value, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); } else { - log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", path, value); + log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", pathIdVer, value); String logMsg = String.format("%s: attributeUpdate: Resource path - %s value - %s is not Writable and cannot be updated", - LOG_LW2M_ERROR, path, value); + LOG_LW2M_ERROR, pathIdVer, value); this.sentLogsToThingsboard(logMsg, lwM2MClient.getRegistration()); } } else { @@ -348,7 +353,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { /** * Trigger Server path = "/1/0/8" - * + *

* Trigger bootStrap path = "/1/0/9" - have to implemented on client */ @Override @@ -458,7 +463,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { private void initLwM2mFromClientValue(Registration registration, LwM2mClient lwM2MClient) { LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); Set clientObjects = this.getAllOjectsInClient(registration); - if (clientObjects != null && !LwM2mTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { + if (clientObjects != null && LWM2M_STRATEGY_2 == LwM2mTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { // #2 lwM2MClient.getPendingRequests().addAll(clientObjects); clientObjects.forEach(path -> lwM2mTransportRequest.sendAllRequest(registration, path, GET_TYPE_OPER_READ, ContentFormat.TLV.getName(), @@ -499,9 +504,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { * #1 Return old Value Resource from LwM2MClient * #2 Update new Resources (replace old Resource Value on new Resource Value) * - * @param registration - Registration LwM2M Client + * @param registration - Registration LwM2M Client * @param lwM2mResource - LwM2mSingleResource response.getContent() - * @param path - resource + * @param path - resource */ private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) { LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); @@ -539,7 +544,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { /** * @param clientProfile - - * @param path - + * @param path - * @return true if path isPresent in postAttributeProfile */ private boolean validatePathInAttrProfile(LwM2mClientProfile clientProfile, String path) { @@ -555,7 +560,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { /** * @param clientProfile - - * @param path - + * @param path - * @return true if path isPresent in postAttributeProfile */ private boolean validatePathInTelemetryProfile(LwM2mClientProfile clientProfile, String path) { @@ -581,10 +586,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { Set clientInstances = this.getAllInstancesInClient(registration); Set result; if (GET_TYPE_OPER_READ.equals(typeOper)) { - result = JacksonUtil.fromString(lwM2MClientProfile.getPostAttributeProfile().toString(), new TypeReference<>() {}); - result.addAll(JacksonUtil.fromString(lwM2MClientProfile.getPostTelemetryProfile().toString(), new TypeReference<>() {})); + result = JacksonUtil.fromString(lwM2MClientProfile.getPostAttributeProfile().toString(), new TypeReference<>() { + }); + result.addAll(JacksonUtil.fromString(lwM2MClientProfile.getPostTelemetryProfile().toString(), new TypeReference<>() { + })); } else { - result = JacksonUtil.fromString(lwM2MClientProfile.getPostObserveProfile().toString(), new TypeReference<>() {}); + result = JacksonUtil.fromString(lwM2MClientProfile.getPostObserveProfile().toString(), new TypeReference<>() { + }); } Set pathSent = ConcurrentHashMap.newKeySet(); result.forEach(target -> { @@ -646,7 +654,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { Arrays.stream(registration.getObjectLinks()).forEach(url -> { LwM2mPath pathIds = new LwM2mPath(url.getUrl()); if (pathIds.isObjectInstance()) { - clientInstances.add(url.getUrl()); + clientInstances.add(convertToIdVerFromObjectId(url.getUrl(), registration)); } }); return (clientInstances.size() > 0) ? clientInstances : null; @@ -656,26 +664,22 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { * @param attributes - new JsonObject * @param telemetry - new JsonObject * @param registration - Registration LwM2M Client - * @param path - + * @param path - */ private void getParametersFromProfile(JsonObject attributes, JsonObject telemetry, Registration registration, Set path) { - LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); - lwM2MClientProfile.getPostAttributeProfile().forEach(p -> { - LwM2mPath pathIds = new LwM2mPath(p.getAsString()); - if (pathIds.isResource()) { - if (path == null || path.contains(p.getAsString())) { - this.addParameters(p.getAsString(), attributes, registration); + if (path != null && path.size() > 0) { + LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); + lwM2MClientProfile.getPostAttributeProfile().forEach(idVer -> { + if (path.contains(idVer.getAsString())) { + this.addParameters(idVer.getAsString(), attributes, registration); } - } - }); - lwM2MClientProfile.getPostTelemetryProfile().forEach(p -> { - LwM2mPath pathIds = new LwM2mPath(p.getAsString()); - if (pathIds.isResource()) { - if (path == null || path.contains(p.getAsString())) { - this.addParameters(p.getAsString(), telemetry, registration); + }); + lwM2MClientProfile.getPostTelemetryProfile().forEach(idVer -> { + if (path.contains(idVer.getAsString())) { + this.addParameters(idVer.getAsString(), telemetry, registration); } - } - }); + }); + } } /** @@ -703,22 +707,21 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { * @return - value of Resource or null */ private String getResourceValueToString(LwM2mClient lwM2MClient, String path) { - LwM2mPath pathIds = new LwM2mPath(path); - ResourceValue resourceValue = this.returnResourceValueFromLwM2MClient(lwM2MClient, pathIds); + 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(); } /** - * * @param lwM2MClient - - * @param pathIds - + * @param path - * @return - return value of Resource by idPath */ - private ResourceValue returnResourceValueFromLwM2MClient(LwM2mClient lwM2MClient, LwM2mPath pathIds) { + private ResourceValue returnResourceValueFromLwM2MClient(LwM2mClient lwM2MClient, String path) { ResourceValue resourceValue = null; - if (pathIds.isResource()) { - resourceValue = lwM2MClient.getResources().get(pathIds.toString()); + if (new LwM2mPath(convertToObjectIdFromIdVer(path)).isResource()) { + resourceValue = lwM2MClient.getResources().get(path); } return resourceValue; } @@ -818,8 +821,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); @@ -840,7 +845,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { } } - private Set convertJsonArrayToSet (JsonArray jsonArray) { + private Set convertJsonArrayToSet(JsonArray jsonArray) { List attributeListOld = new Gson().fromJson(jsonArray, new TypeToken<>() { }.getType()); return Sets.newConcurrentHashSet(attributeListOld); @@ -907,7 +912,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { private void cancelObserveIsValue(Registration registration, Set paramAnallyzer) { LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); paramAnallyzer.forEach(p -> { - if (this.returnResourceValueFromLwM2MClient(lwM2MClient, new LwM2mPath(p)) != null) { + if (this.returnResourceValueFromLwM2MClient(lwM2MClient, p) != null) { this.setCancelObservationRecourse(registration, p); } } @@ -953,8 +958,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { */ private String getPathAttributeUpdateProfile(TransportProtos.SessionInfoProto sessionInfo, String name) { 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)).findFirst().map(Map.Entry::getKey) + .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModelByVer(registration, e.getKey())).findFirst().map(Map.Entry::getKey) .orElse(""); } @@ -974,12 +980,14 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { try { LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo); attributesResponse.getSharedAttributeListList().forEach(attr -> { - String path = this.getPathAttributeUpdate(sessionInfo, attr.getKv().getKey()); - // #1.1 - if (lwM2MClient.getDelayedRequests().containsKey(path) && attr.getTs() > lwM2MClient.getDelayedRequests().get(path).getTs()) { - lwM2MClient.getDelayedRequests().put(path, attr); - } else { - lwM2MClient.getDelayedRequests().put(path, attr); + 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()) { + lwM2MClient.getDelayedRequests().put(path, attr); + } else { + lwM2MClient.getDelayedRequests().put(path, attr); + } } }); // #2.1 @@ -1057,6 +1065,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { } /** + * !!! sharedAttr === profileAttr !!! * If there is a difference in values between the current resource values and the shared attribute values * when the client connects to the server * #1 get attributes name from profile include name resources in ModelObject if resource isWritable @@ -1083,24 +1092,42 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { /** - * Get names and keyNames from profile shared!!!! attr resources IsWritable + * !!! sharedAttr === profileAttr !!! + * Get names or keyNames from profile: resources IsWritable * * @param lwM2MClient - - * @return ArrayList keyNames from profile attr resources shared!!!! && IsWritable + * @return ArrayList keyNames from profile profileAttr && IsWritable */ private List getNamesAttrFromProfileIsWritable(LwM2mClient lwM2MClient) { LwM2mClientProfile profile = lwM2mClientContext.getProfile(lwM2MClient.getProfileId()); - Set attrSet = new Gson().fromJson(profile.getPostAttributeProfile(), new TypeToken<>() {}.getType()); - ConcurrentMap keyNamesMap = new Gson().fromJson(profile.getPostKeyNameProfile().toString(), new TypeToken>() {}.getType()); + Set attrSet = new Gson().fromJson(profile.getPostAttributeProfile(), + new TypeToken>() { + }.getType()); + ConcurrentMap keyNamesMap = new Gson().fromJson(profile.getPostKeyNameProfile().toString(), + new TypeToken>() { + }.getType()); ConcurrentMap keyNamesIsWritable = keyNamesMap.entrySet() .stream() - .filter(e -> (attrSet.contains(e.getKey()) && lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(e.getKey())) != null && - lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(e.getKey())).operations.isWritable())) + .filter(e -> (attrSet.contains(e.getKey()) && resourceIsWritable(lwM2MClient.getRegistration(), e.getKey()))) .collect(Collectors.toConcurrentMap(Map.Entry::getKey, Map.Entry::getValue)); Set namesIsWritable = ConcurrentHashMap.newKeySet(); namesIsWritable.addAll(new HashSet<>(keyNamesIsWritable.values())); return new ArrayList<>(namesIsWritable); } + + 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) { + 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; + } } 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 20f44d597b..209f7aa68a 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 @@ -32,6 +32,7 @@ import java.util.Iterator; import java.util.Map; import static org.thingsboard.server.common.data.ResourceType.LWM2M_MODEL; +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; @Slf4j public class LwM2mVersionedModelProvider implements LwM2mModelProvider { @@ -49,12 +50,9 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider { this.lwM2mClientContext = lwM2mClientContext; this.lwM2mTransportContextServer = lwM2mTransportContextServer; } - private String getIdVer(ObjectModel objectModel) { - return objectModel.id + "##" + ((objectModel.getVersion() == null || objectModel.getVersion().isEmpty()) ? ObjectModel.DEFAULT_VERSION : objectModel.getVersion()); - } - private String getIdVer(Integer objectId, String version) { - return objectId != null ? objectId + "##" + ((version == null || version.isEmpty()) ? ObjectModel.DEFAULT_VERSION : version) : null; + private String getKeyIdVer(Integer objectId, String version) { + return objectId != null ? objectId + LWM2M_SEPARATOR_KEY + ((version == null || version.isEmpty()) ? ObjectModel.DEFAULT_VERSION : version) : null; } /** @@ -65,8 +63,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider { */ @Override public LwM2mModel getObjectModel(Registration registration) { - return new DynamicModel(registration - ); + return new DynamicModel(registration); } private class DynamicModel implements LwM2mModel { @@ -107,7 +104,6 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider { Map supportedObjects = this.registration.getSupportedObject(); Collection result = new ArrayList<>(supportedObjects.size()); Iterator> i$ = supportedObjects.entrySet().iterator(); - while (i$.hasNext()) { Map.Entry supportedObject = i$.next(); ObjectModel objectModel = this.getObjectModelDynamic(supportedObject.getKey(), supportedObject.getValue()); @@ -119,7 +115,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider { } private ObjectModel getObjectModelDynamic(Integer objectId, String version) { - String key = getIdVer(objectId, version); + String key = getKeyIdVer(objectId, version); String xmlB64 = lwM2mTransportContextServer.getTransportResourceCache().get( this.tenantId, LWM2M_MODEL, diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/LwM2mInMemorySecurityStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/LwM2mInMemorySecurityStore.java deleted file mode 100644 index fc66a5fed0..0000000000 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/LwM2mInMemorySecurityStore.java +++ /dev/null @@ -1,251 +0,0 @@ -/** - * Copyright © 2016-2021 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.server.store; - -import lombok.extern.slf4j.Slf4j; -import org.eclipse.leshan.core.util.Hex; -import org.eclipse.leshan.server.registration.Registration; -import org.eclipse.leshan.server.security.InMemorySecurityStore; -import org.eclipse.leshan.server.security.SecurityInfo; -import org.eclipse.leshan.server.security.SecurityStoreListener; -import org.springframework.beans.factory.annotation.Autowired; -import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.gen.transport.TransportProtos; -import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; -import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; -import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; -import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; -import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; -import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; -import org.thingsboard.server.transport.lwm2m.utils.TypeServer; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.stream.Collectors; - -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC; - -@Slf4j -//@Service("LwM2mInMemorySecurityStore") -//@TbLwM2mTransportComponent -@Deprecated -public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { - private static final boolean INFOS_ARE_COMPROMISED = false; - - // lock for the two maps - private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); - private final Lock readLock = readWriteLock.readLock(); - private final Lock writeLock = readWriteLock.writeLock(); - private final Map sessions = new ConcurrentHashMap<>(); - private Map profiles = new ConcurrentHashMap<>(); - private SecurityStoreListener listener; - - @Autowired - LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator; - - /** - * Start after DefaultAuthorizer or LwM2mPskStore - * @param endPoint - - * @return SecurityInfo - */ - @Override - public SecurityInfo getByEndpoint(String endPoint) { - readLock.lock(); - try { - String registrationId = this.getRegistrationId(endPoint, null); - return (registrationId != null && sessions.size() > 0 && sessions.get(registrationId) != null) ? - sessions.get(registrationId).getSecurityInfo() : this.addLwM2MClientToSession(endPoint); - } finally { - readLock.unlock(); - } - } - - /** - * Start after LwM2mPskStore - * @param identity - - * @return SecurityInfo - */ - @Override - public SecurityInfo getByIdentity(String identity) { - readLock.lock(); - try { - String integrationId = this.getRegistrationId(null, identity); - return (integrationId != null) ? sessions.get(integrationId).getSecurityInfo() : this.addLwM2MClientToSession(identity); - } finally { - readLock.unlock(); - } - } - - @Override - public Collection getAll() { - readLock.lock(); - try { - return this.sessions.values().stream().map(LwM2mClient::getSecurityInfo).collect(Collectors.toUnmodifiableList()); - } finally { - readLock.unlock(); - } - } - - /** - * Removed registration Client from sessions and listener - * @param registrationId if Client - */ - public void delRemoveSessionAndListener(String registrationId) { - writeLock.lock(); - try { - LwM2mClient lwM2MClient = (sessions.get(registrationId) != null) ? sessions.get(registrationId) : null; - if (lwM2MClient != null) { - if (listener != null) { - listener.securityInfoRemoved(INFOS_ARE_COMPROMISED, lwM2MClient.getSecurityInfo()); - } - sessions.remove(registrationId); - } - } finally { - writeLock.unlock(); - } - } - - @Override - public void setListener(SecurityStoreListener listener) { - this.listener = listener; - } - - public LwM2mClient getLwM2MClient(String endPoint, String identity) { - Map.Entry modelClients = endPoint != null ? - this.sessions.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndpoint())).findAny().orElse(null) : - this.sessions.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).findAny().orElse(null); - return modelClients != null ? modelClients.getValue() : null; - } - - public LwM2mClient getLwM2MClientWithReg(Registration registration, String registrationId) { - return registrationId != null ? - this.sessions.get(registrationId) : - this.sessions.containsKey(registration.getId()) ? - this.sessions.get(registration.getId()) : - this.sessions.get(registration.getEndpoint()); - } - - public LwM2mClient getLwM2MClient(TransportProtos.SessionInfoProto sessionInfo) { - return this.getSession(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).entrySet().iterator().next().getValue(); - } - - /** - * Update in sessions (LwM2MClient for key registration_Id) after starting registration LwM2MClient in LwM2MTransportServiceImpl - * Remove from sessions LwM2MClient with key registration_Endpoint - * @param registration - - * @return LwM2MClient after adding it to session - */ - public LwM2mClient updateInSessionsLwM2MClient(Registration registration) { - writeLock.lock(); - try { - if (this.sessions.get(registration.getEndpoint()) == null) { - this.addLwM2MClientToSession(registration.getEndpoint()); - } - LwM2mClient lwM2MClient = this.sessions.get(registration.getEndpoint()); - lwM2MClient.setRegistration(registration); -// lwM2MClient.getAttributes().putAll(registration.getAdditionalRegistrationAttributes()); - this.sessions.remove(registration.getEndpoint()); - this.sessions.put(registration.getId(), lwM2MClient); - return lwM2MClient; - } finally { - writeLock.unlock(); - } - } - - private String getRegistrationId(String endPoint, String identity) { - List registrationIds = (endPoint != null) ? - this.sessions.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndpoint())).map(Map.Entry::getKey).collect(Collectors.toList()) : - this.sessions.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).map(Map.Entry::getKey).collect(Collectors.toList()); - return (registrationIds != null && registrationIds.size() > 0) ? registrationIds.get(0) : null; - } - - public Registration getByRegistration(String registrationId) { - return this.sessions.get(registrationId).getRegistration(); - } - - /** - * Add new LwM2MClient to session - * @param identity- - * @return SecurityInfo. If error - SecurityInfoError - * and log: - * - FORBIDDEN - if there is no authorization - * - profileUuid - if the device does not have a profile - * - device - if the thingsboard does not have a device with a name equal to the identity - */ - private SecurityInfo addLwM2MClientToSession(String identity) { - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, TypeServer.CLIENT); - if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { - UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null; - if (store.getSecurityInfo() != null && profileUuid != null) { - String endpoint = store.getSecurityInfo().getEndpoint(); - sessions.put(endpoint, new LwM2mClient(endpoint, store.getSecurityInfo().getIdentity(), store.getSecurityInfo(), store.getMsg(), profileUuid, UUID.randomUUID())); - } else if (store.getSecurityMode() == NO_SEC.code && profileUuid != null) { - sessions.put(identity, new LwM2mClient(identity, null, null, store.getMsg(), profileUuid, UUID.randomUUID())); - } else { - log.error("Registration failed: FORBIDDEN/profileUuid/device [{}] , endpointId: [{}]", profileUuid, identity); - /** - * Return Error securityInfo - */ - byte[] preSharedKey = Hex.decodeHex("0A0B".toCharArray()); - SecurityInfo infoError = SecurityInfo.newPreSharedKeyInfo("error", "error_identity", preSharedKey); - return infoError; - } - } - return store.getSecurityInfo(); - } - - public Map getSession(UUID sessionUuId) { - return this.sessions.entrySet().stream() - .filter(e -> e.getValue().getSessionId().equals(sessionUuId)) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - } - - public Map getSessions() { - return this.sessions; - } - - public Map getProfiles() { - return this.profiles; - } - - public LwM2mClientProfile getProfile(UUID profileUuId) { - return this.profiles.get(profileUuId); - } - - public LwM2mClientProfile getProfile(String registrationId) { - UUID profileUUid = this.getSessions().get(registrationId).getProfileId(); - return this.getProfiles().get(profileUUid); - } - - public Map setProfiles(Map profiles) { - return this.profiles = profiles; - } - - public boolean addUpdateProfileParameters(DeviceProfile deviceProfile) { - LwM2mClientProfile lwM2MClientProfile = LwM2mTransportHandler.getLwM2MClientProfileFromThingsboard(deviceProfile); - if (lwM2MClientProfile != null) { - profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile); - return true; - } - return false; - } -} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mStoreConfiguration.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mStoreConfiguration.java index 9e4b7e442a..06a4612499 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mStoreConfiguration.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mStoreConfiguration.java @@ -29,6 +29,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.server.cache.TBRedisCacheConfiguration; import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; import java.util.Collection; @@ -89,10 +90,14 @@ public class TbLwM2mStoreConfiguration { } @Override - public SecurityInfo getByEndpoint(String endpoint) { - SecurityInfo securityInfo = securityStore.getByEndpoint(endpoint); + public SecurityInfo getByEndpoint(String endPoint) { + SecurityInfo securityInfo = securityStore.getByEndpoint(endPoint); if (securityInfo == null) { - securityInfo = clientContext.addLwM2mClientToSession(endpoint).getSecurityInfo(); + LwM2mClient lwM2mClient = clientContext.getLwM2MClient(endPoint, null); + if (lwM2mClient != null && !lwM2mClient.getRegistration().getIdentity().isSecure()){ + return null; + } + securityInfo = clientContext.addLwM2mClientToSession(endPoint).getSecurityInfo(); try { if (securityInfo != null) { add(securityInfo); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 0afdcd760a..6a078cf36c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -466,7 +466,6 @@ public class ModelConstants { public static final String RESOURCE_TITLE_COLUMN = TITLE_PROPERTY; public static final String RESOURCE_DATA_COLUMN = "data"; - /** * Cassandra attributes and timeseries constants. */ diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java index 816700fe03..8d14d4e6cb 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java @@ -65,7 +65,8 @@ public class TbResourceEntity extends BaseSqlEntity implements Searc } public TbResourceEntity(TbResource resource) { - this.setUuid(resource.getId().getId()); + this.id = resource.getUuidId(); + this.createdTime = resource.getCreatedTime(); this.tenantId = resource.getTenantId().getId(); this.title = resource.getTitle(); this.resourceType = resource.getResourceType().name(); 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 104b6604e1..9504962fe3 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 @@ -43,6 +43,8 @@ import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_SEARCH_TEXT; import static org.thingsboard.server.dao.device.DeviceServiceImpl.INCORRECT_TENANT_ID; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -62,26 +64,24 @@ public class BaseTbResourceService implements TbResourceService { } @Override - public TbResource saveResource(TbResource resource) throws InvalidDDFFileException, IOException { - log.trace("Executing saveResource [{}]", resource); - - if (resource.getId() == null && ResourceType.LWM2M_MODEL.equals(resource.getResourceType())) { + public TbResource saveResource(TbResource tbResource) throws InvalidDDFFileException, IOException { + log.trace("Executing saveResource [{}]", tbResource); + if (ResourceType.LWM2M_MODEL.equals(tbResource.getResourceType())) { List objectModels = - ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(resource.getData())), resource.getSearchText()); + ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(tbResource.getData())), tbResource.getSearchText()); if (!objectModels.isEmpty()) { ObjectModel objectModel = objectModels.get(0); - - String resourceKey = objectModel.id + "_" + objectModel.getVersion(); + String resourceKey = objectModel.id + LWM2M_SEPARATOR_KEY + objectModel.getVersion(); String name = objectModel.name; - resource.setResourceKey(resourceKey); - resource.setTitle(name); - resource.setSearchText(resourceKey + ":" + name); + tbResource.setResourceKey(resourceKey); + tbResource.setTitle(name); + tbResource.setSearchText(resourceKey + LWM2M_SEPARATOR_SEARCH_TEXT + name); + } else { + throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", tbResource.getSearchText())); } } - - validate(resource); - - return resourceDao.saveResource(resource); + validate(tbResource); + return resourceDao.save(tbResource.getTenantId(), tbResource); } @Override @@ -162,9 +162,6 @@ public class BaseTbResourceService implements TbResourceService { throw new DataValidationException("Resource value should be specified!"); } validate(resource.getTenantId(), resource.getResourceType(), resource.getResourceKey()); - if (resource.getResourceType().equals(ResourceType.LWM2M_MODEL) && this.toLwM2mObject(resource) == null) { - throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText())); - } } protected void validate(TenantId tenantId, ResourceType resourceType, String resourceId) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceDao.java b/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceDao.java index 538b99aa32..230e104191 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceDao.java @@ -26,8 +26,6 @@ import java.util.List; public interface TbResourceDao extends Dao { - TbResource saveResource(TbResource resource); - TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId); PageData findAllByTenantId(TenantId tenantId, PageLink pageLink); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceDao.java index e437894a02..f35f654f77 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceDao.java @@ -18,7 +18,6 @@ package org.thingsboard.server.dao.sql.resource; import lombok.extern.slf4j.Slf4j; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.id.TenantId; @@ -53,12 +52,6 @@ public class JpaTbResourceDao extends JpaAbstractSearchTextDao