From be4475c2cc61935bdb73c76fa97cd1fa8cfef768 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 5 Jan 2021 19:06:14 +0200 Subject: [PATCH] Lwm2m: backEnd: refactoring service --- .../secure/LwM2MBootstrapSecurityStore.java | 8 +- ...wM2mCredentialsSecurityInfoValidator.java} | 8 +- .../lwm2m/server/LwM2MTransportRequest.java | 7 +- .../LwM2MTransportServerConfiguration.java | 10 -- .../LwM2MTransportServerInitializer.java | 37 +++--- .../server/LwM2MTransportServiceImpl.java | 111 ++++++++++-------- .../lwm2m/server/LwM2mServerListener.java | 20 ++-- .../lwm2m/server/client/LwM2MClient.java | 4 +- .../lwm2m/server/client/ResourceValue.java | 4 +- .../secure/LwM2mInMemorySecurityStore.java | 31 ++--- 10 files changed, 113 insertions(+), 127 deletions(-) rename common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/{LwM2mValidateCredentialsSecurityInfo.java => LwM2mCredentialsSecurityInfoValidator.java} (97%) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapSecurityStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapSecurityStore.java index 6d21d48c65..75e6f78d35 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapSecurityStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapSecurityStore.java @@ -32,7 +32,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Service; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; -import org.thingsboard.server.transport.lwm2m.secure.LwM2mValidateCredentialsSecurityInfo; +import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; import org.thingsboard.server.transport.lwm2m.server.LwM2MSessionMsgListener; import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportContextServer; @@ -60,7 +60,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { private final EditableBootstrapConfigStore bootstrapConfigStore; @Autowired - LwM2mValidateCredentialsSecurityInfo lwM2MValidateCredentialsSecurityInfo; + LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator; @Autowired public LwM2MTransportContextServer context; @@ -72,7 +72,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { @Override public List getAllByEndpoint(String endPoint) { String endPointKey = endPoint; - ReadResultSecurityStore store = lwM2MValidateCredentialsSecurityInfo.validateCredentialsSecurityInfo(endPointKey, TypeServer.BOOTSTRAP); + ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(endPointKey, TypeServer.BOOTSTRAP); if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { /** add value to store from BootstrapJson */ this.setBootstrapConfigScurityInfo(store); @@ -96,7 +96,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { @Override public SecurityInfo getByIdentity(String identity) { - ReadResultSecurityStore store = lwM2MValidateCredentialsSecurityInfo.validateCredentialsSecurityInfo(identity, TypeServer.BOOTSTRAP); + ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, TypeServer.BOOTSTRAP); if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { /** add value to store from BootstrapJson */ this.setBootstrapConfigScurityInfo(store); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mValidateCredentialsSecurityInfo.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mCredentialsSecurityInfoValidator.java similarity index 97% rename from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mValidateCredentialsSecurityInfo.java rename to common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mCredentialsSecurityInfoValidator.java index 0983f9c87f..80b4772378 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mValidateCredentialsSecurityInfo.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mCredentialsSecurityInfoValidator.java @@ -47,7 +47,7 @@ import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.X5 @Slf4j @Component("LwM2MGetSecurityInfo") @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") -public class LwM2mValidateCredentialsSecurityInfo { +public class LwM2mCredentialsSecurityInfoValidator { @Autowired public LwM2MTransportContextServer contextS; @@ -62,7 +62,7 @@ public class LwM2mValidateCredentialsSecurityInfo { * @param keyValue - * @return ValidateDeviceCredentialsResponseMsg and SecurityInfo */ - public ReadResultSecurityStore validateCredentialsSecurityInfo(String endPoint, TypeServer keyValue) { + public ReadResultSecurityStore createAndValidateCredentialsSecurityInfo(String endPoint, TypeServer keyValue) { CountDownLatch latch = new CountDownLatch(1); final ReadResultSecurityStore[] resultSecurityStore = new ReadResultSecurityStore[1]; contextS.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endPoint).build(), @@ -79,7 +79,7 @@ public class LwM2mValidateCredentialsSecurityInfo { @Override public void onError(Throwable e) { - log.trace("[{}] [{}] Failed to process credentials PSK ", endPoint, e.toString()); + log.trace("[{}] [{}] Failed to process credentials ", endPoint, e); resultSecurityStore[0] = createSecurityInfo(endPoint, null, null); latch.countDown(); } @@ -87,7 +87,7 @@ public class LwM2mValidateCredentialsSecurityInfo { try { latch.await(contextS.getCtxServer().getTimeout(), TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - log.error("", e); + log.error("Failed to await credentials!", e); } return resultSecurityStore[0]; } 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 bc7cbd5b46..de03e25767 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 @@ -88,13 +88,12 @@ public class LwM2MTransportRequest { @Autowired LwM2MTransportServiceImpl service; - @PostConstruct public void init() { this.converter = LwM2mValueConverterImpl.getInstance(); - executorResponse = Executors.newCachedThreadPool( + executorResponse = Executors.newFixedThreadPool(10, new NamedThreadFactory(String.format("LwM2M %s channel response", RESPONSE_CHANNEL))); - executorResponseError = Executors.newCachedThreadPool( + executorResponseError = Executors.newFixedThreadPool(10, new NamedThreadFactory(String.format("LwM2M %s channel response Error", RESPONSE_CHANNEL))); } @@ -220,7 +219,7 @@ public class LwM2MTransportRequest { if (request != null) { this.sendRequest(lwServer, registration, request, lwM2MClient, timeoutInMs, isDelayedUpdate); - } else if (request == null && isDelayedUpdate) { + } else if (isDelayedUpdate) { String msg = String.format(LOG_LW2M_ERROR + ": sendRequest: Resource path - %s msg No SendRequest to Client", target); service.sentLogsToThingsboard(msg, registration); log.error("[{}] - [{}] No SendRequest", target); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerConfiguration.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerConfiguration.java index ac2221054c..c809491803 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerConfiguration.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerConfiguration.java @@ -82,16 +82,6 @@ public class LwM2MTransportServerConfiguration { @Autowired private LwM2mInMemorySecurityStore lwM2mInMemorySecurityStore; - @Bean - public LwM2mServerListener lwM2mServerListenerCert() { - return new LwM2mServerListener(); - } - - @Bean - public LwM2mServerListener lwM2mServerListenerNoSecPskRpk() { - return new LwM2mServerListener(); - } - @Primary @Bean(name = "LeshanServerCert") public LeshanServer getLeshanServerCert() { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerInitializer.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerInitializer.java index 36d39130a3..da4cdbf634 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerInitializer.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerInitializer.java @@ -32,6 +32,10 @@ import javax.annotation.PreDestroy; @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") public class LwM2MTransportServerInitializer { + + @Autowired + private LwM2MTransportServiceImpl service; + @Autowired @Qualifier("LeshanServerCert") private LeshanServer lhServerCert; @@ -39,16 +43,6 @@ public class LwM2MTransportServerInitializer { @Autowired @Qualifier("LeshanServerNoSecPskRpk") private LeshanServer lhServerNoSecPskRpk; -// -// @Autowired -// @Qualifier("LeshanServerListener") -// private LwM2mServerListener lwM2mServerListener; - - @Autowired - private LwM2mServerListener lwM2mServerListenerNoSecPskRpk; - - @Autowired - private LwM2mServerListener lwM2mServerListenerCert; @Autowired private LwM2MTransportContextServer context; @@ -70,28 +64,25 @@ public class LwM2MTransportServerInitializer { private void startLhServerCert() { this.lhServerCert.start(); - LwM2mServerListener serverListenerCert = this.lwM2mServerListenerCert.init(this.lhServerCert); - this.lhServerCert.getRegistrationService().addListener(serverListenerCert.registrationListener); - this.lhServerCert.getPresenceService().addListener(serverListenerCert.presenceListener); - this.lhServerCert.getObservationService().addListener(serverListenerCert.observationListener); + LwM2mServerListener lhServerCertListener = new LwM2mServerListener(this.lhServerCert, service); + this.lhServerCert.getRegistrationService().addListener(lhServerCertListener.registrationListener); + this.lhServerCert.getPresenceService().addListener(lhServerCertListener.presenceListener); + this.lhServerCert.getObservationService().addListener(lhServerCertListener.observationListener); } private void startLhServerNoSecPskRpk() { this.lhServerNoSecPskRpk.start(); - LwM2mServerListener serverListenerNoSecPskRpk = this.lwM2mServerListenerNoSecPskRpk.init(this.lhServerNoSecPskRpk); - this.lhServerNoSecPskRpk.getRegistrationService().addListener(serverListenerNoSecPskRpk.registrationListener); - this.lhServerNoSecPskRpk.getPresenceService().addListener(serverListenerNoSecPskRpk.presenceListener); - this.lhServerNoSecPskRpk.getObservationService().addListener(serverListenerNoSecPskRpk.observationListener); + LwM2mServerListener lhServerNoSecPskRpkListener = new LwM2mServerListener(this.lhServerNoSecPskRpk, service); + this.lhServerNoSecPskRpk.getRegistrationService().addListener(lhServerNoSecPskRpkListener.registrationListener); + this.lhServerNoSecPskRpk.getPresenceService().addListener(lhServerNoSecPskRpkListener.presenceListener); + this.lhServerNoSecPskRpk.getObservationService().addListener(lhServerNoSecPskRpkListener.observationListener); } @PreDestroy public void shutdown() { log.info("Stopping LwM2M transport Server!"); - try { - lhServerCert.destroy(); - lhServerNoSecPskRpk.destroy(); - } finally { - } + lhServerCert.destroy(); + lhServerNoSecPskRpk.destroy(); log.info("LwM2M transport Server stopped!"); } } 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 2a6af4e19e..c4575c1a8f 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 @@ -20,6 +20,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import lombok.extern.slf4j.Slf4j; +import org.eclipse.leshan.core.Link; import org.eclipse.leshan.core.model.ResourceModel; import org.eclipse.leshan.core.node.LwM2mMultipleResource; import org.eclipse.leshan.core.node.LwM2mObject; @@ -56,7 +57,6 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; import javax.annotation.PostConstruct; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashSet; @@ -68,7 +68,6 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -80,7 +79,6 @@ import java.util.stream.Collectors; import static org.thingsboard.server.common.transport.util.JsonUtils.getJsonObject; import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.CLIENT_NOT_AUTHORIZED; -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.DEFAULT_TIMEOUT; import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.DEVICE_ATTRIBUTES_REQUEST; import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.DEVICE_ATTRIBUTES_TOPIC; import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.DEVICE_TELEMETRY_TOPIC; @@ -122,11 +120,11 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @PostConstruct public void init() { this.context.getScheduler().scheduleAtFixedRate(this::checkInactivityAndReportActivity, new Random().nextInt((int) context.getCtxServer().getSessionReportTimeout()), context.getCtxServer().getSessionReportTimeout(), TimeUnit.MILLISECONDS); - this.executorRegistered = Executors.newCachedThreadPool( + this.executorRegistered = Executors.newFixedThreadPool(10, new NamedThreadFactory(String.format("LwM2M %s channel registered", SERVICE_CHANNEL))); - this.executorUpdateRegistered = Executors.newCachedThreadPool( + this.executorUpdateRegistered = Executors.newFixedThreadPool(10, new NamedThreadFactory(String.format("LwM2M %s channel update registered", SERVICE_CHANNEL))); - this.executorUnRegistered = Executors.newCachedThreadPool( + this.executorUnRegistered = Executors.newFixedThreadPool(10, new NamedThreadFactory(String.format("LwM2M %s channel un registered", SERVICE_CHANNEL))); this.converter = LwM2mValueConverterImpl.getInstance(); } @@ -149,7 +147,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { public void onRegistered(LeshanServer lwServer, Registration registration, Collection previousObsersations) { executorRegistered.submit(() -> { try { - log.info("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); + log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.updateInSessionsLwM2MClient(lwServer, registration); if (lwM2MClient != null) { lwM2MClient.setLwM2MTransportServiceImpl(this); @@ -180,6 +178,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { /** * if sessionInfo removed from sessions, then new registerAsyncSession + * * @param lwServer - LeshanServer * @param registration - Registration LwM2M Client */ @@ -280,20 +279,38 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { * @param lwM2MClient - object with All parameters off client */ private void setLwM2MClient(LeshanServer lwServer, Registration registration, LwM2MClient lwM2MClient) { - Arrays.stream(registration.getObjectLinks()).forEach(url -> { + // #1 + for (Link url : registration.getObjectLinks()) { LwM2mPath pathIds = new LwM2mPath(url.getUrl()); if (pathIds.isObjectInstance() && !pathIds.isResource()) { lwM2MClient.getPendingRequests().add(url.getUrl()); } - }); + } // #2 - Arrays.stream(registration.getObjectLinks()).forEach(url -> { + for (Link url : registration.getObjectLinks()) { LwM2mPath pathIds = new LwM2mPath(url.getUrl()); if (pathIds.isObjectInstance() && !pathIds.isResource()) { lwM2MTransportRequest.sendAllRequest(lwServer, registration, url.getUrl(), GET_TYPE_OPER_READ, ContentFormat.TLV.getName(), lwM2MClient, null, null, this.context.getCtxServer().getTimeout(), false); } - }); + } + + // #1 +// Arrays.stream(registration.getObjectLinks()).forEach(url -> { +// LwM2mPath pathIds = new LwM2mPath(url.getUrl()); +// if (pathIds.isObjectInstance() && !pathIds.isResource()) { +// lwM2MClient.getPendingRequests().add(url.getUrl()); +// } +// }); + // #2 + +// Arrays.stream(registration.getObjectLinks()).forEach(url -> { +// LwM2mPath pathIds = new LwM2mPath(url.getUrl()); +// if (pathIds.isObjectInstance() && !pathIds.isResource()) { +// lwM2MTransportRequest.sendAllRequest(lwServer, registration, url.getUrl(), GET_TYPE_OPER_READ, ContentFormat.TLV.getName(), +// lwM2MClient, null, null, this.context.getCtxServer().getTimeout(), false); +// } +// }); } /** @@ -302,18 +319,17 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { */ private SessionInfoProto getValidateSessionInfo(Registration registration) { LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(registration, null); - return getNewSessionInfoProto(lwM2MClient); + return getNewSessionInfoProto(lwM2MClient); } /** - * * @param registrationId - * @return - */ private SessionInfoProto getValidateSessionInfo(String registrationId) { LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(null, registrationId); - return getNewSessionInfoProto(lwM2MClient); + return getNewSessionInfoProto(lwM2MClient); } private SessionInfoProto getNewSessionInfoProto(LwM2MClient lwM2MClient) { @@ -437,6 +453,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { /** * Get names and keyNames from profile shared!!!! attr resources IsWritable + * * @param lwM2MClient - * @return ArrayList keyNames from profile attr resources shared!!!! && IsWritable */ @@ -479,13 +496,13 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { } } // #1.2 - CountDownLatch cancelLatch = new CountDownLatch(1); - this.getParametersFromProfile(attributes, telemetries, registration, paths); - cancelLatch.countDown(); try { - cancelLatch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - log.error("[{}] updateAttrTelemetry", e.toString()); + writeLock.lock(); + this.getParametersFromProfile(attributes, telemetries, registration, paths); + } catch (Exception e) { + log.error("UpdateAttrTelemetry", e); + } finally { + writeLock.unlock(); } if (attributes.getAsJsonObject().entrySet().size() > 0) this.updateParametersOnThingsboard(attributes, DEVICE_ATTRIBUTES_TOPIC, registration); @@ -559,8 +576,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { /** * Prepare Sent to Thigsboard callback - Attribute or Telemetry * - * @param msg - JsonArray: [{name: value}] - * @param topicName - Api Attribute or Telemetry + * @param msg - JsonArray: [{name: value}] + * @param topicName - Api Attribute or Telemetry * @param registration - Id of Registration LwM2M Client */ public void updateParametersOnThingsboard(JsonElement msg, String topicName, Registration registration) { @@ -618,14 +635,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { * {@code ObservationService#cancelObservation()} */ public void setCancelObservationRecourse(LeshanServer lwServer, Registration registration, String path) { - CountDownLatch cancelLatch = new CountDownLatch(1); lwServer.getObservationService().cancelObservations(registration, path); - cancelLatch.countDown(); - try { - cancelLatch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - log.error("", e); - } } /** @@ -685,30 +695,28 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { boolean isChange = false; try { writeLock.lock(); - try { - // #1 - LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(registration, null); - LwM2mPath pathIds = new LwM2mPath(path); - log.warn("#0 nameDevice: [{}] resultIds: [{}] value: [{}], values: [{}] ", lwM2MClient.getDeviceName(), pathIds, value, values); - ResourceModel.Type resModelType = context.getCtxServer().getResourceModelType(registration, pathIds); - ResourceValue resValueOld = lwM2MClient.getResources().get(path); - // #2 - if (resValueOld.isMultiInstances() && !values.toString().equals(resValueOld.getResourceValue().toString())) { - ResourceValue resourceValue = new ResourceValue(values, null, true); - lwM2MClient.getResources().put(path, resourceValue); - isChange = true; - } else if (!LwM2MTransportHandler.equalsResourceValue(resValueOld.getValue(), value, resModelType, pathIds)) { - ResourceValue resourceValue = new ResourceValue(null, value, false); - lwM2MClient.getResources().put(path, resourceValue); - isChange = true; - } - } finally { - writeLock.unlock(); + // #1 + LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(registration, null); + LwM2mPath pathIds = new LwM2mPath(path); + log.warn("#0 nameDevice: [{}] resultIds: [{}] value: [{}], values: [{}] ", lwM2MClient.getDeviceName(), pathIds, value, values); + ResourceModel.Type resModelType = context.getCtxServer().getResourceModelType(registration, pathIds); + ResourceValue resValueOld = lwM2MClient.getResources().get(path); + // #2 + if (resValueOld.isMultiInstances() && !values.toString().equals(resValueOld.getResourceValue().toString())) { + ResourceValue resourceValue = new ResourceValue(values, null, true); + lwM2MClient.getResources().put(path, resourceValue); + isChange = true; + } else if (!LwM2MTransportHandler.equalsResourceValue(resValueOld.getValue(), value, resModelType, pathIds)) { + ResourceValue resourceValue = new ResourceValue(null, value, false); + lwM2MClient.getResources().put(path, resourceValue); + isChange = true; } + } catch (Exception e) { + log.error("#1_1 Update ResourcesValue after Observation is unsuccessfully path: [{}] value: [{}] [{}]", path, value, e.toString()); + } finally { + writeLock.unlock(); } - catch (Exception e) { - log.error("#1_1 Update ResourcesValue after Observation in CountDownLatch is unsuccessfully path: [{}] value: [{}] [{}]", path, value, e.toString()); - } + if (isChange) { Set paths = new HashSet<>(); paths.add(path); @@ -1103,6 +1111,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { /** * if sessionInfo removed from sessions, then new registerAsyncSession + * * @param sessionInfo - */ private void checkInactivity(SessionInfoProto sessionInfo) { 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 2028fb4f00..239a40658f 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 @@ -24,25 +24,18 @@ import org.eclipse.leshan.server.queue.PresenceListener; import org.eclipse.leshan.server.registration.Registration; import org.eclipse.leshan.server.registration.RegistrationListener; import org.eclipse.leshan.server.registration.RegistrationUpdate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; -import org.springframework.stereotype.Component; import java.util.Collection; @Slf4j -@Component() -@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' )|| ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") public class LwM2mServerListener { - private LeshanServer lhServer; + private final LeshanServer lhServer; + private final LwM2MTransportServiceImpl service; - @Autowired - private LwM2MTransportServiceImpl service; - - public LwM2mServerListener init(LeshanServer lhServer) { + public LwM2mServerListener(LeshanServer lhServer, LwM2MTransportServiceImpl service) { this.lhServer = lhServer; - return this; + this.service = service; } public final RegistrationListener registrationListener = new RegistrationListener() { @@ -51,8 +44,8 @@ public class LwM2mServerListener { */ @Override public void registered(Registration registration, Registration previousReg, - Collection previousObsersations) { - service.onRegistered(lhServer, registration, previousObsersations); + Collection previousObservations) { + service.onRegistered(lhServer, registration, previousObservations); } /** @@ -120,4 +113,5 @@ public class LwM2mServerListener { log.info("Received newObservation from [{}] endpoint [{}] ", observation.getPath(), registration.getEndpoint()); } }; + } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2MClient.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2MClient.java index d48e3e4c9e..72cb052dc7 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2MClient.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2MClient.java @@ -63,12 +63,12 @@ public class LwM2MClient implements Cloneable { return super.clone(); } - public LwM2MClient(String endPoint, String identity, SecurityInfo info, ValidateDeviceCredentialsResponseMsg credentialsResponse, Map attributes, UUID profileUuid) { + public LwM2MClient(String endPoint, String identity, SecurityInfo info, ValidateDeviceCredentialsResponseMsg credentialsResponse, UUID profileUuid) { this.endPoint = endPoint; this.identity = identity; this.info = info; this.credentialsResponse = credentialsResponse; - this.attributes = (attributes != null && attributes.size() > 0) ? attributes : new ConcurrentHashMap(); + this.attributes = new ConcurrentHashMap<>(); this.pendingRequests = ConcurrentHashMap.newKeySet(); this.delayedRequests = new ConcurrentHashMap<>(); this.resources = new ConcurrentHashMap<>(); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ResourceValue.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ResourceValue.java index d58890dfba..2c962a4395 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ResourceValue.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ResourceValue.java @@ -16,6 +16,7 @@ package org.thingsboard.server.transport.lwm2m.server.client; import lombok.Data; + import java.util.Map; @Data @@ -24,11 +25,12 @@ public class ResourceValue { Object value; boolean multiInstances; - public ResourceValue ( Map values, Object value, boolean multiInstances) { + public ResourceValue(Map values, Object value, boolean multiInstances) { this.values = values; this.value = value; this.multiInstances = multiInstances; } + public Object getResourceValue() { return this.multiInstances ? this.values : this.value; } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/secure/LwM2mInMemorySecurityStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/secure/LwM2mInMemorySecurityStore.java index fb90b1537c..088962cb71 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/secure/LwM2mInMemorySecurityStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/secure/LwM2mInMemorySecurityStore.java @@ -29,7 +29,7 @@ import org.springframework.stereotype.Service; 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.LwM2mValidateCredentialsSecurityInfo; +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.AttrTelemetryObserveValue; @@ -53,17 +53,18 @@ import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO @Service("LwM2mInMemorySecurityStore") @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' )|| ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { + private static final boolean INFOS_ARE_COMPROMISED = false; + // lock for the two maps - protected final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); - protected final Lock readLock = readWriteLock.readLock(); - protected final Lock writeLock = readWriteLock.writeLock(); - private final boolean infosAreCompromised = false; - protected Map sessions = new ConcurrentHashMap<>(); - protected Map profiles = new ConcurrentHashMap<>(); + 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 - LwM2mValidateCredentialsSecurityInfo lwM2MValidateCredentialsSecurityInfo; + LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator; /** * Start after DefaultAuthorizer or LwM2mPskStore @@ -75,8 +76,8 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { readLock.lock(); try { String registrationId = this.getByRegistrationId(endPoint, null); - SecurityInfo info = (registrationId != null && sessions.size() > 0 && sessions.get(registrationId) != null) ? sessions.get(registrationId).getInfo() : this.addLwM2MClientToSession(endPoint); - return info; + return (registrationId != null && sessions.size() > 0 && sessions.get(registrationId) != null) ? + sessions.get(registrationId).getInfo() : this.addLwM2MClientToSession(endPoint); } finally { readLock.unlock(); } @@ -102,7 +103,7 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { public Collection getAll() { readLock.lock(); try { - return Collections.unmodifiableCollection(this.sessions.entrySet().stream().map(model -> model.getValue().getInfo()).collect(Collectors.toList())); + return Collections.unmodifiableCollection(this.sessions.values().stream().map(LwM2MClient::getInfo).collect(Collectors.toList())); } finally { readLock.unlock(); } @@ -118,7 +119,7 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { LwM2MClient lwM2MClient = (sessions.get(registrationId) != null) ? sessions.get(registrationId) : null; if (lwM2MClient != null) { if (listener != null) { - listener.securityInfoRemoved(infosAreCompromised, lwM2MClient.getInfo()); + listener.securityInfoRemoved(INFOS_ARE_COMPROMISED, lwM2MClient.getInfo()); } sessions.remove(registrationId); } @@ -198,14 +199,14 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { * - device - if the thingsboard does not have a device with a name equal to the identity */ private SecurityInfo addLwM2MClientToSession(String identity) { - ReadResultSecurityStore store = lwM2MValidateCredentialsSecurityInfo.validateCredentialsSecurityInfo(identity, TypeServer.CLIENT); + 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(), null, profileUuid)); + sessions.put(endpoint, new LwM2MClient(endpoint, store.getSecurityInfo().getIdentity(), store.getSecurityInfo(), store.getMsg(), profileUuid)); } else if (store.getSecurityMode() == NO_SEC.code && profileUuid != null) { - sessions.put(identity, new LwM2MClient(identity, null, null, store.getMsg(), null, profileUuid)); + sessions.put(identity, new LwM2MClient(identity, null, null, store.getMsg(), profileUuid)); } else { log.error("Registration failed: FORBIDDEN/profileUuid/device [{}] , endpointId: [{}]", profileUuid, identity); /**