Lwm2m: backEnd: refactoring service
This commit is contained in:
		
							parent
							
								
									bc4684c907
								
							
						
					
					
						commit
						be4475c2cc
					
				@ -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<SecurityInfo> 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);
 | 
			
		||||
 | 
			
		||||
@ -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];
 | 
			
		||||
    }
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
@ -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() {
 | 
			
		||||
 | 
			
		||||
@ -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!");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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<Observation> 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<String> 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) {
 | 
			
		||||
 | 
			
		||||
@ -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<Observation> previousObsersations) {
 | 
			
		||||
            service.onRegistered(lhServer, registration, previousObsersations);
 | 
			
		||||
                               Collection<Observation> previousObservations) {
 | 
			
		||||
            service.onRegistered(lhServer, registration, previousObservations);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
@ -120,4 +113,5 @@ public class LwM2mServerListener {
 | 
			
		||||
            log.info("Received newObservation from [{}] endpoint  [{}] ", observation.getPath(), registration.getEndpoint());
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -63,12 +63,12 @@ public class LwM2MClient implements Cloneable {
 | 
			
		||||
        return super.clone();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public LwM2MClient(String endPoint, String identity, SecurityInfo info, ValidateDeviceCredentialsResponseMsg credentialsResponse, Map<String, String> 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<String, String>();
 | 
			
		||||
        this.attributes = new ConcurrentHashMap<>();
 | 
			
		||||
        this.pendingRequests = ConcurrentHashMap.newKeySet();
 | 
			
		||||
        this.delayedRequests = new ConcurrentHashMap<>();
 | 
			
		||||
        this.resources = new ConcurrentHashMap<>();
 | 
			
		||||
 | 
			
		||||
@ -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<Integer, ?> values, Object value, boolean multiInstances) {
 | 
			
		||||
    public ResourceValue(Map<Integer, ?> values, Object value, boolean multiInstances) {
 | 
			
		||||
        this.values = values;
 | 
			
		||||
        this.value = value;
 | 
			
		||||
        this.multiInstances = multiInstances;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Object getResourceValue() {
 | 
			
		||||
        return this.multiInstances ? this.values : this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -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<String /** registrationId */, LwM2MClient> sessions = new ConcurrentHashMap<>();
 | 
			
		||||
    protected Map<UUID /** profileUUid */, AttrTelemetryObserveValue> profiles = new ConcurrentHashMap<>();
 | 
			
		||||
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
 | 
			
		||||
    private final Lock readLock = readWriteLock.readLock();
 | 
			
		||||
    private final Lock writeLock = readWriteLock.writeLock();
 | 
			
		||||
    private final Map<String /** registrationId */, LwM2MClient> sessions = new ConcurrentHashMap<>();
 | 
			
		||||
    private Map<UUID /** profileUUid */, AttrTelemetryObserveValue> 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<SecurityInfo> 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);
 | 
			
		||||
                    /**
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user