Commit e96452cdcf527f6f4b624a8fa78b3086943d9191

Authored by Volodymyr Babak
2 parents aedebc32 3716e283

Merge remote-tracking branch 'upstream/develop/3.3' into develop/3.3-edge

Showing 82 changed files with 1999 additions and 495 deletions
@@ -30,7 +30,8 @@ import java.util.Arrays; @@ -30,7 +30,8 @@ import java.util.Arrays;
30 "org.thingsboard.server.service.component", 30 "org.thingsboard.server.service.component",
31 "org.thingsboard.server.service.install", 31 "org.thingsboard.server.service.install",
32 "org.thingsboard.server.dao", 32 "org.thingsboard.server.dao",
33 - "org.thingsboard.server.common.stats"}) 33 + "org.thingsboard.server.common.stats",
  34 + "org.thingsboard.server.cache"})
34 public class ThingsboardInstallApplication { 35 public class ThingsboardInstallApplication {
35 36
36 private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name"; 37 private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name";
@@ -47,8 +47,7 @@ import org.thingsboard.server.common.data.id.EdgeId; @@ -47,8 +47,7 @@ import org.thingsboard.server.common.data.id.EdgeId;
47 import org.thingsboard.server.common.data.id.TenantId; 47 import org.thingsboard.server.common.data.id.TenantId;
48 import org.thingsboard.server.common.data.page.PageData; 48 import org.thingsboard.server.common.data.page.PageData;
49 import org.thingsboard.server.common.data.page.PageLink; 49 import org.thingsboard.server.common.data.page.PageLink;
50 -import org.thingsboard.server.common.data.page.TimePageLink;  
51 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 50 +import org.thingsboard.common.util.JacksonUtil;
52 import org.thingsboard.server.queue.util.TbCoreComponent; 51 import org.thingsboard.server.queue.util.TbCoreComponent;
53 import org.thingsboard.server.service.security.model.SecurityUser; 52 import org.thingsboard.server.service.security.model.SecurityUser;
54 import org.thingsboard.server.service.security.permission.Operation; 53 import org.thingsboard.server.service.security.permission.Operation;
@@ -50,7 +50,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionFailedException; @@ -50,7 +50,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionFailedException;
50 import org.thingsboard.server.dao.device.provision.ProvisionRequest; 50 import org.thingsboard.server.dao.device.provision.ProvisionRequest;
51 import org.thingsboard.server.dao.device.provision.ProvisionResponse; 51 import org.thingsboard.server.dao.device.provision.ProvisionResponse;
52 import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus; 52 import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus;
53 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 53 +import org.thingsboard.common.util.JacksonUtil;
54 import org.thingsboard.server.gen.transport.TransportProtos; 54 import org.thingsboard.server.gen.transport.TransportProtos;
55 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; 55 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
56 import org.thingsboard.server.queue.TbQueueCallback; 56 import org.thingsboard.server.queue.TbQueueCallback;
@@ -41,7 +41,7 @@ import org.thingsboard.server.dao.entityview.EntityViewService; @@ -41,7 +41,7 @@ import org.thingsboard.server.dao.entityview.EntityViewService;
41 import org.thingsboard.server.dao.rule.RuleChainService; 41 import org.thingsboard.server.dao.rule.RuleChainService;
42 import org.thingsboard.server.dao.tenant.TenantService; 42 import org.thingsboard.server.dao.tenant.TenantService;
43 import org.thingsboard.server.dao.timeseries.TimeseriesService; 43 import org.thingsboard.server.dao.timeseries.TimeseriesService;
44 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 44 +import org.thingsboard.common.util.JacksonUtil;
45 import org.thingsboard.server.service.install.InstallScripts; 45 import org.thingsboard.server.service.install.InstallScripts;
46 46
47 import java.util.ArrayList; 47 import java.util.ArrayList;
@@ -51,7 +51,6 @@ import java.util.concurrent.ExecutionException; @@ -51,7 +51,6 @@ import java.util.concurrent.ExecutionException;
51 import java.util.stream.Collectors; 51 import java.util.stream.Collectors;
52 52
53 import static org.apache.commons.lang3.StringUtils.isBlank; 53 import static org.apache.commons.lang3.StringUtils.isBlank;
54 -import static org.thingsboard.server.service.install.DatabaseHelper.objectMapper;  
55 54
56 @Service 55 @Service
57 @Profile("install") 56 @Profile("install")
@@ -47,7 +47,7 @@ import org.thingsboard.server.dao.attributes.AttributesService; @@ -47,7 +47,7 @@ import org.thingsboard.server.dao.attributes.AttributesService;
47 import org.thingsboard.server.dao.entity.EntityService; 47 import org.thingsboard.server.dao.entity.EntityService;
48 import org.thingsboard.server.dao.model.ModelConstants; 48 import org.thingsboard.server.dao.model.ModelConstants;
49 import org.thingsboard.server.dao.timeseries.TimeseriesService; 49 import org.thingsboard.server.dao.timeseries.TimeseriesService;
50 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 50 +import org.thingsboard.common.util.JacksonUtil;
51 import org.thingsboard.server.queue.util.TbCoreComponent; 51 import org.thingsboard.server.queue.util.TbCoreComponent;
52 import org.thingsboard.server.service.executors.DbCallbackExecutorService; 52 import org.thingsboard.server.service.executors.DbCallbackExecutorService;
53 import org.thingsboard.server.service.security.AccessValidator; 53 import org.thingsboard.server.service.security.AccessValidator;
@@ -35,7 +35,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; @@ -35,7 +35,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
35 import org.thingsboard.server.common.msg.queue.TbCallback; 35 import org.thingsboard.server.common.msg.queue.TbCallback;
36 import org.thingsboard.server.common.stats.StatsFactory; 36 import org.thingsboard.server.common.stats.StatsFactory;
37 import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; 37 import org.thingsboard.server.common.transport.util.DataDecodingEncodingService;
38 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 38 +import org.thingsboard.common.util.JacksonUtil;
39 import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto; 39 import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto;
40 import org.thingsboard.server.gen.transport.TransportProtos.EdgeNotificationMsgProto; 40 import org.thingsboard.server.gen.transport.TransportProtos.EdgeNotificationMsgProto;
41 import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto; 41 import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto;
@@ -49,7 +49,7 @@ import org.thingsboard.server.dao.exception.DataValidationException; @@ -49,7 +49,7 @@ import org.thingsboard.server.dao.exception.DataValidationException;
49 import org.thingsboard.server.dao.settings.AdminSettingsService; 49 import org.thingsboard.server.dao.settings.AdminSettingsService;
50 import org.thingsboard.server.dao.user.UserService; 50 import org.thingsboard.server.dao.user.UserService;
51 import org.thingsboard.server.dao.user.UserServiceImpl; 51 import org.thingsboard.server.dao.user.UserServiceImpl;
52 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 52 +import org.thingsboard.common.util.JacksonUtil;
53 import org.thingsboard.server.service.security.exception.UserPasswordExpiredException; 53 import org.thingsboard.server.service.security.exception.UserPasswordExpiredException;
54 import org.thingsboard.server.utils.MiscUtils; 54 import org.thingsboard.server.utils.MiscUtils;
55 55
@@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; @@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
31 import org.thingsboard.server.common.data.id.EntityId; 31 import org.thingsboard.server.common.data.id.EntityId;
32 import org.thingsboard.server.common.data.id.TenantId; 32 import org.thingsboard.server.common.data.id.TenantId;
33 import org.thingsboard.server.dao.settings.AdminSettingsService; 33 import org.thingsboard.server.dao.settings.AdminSettingsService;
34 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 34 +import org.thingsboard.common.util.JacksonUtil;
35 import org.thingsboard.server.queue.usagestats.TbApiUsageClient; 35 import org.thingsboard.server.queue.usagestats.TbApiUsageClient;
36 import org.thingsboard.server.service.apiusage.TbApiUsageStateService; 36 import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
37 37
@@ -52,7 +52,7 @@ import org.thingsboard.server.dao.attributes.AttributesService; @@ -52,7 +52,7 @@ import org.thingsboard.server.dao.attributes.AttributesService;
52 import org.thingsboard.server.dao.device.DeviceService; 52 import org.thingsboard.server.dao.device.DeviceService;
53 import org.thingsboard.server.dao.tenant.TenantService; 53 import org.thingsboard.server.dao.tenant.TenantService;
54 import org.thingsboard.server.dao.timeseries.TimeseriesService; 54 import org.thingsboard.server.dao.timeseries.TimeseriesService;
55 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 55 +import org.thingsboard.common.util.JacksonUtil;
56 import org.thingsboard.server.gen.transport.TransportProtos; 56 import org.thingsboard.server.gen.transport.TransportProtos;
57 import org.thingsboard.server.queue.discovery.PartitionChangeEvent; 57 import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
58 import org.thingsboard.server.queue.discovery.PartitionService; 58 import org.thingsboard.server.queue.discovery.PartitionService;
@@ -39,7 +39,7 @@ import org.thingsboard.server.common.msg.queue.TbCallback; @@ -39,7 +39,7 @@ import org.thingsboard.server.common.msg.queue.TbCallback;
39 import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; 39 import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
40 import org.thingsboard.server.dao.attributes.AttributesService; 40 import org.thingsboard.server.dao.attributes.AttributesService;
41 import org.thingsboard.server.dao.timeseries.TimeseriesService; 41 import org.thingsboard.server.dao.timeseries.TimeseriesService;
42 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 42 +import org.thingsboard.common.util.JacksonUtil;
43 import org.thingsboard.server.gen.transport.TransportProtos.*; 43 import org.thingsboard.server.gen.transport.TransportProtos.*;
44 import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto; 44 import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto;
45 import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionUpdateProto; 45 import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionUpdateProto;
@@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.kv.KvEntry; @@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.kv.KvEntry;
30 import org.thingsboard.server.common.data.kv.LongDataEntry; 30 import org.thingsboard.server.common.data.kv.LongDataEntry;
31 import org.thingsboard.server.common.data.kv.StringDataEntry; 31 import org.thingsboard.server.common.data.kv.StringDataEntry;
32 import org.thingsboard.server.common.data.kv.TsKvEntry; 32 import org.thingsboard.server.common.data.kv.TsKvEntry;
33 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 33 +import org.thingsboard.common.util.JacksonUtil;
34 import org.thingsboard.server.gen.transport.TransportProtos; 34 import org.thingsboard.server.gen.transport.TransportProtos;
35 import org.thingsboard.server.gen.transport.TransportProtos.KeyValueProto; 35 import org.thingsboard.server.gen.transport.TransportProtos.KeyValueProto;
36 import org.thingsboard.server.gen.transport.TransportProtos.KeyValueType; 36 import org.thingsboard.server.gen.transport.TransportProtos.KeyValueType;
@@ -54,7 +54,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionRequest; @@ -54,7 +54,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionRequest;
54 import org.thingsboard.server.dao.device.provision.ProvisionResponse; 54 import org.thingsboard.server.dao.device.provision.ProvisionResponse;
55 import org.thingsboard.server.dao.relation.RelationService; 55 import org.thingsboard.server.dao.relation.RelationService;
56 import org.thingsboard.server.dao.tenant.TbTenantProfileCache; 56 import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
57 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 57 +import org.thingsboard.common.util.JacksonUtil;
58 import org.thingsboard.server.gen.transport.TransportProtos; 58 import org.thingsboard.server.gen.transport.TransportProtos;
59 import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; 59 import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto;
60 import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg; 60 import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg;
@@ -643,8 +643,8 @@ transport: @@ -643,8 +643,8 @@ transport:
643 public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:3fc4e61bcd8901ec27c424114c3e887ed372497f0c2cf85839b8443e76988b34}" 643 public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:3fc4e61bcd8901ec27c424114c3e887ed372497f0c2cf85839b8443e76988b34}"
644 private_encoded: "${LWM2M_SERVER_PRIVATE_ENCODED_BS:308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104205ecafd90caa7be45c42e1f3f32571632b8409e6e6249d7124f4ba56fab3c8083a00a06082a8648ce3d030107a144034200045017c87a1c1768264656b3b355434b0def6edb8b9bf166a4762d9930cd730f913fc4e61bcd8901ec27c424114c3e887ed372497f0c2cf85839b8443e76988b34}" # Only Certificate_x509: 644 private_encoded: "${LWM2M_SERVER_PRIVATE_ENCODED_BS:308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104205ecafd90caa7be45c42e1f3f32571632b8409e6e6249d7124f4ba56fab3c8083a00a06082a8648ce3d030107a144034200045017c87a1c1768264656b3b355434b0def6edb8b9bf166a4762d9930cd730f913fc4e61bcd8901ec27c424114c3e887ed372497f0c2cf85839b8443e76988b34}" # Only Certificate_x509:
645 alias: "${LWM2M_KEYSTORE_ALIAS_BOOTSTRAP:bootstrap}" 645 alias: "${LWM2M_KEYSTORE_ALIAS_BOOTSTRAP:bootstrap}"
646 - # Redis  
647 - redis_url: "${LWM2M_REDIS_URL:''}" 646 + # Use redis for Security and Registration stores
  647 + redis.enabled: "${LWM2M_REDIS_ENABLED:false}"
648 648
649 # Edges parameters 649 # Edges parameters
650 edges: 650 edges:
@@ -26,7 +26,7 @@ import org.junit.Before; @@ -26,7 +26,7 @@ import org.junit.Before;
26 import org.junit.Test; 26 import org.junit.Test;
27 import org.thingsboard.server.common.data.Device; 27 import org.thingsboard.server.common.data.Device;
28 import org.thingsboard.server.common.data.device.profile.MqttTopics; 28 import org.thingsboard.server.common.data.device.profile.MqttTopics;
29 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 29 +import org.thingsboard.common.util.JacksonUtil;
30 import org.thingsboard.server.mqtt.attributes.AbstractMqttAttributesIntegrationTest; 30 import org.thingsboard.server.mqtt.attributes.AbstractMqttAttributesIntegrationTest;
31 31
32 import java.nio.charset.StandardCharsets; 32 import java.nio.charset.StandardCharsets;
@@ -25,7 +25,7 @@ import org.junit.Test; @@ -25,7 +25,7 @@ import org.junit.Test;
25 import org.thingsboard.server.common.data.Device; 25 import org.thingsboard.server.common.data.Device;
26 import org.thingsboard.server.common.data.TransportPayloadType; 26 import org.thingsboard.server.common.data.TransportPayloadType;
27 import org.thingsboard.server.common.data.device.profile.MqttTopics; 27 import org.thingsboard.server.common.data.device.profile.MqttTopics;
28 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 28 +import org.thingsboard.common.util.JacksonUtil;
29 import org.thingsboard.server.mqtt.attributes.AbstractMqttAttributesIntegrationTest; 29 import org.thingsboard.server.mqtt.attributes.AbstractMqttAttributesIntegrationTest;
30 30
31 import java.nio.charset.StandardCharsets; 31 import java.nio.charset.StandardCharsets;
@@ -37,7 +37,7 @@ import org.thingsboard.server.common.transport.util.JsonUtils; @@ -37,7 +37,7 @@ import org.thingsboard.server.common.transport.util.JsonUtils;
37 import org.thingsboard.server.dao.device.DeviceCredentialsService; 37 import org.thingsboard.server.dao.device.DeviceCredentialsService;
38 import org.thingsboard.server.dao.device.DeviceService; 38 import org.thingsboard.server.dao.device.DeviceService;
39 import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus; 39 import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus;
40 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 40 +import org.thingsboard.common.util.JacksonUtil;
41 import org.thingsboard.server.mqtt.AbstractMqttIntegrationTest; 41 import org.thingsboard.server.mqtt.AbstractMqttIntegrationTest;
42 42
43 import java.util.concurrent.CountDownLatch; 43 import java.util.concurrent.CountDownLatch;
@@ -36,7 +36,7 @@ import org.thingsboard.server.common.msg.EncryptionUtil; @@ -36,7 +36,7 @@ import org.thingsboard.server.common.msg.EncryptionUtil;
36 import org.thingsboard.server.dao.device.DeviceCredentialsService; 36 import org.thingsboard.server.dao.device.DeviceCredentialsService;
37 import org.thingsboard.server.dao.device.DeviceService; 37 import org.thingsboard.server.dao.device.DeviceService;
38 import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus; 38 import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus;
39 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 39 +import org.thingsboard.common.util.JacksonUtil;
40 import org.thingsboard.server.gen.transport.TransportProtos.CredentialsDataProto; 40 import org.thingsboard.server.gen.transport.TransportProtos.CredentialsDataProto;
41 import org.thingsboard.server.gen.transport.TransportProtos.CredentialsType; 41 import org.thingsboard.server.gen.transport.TransportProtos.CredentialsType;
42 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceCredentialsMsg; 42 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceCredentialsMsg;
@@ -47,7 +47,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenR @@ -47,7 +47,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenR
47 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; 47 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg;
48 import org.thingsboard.server.mqtt.AbstractMqttIntegrationTest; 48 import org.thingsboard.server.mqtt.AbstractMqttIntegrationTest;
49 49
50 -import java.util.UUID;  
51 import java.util.concurrent.CountDownLatch; 50 import java.util.concurrent.CountDownLatch;
52 import java.util.concurrent.TimeUnit; 51 import java.util.concurrent.TimeUnit;
53 52
@@ -30,7 +30,7 @@ import org.junit.Assert; @@ -30,7 +30,7 @@ import org.junit.Assert;
30 import org.thingsboard.server.common.data.Device; 30 import org.thingsboard.server.common.data.Device;
31 import org.thingsboard.server.common.data.TransportPayloadType; 31 import org.thingsboard.server.common.data.TransportPayloadType;
32 import org.thingsboard.server.common.data.device.profile.MqttTopics; 32 import org.thingsboard.server.common.data.device.profile.MqttTopics;
33 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 33 +import org.thingsboard.common.util.JacksonUtil;
34 import org.thingsboard.server.mqtt.AbstractMqttIntegrationTest; 34 import org.thingsboard.server.mqtt.AbstractMqttIntegrationTest;
35 35
36 import java.util.Arrays; 36 import java.util.Arrays;
  1 +<!--
  2 +
  3 + Copyright © 2016-2021 The Thingsboard Authors
  4 +
  5 + Licensed under the Apache License, Version 2.0 (the "License");
  6 + you may not use this file except in compliance with the License.
  7 + You may obtain a copy of the License at
  8 +
  9 + http://www.apache.org/licenses/LICENSE-2.0
  10 +
  11 + Unless required by applicable law or agreed to in writing, software
  12 + distributed under the License is distributed on an "AS IS" BASIS,
  13 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 + See the License for the specific language governing permissions and
  15 + limitations under the License.
  16 +
  17 +-->
  18 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  19 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  20 + <modelVersion>4.0.0</modelVersion>
  21 + <parent>
  22 + <groupId>org.thingsboard</groupId>
  23 + <version>3.3.0-SNAPSHOT</version>
  24 + <artifactId>common</artifactId>
  25 + </parent>
  26 + <groupId>org.thingsboard.common</groupId>
  27 + <artifactId>cache</artifactId>
  28 + <packaging>jar</packaging>
  29 +
  30 + <name>Thingsboard Server Common Cache</name>
  31 + <url>https://thingsboard.io</url>
  32 +
  33 + <properties>
  34 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  35 + <main.dir>${basedir}/../..</main.dir>
  36 + </properties>
  37 +
  38 + <dependencies>
  39 + <dependency>
  40 + <groupId>org.thingsboard.common</groupId>
  41 + <artifactId>data</artifactId>
  42 + </dependency>
  43 + <dependency>
  44 + <groupId>org.springframework.boot</groupId>
  45 + <artifactId>spring-boot-autoconfigure</artifactId>
  46 + </dependency>
  47 + <dependency>
  48 + <groupId>org.springframework.data</groupId>
  49 + <artifactId>spring-data-redis</artifactId>
  50 + </dependency>
  51 + <dependency>
  52 + <groupId>redis.clients</groupId>
  53 + <artifactId>jedis</artifactId>
  54 + </dependency>
  55 + <dependency>
  56 + <groupId>com.github.ben-manes.caffeine</groupId>
  57 + <artifactId>caffeine</artifactId>
  58 + </dependency>
  59 + <dependency>
  60 + <groupId>org.apache.commons</groupId>
  61 + <artifactId>commons-lang3</artifactId>
  62 + </dependency>
  63 + <dependency>
  64 + <groupId>org.slf4j</groupId>
  65 + <artifactId>slf4j-api</artifactId>
  66 + </dependency>
  67 + <dependency>
  68 + <groupId>org.slf4j</groupId>
  69 + <artifactId>log4j-over-slf4j</artifactId>
  70 + </dependency>
  71 + <dependency>
  72 + <groupId>ch.qos.logback</groupId>
  73 + <artifactId>logback-core</artifactId>
  74 + </dependency>
  75 + <dependency>
  76 + <groupId>ch.qos.logback</groupId>
  77 + <artifactId>logback-classic</artifactId>
  78 + </dependency>
  79 + <dependency>
  80 + <groupId>junit</groupId>
  81 + <artifactId>junit</artifactId>
  82 + <scope>test</scope>
  83 + </dependency>
  84 + <dependency>
  85 + <groupId>org.mockito</groupId>
  86 + <artifactId>mockito-core</artifactId>
  87 + <scope>test</scope>
  88 + </dependency>
  89 + </dependencies>
  90 +
  91 + <build>
  92 + <plugins>
  93 +<!-- <plugin>-->
  94 +<!-- <groupId>org.apache.maven.plugins</groupId>-->
  95 +<!-- <artifactId>maven-source-plugin</artifactId>-->
  96 +<!-- <executions>-->
  97 +<!-- <execution>-->
  98 +<!-- <id>attach-sources</id>-->
  99 +<!-- <goals>-->
  100 +<!-- <goal>jar</goal>-->
  101 +<!-- </goals>-->
  102 +<!-- </execution>-->
  103 +<!-- </executions>-->
  104 +<!-- </plugin>-->
  105 +<!-- <plugin>-->
  106 +<!-- <groupId>org.apache.maven.plugins</groupId>-->
  107 +<!-- <artifactId>maven-deploy-plugin</artifactId>-->
  108 +<!-- <configuration>-->
  109 +<!-- <skip>false</skip>-->
  110 +<!-- </configuration>-->
  111 +<!-- </plugin>-->
  112 + </plugins>
  113 + </build>
  114 +
  115 +</project>
common/cache/src/main/java/org/thingsboard/server/cache/CacheSpecs.java renamed from dao/src/main/java/org/thingsboard/server/dao/cache/CacheSpecs.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.dao.cache; 16 +package org.thingsboard.server.cache;
17 17
18 import lombok.Data; 18 import lombok.Data;
19 19
common/cache/src/main/java/org/thingsboard/server/cache/CaffeineCacheConfiguration.java renamed from dao/src/main/java/org/thingsboard/server/dao/cache/CaffeineCacheConfiguration.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.dao.cache; 16 +package org.thingsboard.server.cache;
17 17
18 import com.github.benmanes.caffeine.cache.Caffeine; 18 import com.github.benmanes.caffeine.cache.Caffeine;
19 import com.github.benmanes.caffeine.cache.RemovalCause; 19 import com.github.benmanes.caffeine.cache.RemovalCause;
@@ -26,7 +26,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @@ -26,7 +26,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
26 import org.springframework.cache.CacheManager; 26 import org.springframework.cache.CacheManager;
27 import org.springframework.cache.annotation.EnableCaching; 27 import org.springframework.cache.annotation.EnableCaching;
28 import org.springframework.cache.caffeine.CaffeineCache; 28 import org.springframework.cache.caffeine.CaffeineCache;
29 -import org.springframework.cache.interceptor.KeyGenerator;  
30 import org.springframework.cache.support.SimpleCacheManager; 29 import org.springframework.cache.support.SimpleCacheManager;
31 import org.springframework.context.annotation.Bean; 30 import org.springframework.context.annotation.Bean;
32 import org.springframework.context.annotation.Configuration; 31 import org.springframework.context.annotation.Configuration;
@@ -78,14 +77,9 @@ public class CaffeineCacheConfiguration { @@ -78,14 +77,9 @@ public class CaffeineCacheConfiguration {
78 return Ticker.systemTicker(); 77 return Ticker.systemTicker();
79 } 78 }
80 79
81 - @Bean  
82 - public KeyGenerator previousDeviceCredentialsId() {  
83 - return new PreviousDeviceCredentialsIdKeyGenerator();  
84 - }  
85 -  
86 private Weigher<? super Object, ? super Object> collectionSafeWeigher() { 80 private Weigher<? super Object, ? super Object> collectionSafeWeigher() {
87 return (Weigher<Object, Object>) (key, value) -> { 81 return (Weigher<Object, Object>) (key, value) -> {
88 - if(value instanceof Collection) { 82 + if (value instanceof Collection) {
89 return ((Collection) value).size(); 83 return ((Collection) value).size();
90 } 84 }
91 return 1; 85 return 1;
common/cache/src/main/java/org/thingsboard/server/cache/TBRedisCacheConfiguration.java renamed from dao/src/main/java/org/thingsboard/server/dao/cache/TBRedisCacheConfiguration.java
@@ -13,14 +13,13 @@ @@ -13,14 +13,13 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.dao.cache; 16 +package org.thingsboard.server.cache;
17 17
18 import lombok.Data; 18 import lombok.Data;
19 import org.springframework.beans.factory.annotation.Value; 19 import org.springframework.beans.factory.annotation.Value;
20 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 20 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
21 import org.springframework.cache.CacheManager; 21 import org.springframework.cache.CacheManager;
22 import org.springframework.cache.annotation.EnableCaching; 22 import org.springframework.cache.annotation.EnableCaching;
23 -import org.springframework.cache.interceptor.KeyGenerator;  
24 import org.springframework.context.annotation.Bean; 23 import org.springframework.context.annotation.Bean;
25 import org.springframework.context.annotation.Configuration; 24 import org.springframework.context.annotation.Configuration;
26 import org.springframework.core.convert.converter.ConverterRegistry; 25 import org.springframework.core.convert.converter.ConverterRegistry;
@@ -90,11 +89,6 @@ public abstract class TBRedisCacheConfiguration { @@ -90,11 +89,6 @@ public abstract class TBRedisCacheConfiguration {
90 } 89 }
91 90
92 @Bean 91 @Bean
93 - public KeyGenerator previousDeviceCredentialsId() {  
94 - return new PreviousDeviceCredentialsIdKeyGenerator();  
95 - }  
96 -  
97 - @Bean  
98 public RedisTemplate<String, Object> redisTemplate() { 92 public RedisTemplate<String, Object> redisTemplate() {
99 RedisTemplate<String, Object> template = new RedisTemplate<>(); 93 RedisTemplate<String, Object> template = new RedisTemplate<>();
100 template.setConnectionFactory(redisConnectionFactory()); 94 template.setConnectionFactory(redisConnectionFactory());
common/cache/src/main/java/org/thingsboard/server/cache/TBRedisClusterConfiguration.java renamed from dao/src/main/java/org/thingsboard/server/dao/cache/TBRedisClusterConfiguration.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.dao.cache; 16 +package org.thingsboard.server.cache;
17 17
18 import org.apache.commons.lang3.StringUtils; 18 import org.apache.commons.lang3.StringUtils;
19 import org.springframework.beans.factory.annotation.Value; 19 import org.springframework.beans.factory.annotation.Value;
common/cache/src/main/java/org/thingsboard/server/cache/TBRedisStandaloneConfiguration.java renamed from dao/src/main/java/org/thingsboard/server/dao/cache/TBRedisStandaloneConfiguration.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.dao.cache; 16 +package org.thingsboard.server.cache;
17 17
18 import org.springframework.beans.factory.annotation.Value; 18 import org.springframework.beans.factory.annotation.Value;
19 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 19 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -42,6 +42,7 @@ @@ -42,6 +42,7 @@
42 <module>transport</module> 42 <module>transport</module>
43 <module>dao-api</module> 43 <module>dao-api</module>
44 <module>stats</module> 44 <module>stats</module>
  45 + <module>cache</module>
45 <module>edge-api</module> 46 <module>edge-api</module>
46 </modules> 47 </modules>
47 48
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.queue.util;
  17 +
  18 +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
  19 +
  20 +import java.lang.annotation.Retention;
  21 +import java.lang.annotation.RetentionPolicy;
  22 +
  23 +@Retention(RetentionPolicy.RUNTIME)
  24 +@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")
  25 +public @interface TbLwM2mTransportComponent {
  26 +}
@@ -90,7 +90,6 @@ @@ -90,7 +90,6 @@
90 <groupId>org.eclipse.leshan</groupId> 90 <groupId>org.eclipse.leshan</groupId>
91 <artifactId>leshan-client-cf</artifactId> 91 <artifactId>leshan-client-cf</artifactId>
92 </dependency> 92 </dependency>
93 -  
94 <dependency> 93 <dependency>
95 <groupId>org.eclipse.leshan</groupId> 94 <groupId>org.eclipse.leshan</groupId>
96 <artifactId>leshan-server-redis</artifactId> 95 <artifactId>leshan-server-redis</artifactId>
@@ -29,7 +29,7 @@ import org.springframework.stereotype.Component; @@ -29,7 +29,7 @@ import org.springframework.stereotype.Component;
29 import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapSecurityStore; 29 import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapSecurityStore;
30 import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MInMemoryBootstrapConfigStore; 30 import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MInMemoryBootstrapConfigStore;
31 import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2mDefaultBootstrapSessionManager; 31 import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2mDefaultBootstrapSessionManager;
32 -import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportContextServer; 32 +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer;
33 33
34 import java.math.BigInteger; 34 import java.math.BigInteger;
35 import java.security.AlgorithmParameters; 35 import java.security.AlgorithmParameters;
@@ -56,7 +56,7 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE @@ -56,7 +56,7 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE
56 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8; 56 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
57 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; 57 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256;
58 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8; 58 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8;
59 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.getCoapConfig; 59 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getCoapConfig;
60 60
61 @Slf4j 61 @Slf4j
62 @Component 62 @Component
@@ -70,7 +70,7 @@ public class LwM2MTransportBootstrapServerConfiguration { @@ -70,7 +70,7 @@ public class LwM2MTransportBootstrapServerConfiguration {
70 private LwM2MTransportContextBootstrap contextBs; 70 private LwM2MTransportContextBootstrap contextBs;
71 71
72 @Autowired 72 @Autowired
73 - private LwM2MTransportContextServer contextS; 73 + private LwM2mTransportContextServer contextS;
74 74
75 @Autowired 75 @Autowired
76 private LwM2MBootstrapSecurityStore lwM2MBootstrapSecurityStore; 76 private LwM2MBootstrapSecurityStore lwM2MBootstrapSecurityStore;
@@ -94,7 +94,7 @@ public class LwM2MTransportBootstrapServerConfiguration { @@ -94,7 +94,7 @@ public class LwM2MTransportBootstrapServerConfiguration {
94 builder.setCoapConfig(getCoapConfig(bootstrapPortNoSec, bootstrapSecurePort)); 94 builder.setCoapConfig(getCoapConfig(bootstrapPortNoSec, bootstrapSecurePort));
95 95
96 /** Define model provider (Create Models )*/ 96 /** Define model provider (Create Models )*/
97 - builder.setModel(new StaticModel(contextS.getCtxServer().getModelsValue())); 97 + builder.setModel(new StaticModel(contextS.getLwM2MTransportConfigServer().getModelsValue()));
98 98
99 /** Create credentials */ 99 /** Create credentials */
100 this.setServerWithCredentials(builder); 100 this.setServerWithCredentials(builder);
@@ -108,8 +108,8 @@ public class LwM2MTransportBootstrapServerConfiguration { @@ -108,8 +108,8 @@ public class LwM2MTransportBootstrapServerConfiguration {
108 108
109 /** Create and Set DTLS Config */ 109 /** Create and Set DTLS Config */
110 DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder(); 110 DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder();
111 - dtlsConfig.setRecommendedSupportedGroupsOnly(this.contextS.getCtxServer().isRecommendedSupportedGroups());  
112 - dtlsConfig.setRecommendedCipherSuitesOnly(this.contextS.getCtxServer().isRecommendedCiphers()); 111 + dtlsConfig.setRecommendedSupportedGroupsOnly(this.contextS.getLwM2MTransportConfigServer().isRecommendedSupportedGroups());
  112 + dtlsConfig.setRecommendedCipherSuitesOnly(this.contextS.getLwM2MTransportConfigServer().isRecommendedCiphers());
113 if (this.pskMode) { 113 if (this.pskMode) {
114 dtlsConfig.setSupportedCipherSuites( 114 dtlsConfig.setSupportedCipherSuites(
115 TLS_PSK_WITH_AES_128_CCM_8, 115 TLS_PSK_WITH_AES_128_CCM_8,
@@ -135,10 +135,10 @@ public class LwM2MTransportBootstrapServerConfiguration { @@ -135,10 +135,10 @@ public class LwM2MTransportBootstrapServerConfiguration {
135 135
136 private void setServerWithCredentials(LeshanBootstrapServerBuilder builder) { 136 private void setServerWithCredentials(LeshanBootstrapServerBuilder builder) {
137 try { 137 try {
138 - if (this.contextS.getCtxServer().getKeyStoreValue() != null) {  
139 - KeyStore keyStoreServer = this.contextS.getCtxServer().getKeyStoreValue(); 138 + if (this.contextS.getLwM2MTransportConfigServer().getKeyStoreValue() != null) {
  139 + KeyStore keyStoreServer = this.contextS.getLwM2MTransportConfigServer().getKeyStoreValue();
140 if (this.setBuilderX509(builder)) { 140 if (this.setBuilderX509(builder)) {
141 - X509Certificate rootCAX509Cert = (X509Certificate) keyStoreServer.getCertificate(this.contextS.getCtxServer().getRootAlias()); 141 + X509Certificate rootCAX509Cert = (X509Certificate) keyStoreServer.getCertificate(this.contextS.getLwM2MTransportConfigServer().getRootAlias());
142 if (rootCAX509Cert != null) { 142 if (rootCAX509Cert != null) {
143 X509Certificate[] trustedCertificates = new X509Certificate[1]; 143 X509Certificate[] trustedCertificates = new X509Certificate[1];
144 trustedCertificates[0] = rootCAX509Cert; 144 trustedCertificates[0] = rootCAX509Cert;
@@ -169,8 +169,8 @@ public class LwM2MTransportBootstrapServerConfiguration { @@ -169,8 +169,8 @@ public class LwM2MTransportBootstrapServerConfiguration {
169 * For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks 169 * For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks
170 */ 170 */
171 try { 171 try {
172 - X509Certificate serverCertificate = (X509Certificate) this.contextS.getCtxServer().getKeyStoreValue().getCertificate(this.contextBs.getCtxBootStrap().getBootstrapAlias());  
173 - PrivateKey privateKey = (PrivateKey) this.contextS.getCtxServer().getKeyStoreValue().getKey(this.contextBs.getCtxBootStrap().getBootstrapAlias(), this.contextS.getCtxServer().getKeyStorePasswordServer() == null ? null : this.contextS.getCtxServer().getKeyStorePasswordServer().toCharArray()); 172 + X509Certificate serverCertificate = (X509Certificate) this.contextS.getLwM2MTransportConfigServer().getKeyStoreValue().getCertificate(this.contextBs.getCtxBootStrap().getBootstrapAlias());
  173 + PrivateKey privateKey = (PrivateKey) this.contextS.getLwM2MTransportConfigServer().getKeyStoreValue().getKey(this.contextBs.getCtxBootStrap().getBootstrapAlias(), this.contextS.getLwM2MTransportConfigServer().getKeyStorePasswordServer() == null ? null : this.contextS.getLwM2MTransportConfigServer().getKeyStorePasswordServer().toCharArray());
174 PublicKey publicKey = serverCertificate.getPublicKey(); 174 PublicKey publicKey = serverCertificate.getPublicKey();
175 if (serverCertificate != null && 175 if (serverCertificate != null &&
176 privateKey != null && privateKey.getEncoded().length > 0 && 176 privateKey != null && privateKey.getEncoded().length > 0 &&
@@ -31,30 +31,24 @@ package org.thingsboard.server.transport.lwm2m.bootstrap; @@ -31,30 +31,24 @@ package org.thingsboard.server.transport.lwm2m.bootstrap;
31 */ 31 */
32 32
33 import lombok.extern.slf4j.Slf4j; 33 import lombok.extern.slf4j.Slf4j;
34 -import org.springframework.beans.factory.annotation.Autowired;  
35 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; 34 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
36 import org.springframework.stereotype.Component; 35 import org.springframework.stereotype.Component;
37 import org.thingsboard.server.common.transport.TransportContext; 36 import org.thingsboard.server.common.transport.TransportContext;
38 import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigBootstrap; 37 import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigBootstrap;
39 38
40 -import javax.annotation.PostConstruct;  
41 -  
42 39
43 @Slf4j 40 @Slf4j
44 @Component 41 @Component
45 @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true') || '${service.type:null}'=='monolith'") 42 @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true') || '${service.type:null}'=='monolith'")
46 public class LwM2MTransportContextBootstrap extends TransportContext { 43 public class LwM2MTransportContextBootstrap extends TransportContext {
47 44
48 - private LwM2MTransportConfigBootstrap ctxBootStrap;  
49 - @Autowired  
50 - LwM2MTransportConfigBootstrap lwM2MTransportConfigBootstarp; 45 + private final LwM2MTransportConfigBootstrap lwM2MTransportConfigBootstrap;
51 46
52 - @PostConstruct  
53 - public void init() {  
54 - this.ctxBootStrap = lwM2MTransportConfigBootstarp; 47 + public LwM2MTransportContextBootstrap(LwM2MTransportConfigBootstrap ctxBootStrap) {
  48 + this.lwM2MTransportConfigBootstrap = ctxBootStrap;
55 } 49 }
56 50
57 public LwM2MTransportConfigBootstrap getCtxBootStrap() { 51 public LwM2MTransportConfigBootstrap getCtxBootStrap() {
58 - return this.ctxBootStrap; 52 + return this.lwM2MTransportConfigBootstrap;
59 } 53 }
60 } 54 }
@@ -27,16 +27,15 @@ import org.eclipse.leshan.server.bootstrap.EditableBootstrapConfigStore; @@ -27,16 +27,15 @@ import org.eclipse.leshan.server.bootstrap.EditableBootstrapConfigStore;
27 import org.eclipse.leshan.server.bootstrap.InvalidConfigurationException; 27 import org.eclipse.leshan.server.bootstrap.InvalidConfigurationException;
28 import org.eclipse.leshan.server.security.BootstrapSecurityStore; 28 import org.eclipse.leshan.server.security.BootstrapSecurityStore;
29 import org.eclipse.leshan.server.security.SecurityInfo; 29 import org.eclipse.leshan.server.security.SecurityInfo;
30 -import org.springframework.beans.factory.annotation.Autowired;  
31 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; 30 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
32 import org.springframework.stereotype.Service; 31 import org.springframework.stereotype.Service;
33 import org.thingsboard.server.gen.transport.TransportProtos; 32 import org.thingsboard.server.gen.transport.TransportProtos;
34 import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; 33 import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
35 import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; 34 import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
36 import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; 35 import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore;
37 -import org.thingsboard.server.transport.lwm2m.server.LwM2MSessionMsgListener;  
38 -import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportContextServer;  
39 -import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler; 36 +import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener;
  37 +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer;
  38 +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler;
40 import org.thingsboard.server.transport.lwm2m.utils.TypeServer; 39 import org.thingsboard.server.transport.lwm2m.utils.TypeServer;
41 40
42 import java.io.IOException; 41 import java.io.IOException;
@@ -45,12 +44,12 @@ import java.util.Arrays; @@ -45,12 +44,12 @@ import java.util.Arrays;
45 import java.util.List; 44 import java.util.List;
46 import java.util.UUID; 45 import java.util.UUID;
47 46
48 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.BOOTSTRAP_SERVER;  
49 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.LOG_LW2M_ERROR;  
50 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.LOG_LW2M_INFO;  
51 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.LWM2M_SERVER;  
52 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.SERVERS;  
53 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.getBootstrapParametersFromThingsboard; 47 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.BOOTSTRAP_SERVER;
  48 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR;
  49 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO;
  50 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LWM2M_SERVER;
  51 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.SERVERS;
  52 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getBootstrapParametersFromThingsboard;
54 53
55 @Slf4j 54 @Slf4j
56 @Service("LwM2MBootstrapSecurityStore") 55 @Service("LwM2MBootstrapSecurityStore")
@@ -59,14 +58,14 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { @@ -59,14 +58,14 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
59 58
60 private final EditableBootstrapConfigStore bootstrapConfigStore; 59 private final EditableBootstrapConfigStore bootstrapConfigStore;
61 60
62 - @Autowired  
63 - LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator; 61 + private final LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator;
64 62
65 - @Autowired  
66 - public LwM2MTransportContextServer context; 63 + private final LwM2mTransportContextServer context;
67 64
68 - public LwM2MBootstrapSecurityStore(EditableBootstrapConfigStore bootstrapConfigStore) { 65 + public LwM2MBootstrapSecurityStore(EditableBootstrapConfigStore bootstrapConfigStore, LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator, LwM2mTransportContextServer context) {
69 this.bootstrapConfigStore = bootstrapConfigStore; 66 this.bootstrapConfigStore = bootstrapConfigStore;
  67 + this.lwM2MCredentialsSecurityInfoValidator = lwM2MCredentialsSecurityInfoValidator;
  68 + this.context = context;
70 } 69 }
71 70
72 @Override 71 @Override
@@ -162,18 +161,18 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { @@ -162,18 +161,18 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
162 LwM2MServerBootstrap profileLwm2mServer = mapper.readValue(bootstrapObject.get(LWM2M_SERVER).toString(), LwM2MServerBootstrap.class); 161 LwM2MServerBootstrap profileLwm2mServer = mapper.readValue(bootstrapObject.get(LWM2M_SERVER).toString(), LwM2MServerBootstrap.class);
163 UUID sessionUUiD = UUID.randomUUID(); 162 UUID sessionUUiD = UUID.randomUUID();
164 TransportProtos.SessionInfoProto sessionInfo = context.getValidateSessionInfo(store.getMsg(), sessionUUiD.getMostSignificantBits(), sessionUUiD.getLeastSignificantBits()); 163 TransportProtos.SessionInfoProto sessionInfo = context.getValidateSessionInfo(store.getMsg(), sessionUUiD.getMostSignificantBits(), sessionUUiD.getLeastSignificantBits());
165 - context.getTransportService().registerAsyncSession(sessionInfo, new LwM2MSessionMsgListener(null, sessionInfo)); 164 + context.getTransportService().registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(null, sessionInfo));
166 if (this.getValidatedSecurityMode(lwM2MBootstrapConfig.bootstrapServer, profileServerBootstrap, lwM2MBootstrapConfig.lwm2mServer, profileLwm2mServer)) { 165 if (this.getValidatedSecurityMode(lwM2MBootstrapConfig.bootstrapServer, profileServerBootstrap, lwM2MBootstrapConfig.lwm2mServer, profileLwm2mServer)) {
167 lwM2MBootstrapConfig.bootstrapServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.bootstrapServer, profileServerBootstrap); 166 lwM2MBootstrapConfig.bootstrapServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.bootstrapServer, profileServerBootstrap);
168 lwM2MBootstrapConfig.lwm2mServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.lwm2mServer, profileLwm2mServer); 167 lwM2MBootstrapConfig.lwm2mServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.lwm2mServer, profileLwm2mServer);
169 String logMsg = String.format("%s: getParametersBootstrap: %s Access connect client with bootstrap server.", LOG_LW2M_INFO, store.getEndPoint()); 168 String logMsg = String.format("%s: getParametersBootstrap: %s Access connect client with bootstrap server.", LOG_LW2M_INFO, store.getEndPoint());
170 - context.sentParametersOnThingsboard(context.getTelemetryMsgObject(logMsg), LwM2MTransportHandler.DEVICE_TELEMETRY_TOPIC, sessionInfo); 169 + context.sentParametersOnThingsboard(context.getTelemetryMsgObject(logMsg), LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC, sessionInfo);
171 return lwM2MBootstrapConfig; 170 return lwM2MBootstrapConfig;
172 } else { 171 } else {
173 log.error(" [{}] Different values SecurityMode between of client and profile.", store.getEndPoint()); 172 log.error(" [{}] Different values SecurityMode between of client and profile.", store.getEndPoint());
174 log.error("{} getParametersBootstrap: [{}] Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint()); 173 log.error("{} getParametersBootstrap: [{}] Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint());
175 String logMsg = String.format("%s: getParametersBootstrap: %s Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint()); 174 String logMsg = String.format("%s: getParametersBootstrap: %s Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint());
176 - context.sentParametersOnThingsboard(context.getTelemetryMsgObject(logMsg), LwM2MTransportHandler.DEVICE_TELEMETRY_TOPIC, sessionInfo); 175 + context.sentParametersOnThingsboard(context.getTelemetryMsgObject(logMsg), LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC, sessionInfo);
177 return null; 176 return null;
178 } 177 }
179 } 178 }
@@ -20,16 +20,14 @@ import lombok.extern.slf4j.Slf4j; @@ -20,16 +20,14 @@ import lombok.extern.slf4j.Slf4j;
20 import org.eclipse.leshan.core.util.Hex; 20 import org.eclipse.leshan.core.util.Hex;
21 import org.eclipse.leshan.core.util.SecurityUtil; 21 import org.eclipse.leshan.core.util.SecurityUtil;
22 import org.eclipse.leshan.server.security.SecurityInfo; 22 import org.eclipse.leshan.server.security.SecurityInfo;
23 -import org.springframework.beans.factory.annotation.Autowired;  
24 -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;  
25 import org.springframework.stereotype.Component; 23 import org.springframework.stereotype.Component;
26 import org.thingsboard.server.common.data.DeviceProfile; 24 import org.thingsboard.server.common.data.DeviceProfile;
27 import org.thingsboard.server.common.transport.TransportServiceCallback; 25 import org.thingsboard.server.common.transport.TransportServiceCallback;
28 -import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg;  
29 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; 26 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
30 -import org.thingsboard.server.transport.lwm2m.bootstrap.LwM2MTransportContextBootstrap;  
31 -import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportContextServer;  
32 -import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler; 27 +import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg;
  28 +import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
  29 +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer;
  30 +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler;
33 import org.thingsboard.server.transport.lwm2m.utils.TypeServer; 31 import org.thingsboard.server.transport.lwm2m.utils.TypeServer;
34 32
35 import java.io.IOException; 33 import java.io.IOException;
@@ -45,47 +43,46 @@ import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.RP @@ -45,47 +43,46 @@ import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.RP
45 import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.X509; 43 import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.X509;
46 44
47 @Slf4j 45 @Slf4j
48 -@Component("LwM2MGetSecurityInfo")  
49 -@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") 46 +@Component
  47 +@TbLwM2mTransportComponent
50 public class LwM2mCredentialsSecurityInfoValidator { 48 public class LwM2mCredentialsSecurityInfoValidator {
51 49
52 - @Autowired  
53 - public LwM2MTransportContextServer contextS;  
54 -  
55 - @Autowired  
56 - public LwM2MTransportContextBootstrap contextBS; 50 + private final LwM2mTransportContextServer contextS;
57 51
  52 + public LwM2mCredentialsSecurityInfoValidator(LwM2mTransportContextServer contextS) {
  53 + this.contextS = contextS;
  54 + }
58 55
59 /** 56 /**
60 * Request to thingsboard Response from thingsboard ValidateDeviceLwM2MCredentials 57 * Request to thingsboard Response from thingsboard ValidateDeviceLwM2MCredentials
61 - * @param endPoint - 58 + * @param endpoint -
62 * @param keyValue - 59 * @param keyValue -
63 * @return ValidateDeviceCredentialsResponseMsg and SecurityInfo 60 * @return ValidateDeviceCredentialsResponseMsg and SecurityInfo
64 */ 61 */
65 - public ReadResultSecurityStore createAndValidateCredentialsSecurityInfo(String endPoint, TypeServer keyValue) { 62 + public ReadResultSecurityStore createAndValidateCredentialsSecurityInfo(String endpoint, TypeServer keyValue) {
66 CountDownLatch latch = new CountDownLatch(1); 63 CountDownLatch latch = new CountDownLatch(1);
67 final ReadResultSecurityStore[] resultSecurityStore = new ReadResultSecurityStore[1]; 64 final ReadResultSecurityStore[] resultSecurityStore = new ReadResultSecurityStore[1];
68 - contextS.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endPoint).build(),  
69 - new TransportServiceCallback<ValidateDeviceCredentialsResponseMsg>() { 65 + contextS.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endpoint).build(),
  66 + new TransportServiceCallback<>() {
70 @Override 67 @Override
71 public void onSuccess(ValidateDeviceCredentialsResponseMsg msg) { 68 public void onSuccess(ValidateDeviceCredentialsResponseMsg msg) {
72 String credentialsBody = msg.getCredentialsBody(); 69 String credentialsBody = msg.getCredentialsBody();
73 - resultSecurityStore[0] = createSecurityInfo(endPoint, credentialsBody, keyValue); 70 + resultSecurityStore[0] = createSecurityInfo(endpoint, credentialsBody, keyValue);
74 resultSecurityStore[0].setMsg(msg); 71 resultSecurityStore[0].setMsg(msg);
75 - Optional<DeviceProfile> deviceProfileOpt = LwM2MTransportHandler.decode(msg.getProfileBody().toByteArray()); 72 + Optional<DeviceProfile> deviceProfileOpt = LwM2mTransportHandler.decode(msg.getProfileBody().toByteArray());
76 deviceProfileOpt.ifPresent(profile -> resultSecurityStore[0].setDeviceProfile(profile)); 73 deviceProfileOpt.ifPresent(profile -> resultSecurityStore[0].setDeviceProfile(profile));
77 latch.countDown(); 74 latch.countDown();
78 } 75 }
79 76
80 @Override 77 @Override
81 public void onError(Throwable e) { 78 public void onError(Throwable e) {
82 - log.trace("[{}] [{}] Failed to process credentials ", endPoint, e);  
83 - resultSecurityStore[0] = createSecurityInfo(endPoint, null, null); 79 + log.trace("[{}] [{}] Failed to process credentials ", endpoint, e);
  80 + resultSecurityStore[0] = createSecurityInfo(endpoint, null, null);
84 latch.countDown(); 81 latch.countDown();
85 } 82 }
86 }); 83 });
87 try { 84 try {
88 - latch.await(contextS.getCtxServer().getTimeout(), TimeUnit.MILLISECONDS); 85 + latch.await(contextS.getLwM2MTransportConfigServer().getTimeout(), TimeUnit.MILLISECONDS);
89 } catch (InterruptedException e) { 86 } catch (InterruptedException e) {
90 log.error("Failed to await credentials!", e); 87 log.error("Failed to await credentials!", e);
91 } 88 }
@@ -101,7 +98,7 @@ public class LwM2mCredentialsSecurityInfoValidator { @@ -101,7 +98,7 @@ public class LwM2mCredentialsSecurityInfoValidator {
101 */ 98 */
102 private ReadResultSecurityStore createSecurityInfo(String endPoint, String jsonStr, TypeServer keyValue) { 99 private ReadResultSecurityStore createSecurityInfo(String endPoint, String jsonStr, TypeServer keyValue) {
103 ReadResultSecurityStore result = new ReadResultSecurityStore(); 100 ReadResultSecurityStore result = new ReadResultSecurityStore();
104 - JsonObject objectMsg = LwM2MTransportHandler.validateJson(jsonStr); 101 + JsonObject objectMsg = LwM2mTransportHandler.validateJson(jsonStr);
105 if (objectMsg != null && !objectMsg.isJsonNull()) { 102 if (objectMsg != null && !objectMsg.isJsonNull()) {
106 JsonObject object = (objectMsg.has(keyValue.type) && !objectMsg.get(keyValue.type).isJsonNull()) ? objectMsg.get(keyValue.type).getAsJsonObject() : null; 103 JsonObject object = (objectMsg.has(keyValue.type) && !objectMsg.get(keyValue.type).isJsonNull()) ? objectMsg.get(keyValue.type).getAsJsonObject() : null;
107 /** 104 /**
@@ -31,9 +31,9 @@ import java.util.Collection; @@ -31,9 +31,9 @@ import java.util.Collection;
31 public class LwM2mServerListener { 31 public class LwM2mServerListener {
32 32
33 private final LeshanServer lhServer; 33 private final LeshanServer lhServer;
34 - private final LwM2MTransportServiceImpl service; 34 + private final LwM2mTransportServiceImpl service;
35 35
36 - public LwM2mServerListener(LeshanServer lhServer, LwM2MTransportServiceImpl service) { 36 + public LwM2mServerListener(LeshanServer lhServer, LwM2mTransportServiceImpl service) {
37 this.lhServer = lhServer; 37 this.lhServer = lhServer;
38 this.service = service; 38 this.service = service;
39 } 39 }
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mSessionMsgListener.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MSessionMsgListener.java
@@ -32,11 +32,11 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCre @@ -32,11 +32,11 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCre
32 import java.util.Optional; 32 import java.util.Optional;
33 33
34 @Slf4j 34 @Slf4j
35 -public class LwM2MSessionMsgListener implements GenericFutureListener<Future<? super Void>>, SessionMsgListener {  
36 - private LwM2MTransportServiceImpl service; 35 +public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? super Void>>, SessionMsgListener {
  36 + private LwM2mTransportServiceImpl service;
37 private TransportProtos.SessionInfoProto sessionInfo; 37 private TransportProtos.SessionInfoProto sessionInfo;
38 38
39 - public LwM2MSessionMsgListener(LwM2MTransportServiceImpl service, TransportProtos.SessionInfoProto sessionInfo) { 39 + public LwM2mSessionMsgListener(LwM2mTransportServiceImpl service, TransportProtos.SessionInfoProto sessionInfo) {
40 this.service = service; 40 this.service = service;
41 this.sessionInfo = sessionInfo; 41 this.sessionInfo = sessionInfo;
42 } 42 }
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportContextServer.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportContextServer.java
@@ -34,8 +34,6 @@ import com.google.gson.JsonElement; @@ -34,8 +34,6 @@ import com.google.gson.JsonElement;
34 import com.google.gson.JsonObject; 34 import com.google.gson.JsonObject;
35 import lombok.Getter; 35 import lombok.Getter;
36 import lombok.extern.slf4j.Slf4j; 36 import lombok.extern.slf4j.Slf4j;
37 -import org.springframework.beans.factory.annotation.Autowired;  
38 -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;  
39 import org.springframework.stereotype.Component; 37 import org.springframework.stereotype.Component;
40 import org.thingsboard.server.common.transport.TransportContext; 38 import org.thingsboard.server.common.transport.TransportContext;
41 import org.thingsboard.server.common.transport.TransportService; 39 import org.thingsboard.server.common.transport.TransportService;
@@ -43,40 +41,32 @@ import org.thingsboard.server.common.transport.TransportServiceCallback; @@ -43,40 +41,32 @@ import org.thingsboard.server.common.transport.TransportServiceCallback;
43 import org.thingsboard.server.common.transport.adaptor.AdaptorException; 41 import org.thingsboard.server.common.transport.adaptor.AdaptorException;
44 import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer; 42 import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer;
45 import org.thingsboard.server.gen.transport.TransportProtos; 43 import org.thingsboard.server.gen.transport.TransportProtos;
  44 +import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
46 import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor; 45 import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor;
47 -import org.thingsboard.server.transport.lwm2m.server.secure.LwM2mInMemorySecurityStore;  
48 46
49 -import javax.annotation.PostConstruct;  
50 -  
51 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.LOG_LW2M_TELEMETRY; 47 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY;
52 48
53 @Slf4j 49 @Slf4j
54 @Component 50 @Component
55 -@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true') || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")  
56 -public class LwM2MTransportContextServer extends TransportContext { 51 +@TbLwM2mTransportComponent
  52 +public class LwM2mTransportContextServer extends TransportContext {
57 53
58 - private LwM2MTransportConfigServer ctxServer;  
59 54
60 - @Autowired  
61 - protected LwM2MTransportConfigServer lwM2MTransportConfigServer; 55 + private final LwM2MTransportConfigServer lwM2MTransportConfigServer;
62 56
63 - @Autowired  
64 - private TransportService transportService; 57 + private final TransportService transportService;
65 58
66 @Getter 59 @Getter
67 - @Autowired  
68 - private LwM2MJsonAdaptor adaptor;  
69 -  
70 - @Autowired  
71 - LwM2mInMemorySecurityStore lwM2mInMemorySecurityStore; 60 + private final LwM2MJsonAdaptor adaptor;
72 61
73 - @PostConstruct  
74 - public void init() {  
75 - this.ctxServer = lwM2MTransportConfigServer; 62 + public LwM2mTransportContextServer(LwM2MTransportConfigServer lwM2MTransportConfigServer, TransportService transportService, LwM2MJsonAdaptor adaptor) {
  63 + this.lwM2MTransportConfigServer = lwM2MTransportConfigServer;
  64 + this.transportService = transportService;
  65 + this.adaptor = adaptor;
76 } 66 }
77 67
78 - public LwM2MTransportConfigServer getCtxServer() {  
79 - return this.ctxServer; 68 + public LwM2MTransportConfigServer getLwM2MTransportConfigServer() {
  69 + return this.lwM2MTransportConfigServer;
80 } 70 }
81 71
82 /** 72 /**
@@ -86,7 +76,7 @@ public class LwM2MTransportContextServer extends TransportContext { @@ -86,7 +76,7 @@ public class LwM2MTransportContextServer extends TransportContext {
86 * @return - dummy 76 * @return - dummy
87 */ 77 */
88 private <T> TransportServiceCallback<Void> getPubAckCallbackSentAttrTelemetry(final T msg) { 78 private <T> TransportServiceCallback<Void> getPubAckCallbackSentAttrTelemetry(final T msg) {
89 - return new TransportServiceCallback<Void>() { 79 + return new TransportServiceCallback<>() {
90 @Override 80 @Override
91 public void onSuccess(Void dummy) { 81 public void onSuccess(Void dummy) {
92 log.trace("Success to publish msg: {}, dummy: {}", msg, dummy); 82 log.trace("Success to publish msg: {}, dummy: {}", msg, dummy);
@@ -101,11 +91,11 @@ public class LwM2MTransportContextServer extends TransportContext { @@ -101,11 +91,11 @@ public class LwM2MTransportContextServer extends TransportContext {
101 91
102 public void sentParametersOnThingsboard(JsonElement msg, String topicName, TransportProtos.SessionInfoProto sessionInfo) { 92 public void sentParametersOnThingsboard(JsonElement msg, String topicName, TransportProtos.SessionInfoProto sessionInfo) {
103 try { 93 try {
104 - if (topicName.equals(LwM2MTransportHandler.DEVICE_ATTRIBUTES_TOPIC)) { 94 + if (topicName.equals(LwM2mTransportHandler.DEVICE_ATTRIBUTES_TOPIC)) {
105 TransportProtos.PostAttributeMsg postAttributeMsg = adaptor.convertToPostAttributes(msg); 95 TransportProtos.PostAttributeMsg postAttributeMsg = adaptor.convertToPostAttributes(msg);
106 TransportServiceCallback call = this.getPubAckCallbackSentAttrTelemetry(postAttributeMsg); 96 TransportServiceCallback call = this.getPubAckCallbackSentAttrTelemetry(postAttributeMsg);
107 transportService.process(sessionInfo, postAttributeMsg, this.getPubAckCallbackSentAttrTelemetry(call)); 97 transportService.process(sessionInfo, postAttributeMsg, this.getPubAckCallbackSentAttrTelemetry(call));
108 - } else if (topicName.equals(LwM2MTransportHandler.DEVICE_TELEMETRY_TOPIC)) { 98 + } else if (topicName.equals(LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC)) {
109 TransportProtos.PostTelemetryMsg postTelemetryMsg = adaptor.convertToPostTelemetry(msg); 99 TransportProtos.PostTelemetryMsg postTelemetryMsg = adaptor.convertToPostTelemetry(msg);
110 TransportServiceCallback call = this.getPubAckCallbackSentAttrTelemetry(postTelemetryMsg); 100 TransportServiceCallback call = this.getPubAckCallbackSentAttrTelemetry(postTelemetryMsg);
111 transportService.process(sessionInfo, postTelemetryMsg, this.getPubAckCallbackSentAttrTelemetry(call)); 101 transportService.process(sessionInfo, postTelemetryMsg, this.getPubAckCallbackSentAttrTelemetry(call));
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportHandler.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportHandler.java
@@ -36,8 +36,8 @@ import org.nustaq.serialization.FSTConfiguration; @@ -36,8 +36,8 @@ import org.nustaq.serialization.FSTConfiguration;
36 import org.thingsboard.server.common.data.DeviceProfile; 36 import org.thingsboard.server.common.data.DeviceProfile;
37 import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; 37 import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
38 import org.thingsboard.server.common.transport.TransportServiceCallback; 38 import org.thingsboard.server.common.transport.TransportServiceCallback;
39 -import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClientProfile;  
40 -import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClient; 39 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile;
  40 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
41 41
42 import java.io.File; 42 import java.io.File;
43 import java.io.IOException; 43 import java.io.IOException;
@@ -49,7 +49,7 @@ import java.util.Optional; @@ -49,7 +49,7 @@ import java.util.Optional;
49 @Slf4j 49 @Slf4j
50 //@Component("LwM2MTransportHandler") 50 //@Component("LwM2MTransportHandler")
51 //@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' )|| ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") 51 //@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' )|| ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")
52 -public class LwM2MTransportHandler { 52 +public class LwM2mTransportHandler {
53 53
54 // We choose a default timeout a bit higher to the MAX_TRANSMIT_WAIT(62-93s) which is the time from starting to 54 // We choose a default timeout a bit higher to the MAX_TRANSMIT_WAIT(62-93s) which is the time from starting to
55 // send a Confirmable message to the time when an acknowledgement is no longer expected. 55 // send a Confirmable message to the time when an acknowledgement is no longer expected.
@@ -188,8 +188,8 @@ public class LwM2MTransportHandler { @@ -188,8 +188,8 @@ public class LwM2MTransportHandler {
188 return null; 188 return null;
189 } 189 }
190 190
191 - public static LwM2MClientProfile getNewProfileParameters(JsonObject profilesConfigData) {  
192 - LwM2MClientProfile lwM2MClientProfile = new LwM2MClientProfile(); 191 + public static LwM2mClientProfile getNewProfileParameters(JsonObject profilesConfigData) {
  192 + LwM2mClientProfile lwM2MClientProfile = new LwM2mClientProfile();
193 lwM2MClientProfile.setPostClientLwM2mSettings(profilesConfigData.get(CLIENT_LWM2M_SETTINGS).getAsJsonObject()); 193 lwM2MClientProfile.setPostClientLwM2mSettings(profilesConfigData.get(CLIENT_LWM2M_SETTINGS).getAsJsonObject());
194 lwM2MClientProfile.setPostKeyNameProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(KEY_NAME).getAsJsonObject()); 194 lwM2MClientProfile.setPostKeyNameProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(KEY_NAME).getAsJsonObject());
195 lwM2MClientProfile.setPostAttributeProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE).getAsJsonArray()); 195 lwM2MClientProfile.setPostAttributeProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE).getAsJsonArray());
@@ -214,14 +214,14 @@ public class LwM2MTransportHandler { @@ -214,14 +214,14 @@ public class LwM2MTransportHandler {
214 * "telemetry":["/1/0/1","/2/0/1","/6/0/1"], 214 * "telemetry":["/1/0/1","/2/0/1","/6/0/1"],
215 * "observe":["/2/0","/2/0/0","/4/0/2"]} 215 * "observe":["/2/0","/2/0/0","/4/0/2"]}
216 */ 216 */
217 - public static LwM2MClientProfile getLwM2MClientProfileFromThingsboard(DeviceProfile deviceProfile) { 217 + public static LwM2mClientProfile getLwM2MClientProfileFromThingsboard(DeviceProfile deviceProfile) {
218 if (deviceProfile != null && ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties().size() > 0) { 218 if (deviceProfile != null && ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties().size() > 0) {
219 Object profile = ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties(); 219 Object profile = ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties();
220 try { 220 try {
221 ObjectMapper mapper = new ObjectMapper(); 221 ObjectMapper mapper = new ObjectMapper();
222 String profileStr = mapper.writeValueAsString(profile); 222 String profileStr = mapper.writeValueAsString(profile);
223 JsonObject profileJson = (profileStr != null) ? validateJson(profileStr) : null; 223 JsonObject profileJson = (profileStr != null) ? validateJson(profileStr) : null;
224 - return (getValidateCredentialsBodyFromThingsboard(profileJson)) ? LwM2MTransportHandler.getNewProfileParameters(profileJson) : null; 224 + return (getValidateCredentialsBodyFromThingsboard(profileJson)) ? LwM2mTransportHandler.getNewProfileParameters(profileJson) : null;
225 } catch (IOException e) { 225 } catch (IOException e) {
226 log.error("", e); 226 log.error("", e);
227 } 227 }
@@ -244,12 +244,12 @@ public class LwM2MTransportHandler { @@ -244,12 +244,12 @@ public class LwM2MTransportHandler {
244 return null; 244 return null;
245 } 245 }
246 246
247 - public static boolean getClientUpdateValueAfterConnect (LwM2MClientProfile profile) { 247 + public static boolean getClientUpdateValueAfterConnect (LwM2mClientProfile profile) {
248 return profile.getPostClientLwM2mSettings().getAsJsonObject().has("clientUpdateValueAfterConnect") && 248 return profile.getPostClientLwM2mSettings().getAsJsonObject().has("clientUpdateValueAfterConnect") &&
249 profile.getPostClientLwM2mSettings().getAsJsonObject().get("clientUpdateValueAfterConnect").getAsBoolean(); 249 profile.getPostClientLwM2mSettings().getAsJsonObject().get("clientUpdateValueAfterConnect").getAsBoolean();
250 } 250 }
251 251
252 - public static boolean getClientOnlyObserveAfterConnect (LwM2MClientProfile profile) { 252 + public static boolean getClientOnlyObserveAfterConnect (LwM2mClientProfile profile) {
253 return profile.getPostClientLwM2mSettings().getAsJsonObject().has("clientOnlyObserveAfterConnect") && 253 return profile.getPostClientLwM2mSettings().getAsJsonObject().has("clientOnlyObserveAfterConnect") &&
254 profile.getPostClientLwM2mSettings().getAsJsonObject().get("clientOnlyObserveAfterConnect").getAsBoolean(); 254 profile.getPostClientLwM2mSettings().getAsJsonObject().get("clientOnlyObserveAfterConnect").getAsBoolean();
255 } 255 }
@@ -336,11 +336,11 @@ public class LwM2MTransportHandler { @@ -336,11 +336,11 @@ public class LwM2MTransportHandler {
336 return StringUtils.join(linkedListOut, ""); 336 return StringUtils.join(linkedListOut, "");
337 } 337 }
338 338
339 - public static <T> TransportServiceCallback<Void> getAckCallback(LwM2MClient lwM2MClient, int requestId, String typeTopic) { 339 + public static <T> TransportServiceCallback<Void> getAckCallback(LwM2mClient lwM2MClient, int requestId, String typeTopic) {
340 return new TransportServiceCallback<Void>() { 340 return new TransportServiceCallback<Void>() {
341 @Override 341 @Override
342 public void onSuccess(Void dummy) { 342 public void onSuccess(Void dummy) {
343 - log.trace("[{}] [{}] - requestId [{}] - EndPoint , Access AckCallback", typeTopic, requestId, lwM2MClient.getEndPoint()); 343 + log.trace("[{}] [{}] - requestId [{}] - EndPoint , Access AckCallback", typeTopic, requestId, lwM2MClient.getEndpoint());
344 } 344 }
345 345
346 @Override 346 @Override
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportRequest.java
@@ -48,9 +48,10 @@ import org.eclipse.leshan.core.util.NamedThreadFactory; @@ -48,9 +48,10 @@ import org.eclipse.leshan.core.util.NamedThreadFactory;
48 import org.eclipse.leshan.server.californium.LeshanServer; 48 import org.eclipse.leshan.server.californium.LeshanServer;
49 import org.eclipse.leshan.server.registration.Registration; 49 import org.eclipse.leshan.server.registration.Registration;
50 import org.springframework.beans.factory.annotation.Autowired; 50 import org.springframework.beans.factory.annotation.Autowired;
51 -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;  
52 import org.springframework.stereotype.Service; 51 import org.springframework.stereotype.Service;
53 -import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClient; 52 +import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
  53 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
  54 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
54 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; 55 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
55 56
56 import javax.annotation.PostConstruct; 57 import javax.annotation.PostConstruct;
@@ -63,40 +64,41 @@ import java.util.concurrent.Executors; @@ -63,40 +64,41 @@ import java.util.concurrent.Executors;
63 64
64 import static org.eclipse.californium.core.coap.CoAP.ResponseCode.isSuccess; 65 import static org.eclipse.californium.core.coap.CoAP.ResponseCode.isSuccess;
65 import static org.eclipse.leshan.core.attributes.Attribute.MINIMUM_PERIOD; 66 import static org.eclipse.leshan.core.attributes.Attribute.MINIMUM_PERIOD;
66 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.DEFAULT_TIMEOUT;  
67 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.GET_TYPE_OPER_DISCOVER;  
68 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.GET_TYPE_OPER_OBSERVE;  
69 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.GET_TYPE_OPER_READ;  
70 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.LOG_LW2M_ERROR;  
71 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.LOG_LW2M_INFO;  
72 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.POST_TYPE_OPER_EXECUTE;  
73 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.POST_TYPE_OPER_OBSERVE_CANCEL;  
74 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.POST_TYPE_OPER_WRITE_REPLACE;  
75 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.PUT_TYPE_OPER_WRITE_ATTRIBUTES;  
76 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.PUT_TYPE_OPER_WRITE_UPDATE;  
77 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.RESPONSE_CHANNEL; 67 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEFAULT_TIMEOUT;
  68 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_DISCOVER;
  69 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_OBSERVE;
  70 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_READ;
  71 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR;
  72 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO;
  73 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_EXECUTE;
  74 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_OBSERVE_CANCEL;
  75 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_WRITE_REPLACE;
  76 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_ATTRIBUTES;
  77 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_UPDATE;
  78 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.RESPONSE_CHANNEL;
78 79
79 @Slf4j 80 @Slf4j
80 -@Service("LwM2MTransportRequest")  
81 -@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")  
82 -public class LwM2MTransportRequest { 81 +@Service("LwM2mTransportRequest")
  82 +@TbLwM2mTransportComponent
  83 +public class LwM2mTransportRequest {
83 private ExecutorService executorResponse; 84 private ExecutorService executorResponse;
84 - private ExecutorService executorResponseError; 85 +
85 private LwM2mValueConverterImpl converter; 86 private LwM2mValueConverterImpl converter;
86 87
87 @Autowired 88 @Autowired
88 - LwM2MTransportServiceImpl service; 89 + private LwM2mTransportServiceImpl service;
  90 +
  91 + @Autowired
  92 + private LwM2mTransportContextServer context;
89 93
90 @Autowired 94 @Autowired
91 - public LwM2MTransportContextServer context; 95 + private LwM2mClientContext lwM2mClientContext;
92 96
93 @PostConstruct 97 @PostConstruct
94 public void init() { 98 public void init() {
95 this.converter = LwM2mValueConverterImpl.getInstance(); 99 this.converter = LwM2mValueConverterImpl.getInstance();
96 - executorResponse = Executors.newFixedThreadPool(this.context.getCtxServer().getRequestPoolSize(), 100 + executorResponse = Executors.newFixedThreadPool(this.context.getLwM2MTransportConfigServer().getRequestPoolSize(),
97 new NamedThreadFactory(String.format("LwM2M %s channel response", RESPONSE_CHANNEL))); 101 new NamedThreadFactory(String.format("LwM2M %s channel response", RESPONSE_CHANNEL)));
98 - executorResponseError = Executors.newFixedThreadPool(this.context.getCtxServer().getRequestErrorPoolSize(),  
99 - new NamedThreadFactory(String.format("LwM2M %s channel response Error", RESPONSE_CHANNEL)));  
100 } 102 }
101 103
102 public Collection<Registration> doGetRegistrations(LeshanServer lwServer) { 104 public Collection<Registration> doGetRegistrations(LeshanServer lwServer) {
@@ -124,7 +126,7 @@ public class LwM2MTransportRequest { @@ -124,7 +126,7 @@ public class LwM2MTransportRequest {
124 if (registration != null && resultIds.getObjectId() >= 0) { 126 if (registration != null && resultIds.getObjectId() >= 0) {
125 DownlinkRequest request = null; 127 DownlinkRequest request = null;
126 ContentFormat contentFormat = contentFormatParam != null ? ContentFormat.fromName(contentFormatParam.toUpperCase()) : null; 128 ContentFormat contentFormat = contentFormatParam != null ? ContentFormat.fromName(contentFormatParam.toUpperCase()) : null;
127 - ResourceModel resource = service.context.getCtxServer().getResourceModel(registration, resultIds); 129 + ResourceModel resource = service.context.getLwM2MTransportConfigServer().getResourceModel(registration, resultIds);
128 timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT; 130 timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT;
129 switch (typeOper) { 131 switch (typeOper) {
130 case GET_TYPE_OPER_READ: 132 case GET_TYPE_OPER_READ:
@@ -234,7 +236,7 @@ public class LwM2MTransportRequest { @@ -234,7 +236,7 @@ public class LwM2MTransportRequest {
234 236
235 @SuppressWarnings("unchecked") 237 @SuppressWarnings("unchecked")
236 private void sendRequest(LeshanServer lwServer, Registration registration, DownlinkRequest request, long timeoutInMs) { 238 private void sendRequest(LeshanServer lwServer, Registration registration, DownlinkRequest request, long timeoutInMs) {
237 - LwM2MClient lwM2MClient = this.service.lwM2mInMemorySecurityStore.getLwM2MClientWithReg(registration, null); 239 + LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);
238 lwServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { 240 lwServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> {
239 if (!lwM2MClient.isInit()) { 241 if (!lwM2MClient.isInit()) {
240 lwM2MClient.initValue(this.service, request.getPath().toString()); 242 lwM2MClient.initValue(this.service, request.getPath().toString());
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerConfiguration.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerConfiguration.java
@@ -22,15 +22,16 @@ import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeEncoder; @@ -22,15 +22,16 @@ import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeEncoder;
22 import org.eclipse.leshan.core.util.Hex; 22 import org.eclipse.leshan.core.util.Hex;
23 import org.eclipse.leshan.server.californium.LeshanServer; 23 import org.eclipse.leshan.server.californium.LeshanServer;
24 import org.eclipse.leshan.server.californium.LeshanServerBuilder; 24 import org.eclipse.leshan.server.californium.LeshanServerBuilder;
  25 +import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore;
25 import org.eclipse.leshan.server.model.LwM2mModelProvider; 26 import org.eclipse.leshan.server.model.LwM2mModelProvider;
26 import org.eclipse.leshan.server.model.VersionedModelProvider; 27 import org.eclipse.leshan.server.model.VersionedModelProvider;
27 import org.eclipse.leshan.server.security.DefaultAuthorizer; 28 import org.eclipse.leshan.server.security.DefaultAuthorizer;
  29 +import org.eclipse.leshan.server.security.EditableSecurityStore;
28 import org.eclipse.leshan.server.security.SecurityChecker; 30 import org.eclipse.leshan.server.security.SecurityChecker;
29 import org.springframework.beans.factory.annotation.Autowired; 31 import org.springframework.beans.factory.annotation.Autowired;
30 -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;  
31 import org.springframework.context.annotation.Bean; 32 import org.springframework.context.annotation.Bean;
32 import org.springframework.stereotype.Component; 33 import org.springframework.stereotype.Component;
33 -import org.thingsboard.server.transport.lwm2m.server.secure.LwM2mInMemorySecurityStore; 34 +import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
34 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; 35 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
35 36
36 import java.math.BigInteger; 37 import java.math.BigInteger;
@@ -57,32 +58,35 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE @@ -57,32 +58,35 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE
57 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8; 58 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
58 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; 59 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256;
59 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8; 60 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8;
60 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.getCoapConfig; 61 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getCoapConfig;
61 62
62 @Slf4j 63 @Slf4j
63 @Component("LwM2MTransportServerConfiguration") 64 @Component("LwM2MTransportServerConfiguration")
64 -@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")  
65 -public class LwM2MTransportServerConfiguration { 65 +@TbLwM2mTransportComponent
  66 +public class LwM2mTransportServerConfiguration {
66 private PublicKey publicKey; 67 private PublicKey publicKey;
67 private PrivateKey privateKey; 68 private PrivateKey privateKey;
68 private boolean pskMode = false; 69 private boolean pskMode = false;
69 70
70 @Autowired 71 @Autowired
71 - private LwM2MTransportContextServer context; 72 + private LwM2mTransportContextServer context;
72 73
73 @Autowired 74 @Autowired
74 - private LwM2mInMemorySecurityStore lwM2mInMemorySecurityStore; 75 + private CaliforniumRegistrationStore registrationStore;
  76 +
  77 + @Autowired
  78 + private EditableSecurityStore securityStore;
75 79
76 @Bean 80 @Bean
77 public LeshanServer getLeshanServer() { 81 public LeshanServer getLeshanServer() {
78 log.info("Starting LwM2M transport Server... PostConstruct"); 82 log.info("Starting LwM2M transport Server... PostConstruct");
79 - return this.getLhServer(this.context.getCtxServer().getServerPortNoSec(), this.context.getCtxServer().getServerPortSecurity()); 83 + return this.getLhServer(this.context.getLwM2MTransportConfigServer().getServerPortNoSec(), this.context.getLwM2MTransportConfigServer().getServerPortSecurity());
80 } 84 }
81 85
82 private LeshanServer getLhServer(Integer serverPortNoSec, Integer serverSecurePort) { 86 private LeshanServer getLhServer(Integer serverPortNoSec, Integer serverSecurePort) {
83 LeshanServerBuilder builder = new LeshanServerBuilder(); 87 LeshanServerBuilder builder = new LeshanServerBuilder();
84 - builder.setLocalAddress(this.context.getCtxServer().getServerHost(), serverPortNoSec);  
85 - builder.setLocalSecureAddress(this.context.getCtxServer().getServerHostSecurity(), serverSecurePort); 88 + builder.setLocalAddress(this.context.getLwM2MTransportConfigServer().getServerHost(), serverPortNoSec);
  89 + builder.setLocalSecureAddress(this.context.getLwM2MTransportConfigServer().getServerHostSecurity(), serverSecurePort);
86 builder.setDecoder(new DefaultLwM2mNodeDecoder()); 90 builder.setDecoder(new DefaultLwM2mNodeDecoder());
87 /** Use a magic converter to support bad type send by the UI. */ 91 /** Use a magic converter to support bad type send by the UI. */
88 builder.setEncoder(new DefaultLwM2mNodeEncoder(LwM2mValueConverterImpl.getInstance())); 92 builder.setEncoder(new DefaultLwM2mNodeEncoder(LwM2mValueConverterImpl.getInstance()));
@@ -91,26 +95,26 @@ public class LwM2MTransportServerConfiguration { @@ -91,26 +95,26 @@ public class LwM2MTransportServerConfiguration {
91 builder.setCoapConfig(getCoapConfig(serverPortNoSec, serverSecurePort)); 95 builder.setCoapConfig(getCoapConfig(serverPortNoSec, serverSecurePort));
92 96
93 /** Define model provider (Create Models )*/ 97 /** Define model provider (Create Models )*/
94 - LwM2mModelProvider modelProvider = new VersionedModelProvider(this.context.getCtxServer().getModelsValue()); 98 + LwM2mModelProvider modelProvider = new VersionedModelProvider(this.context.getLwM2MTransportConfigServer().getModelsValue());
95 builder.setObjectModelProvider(modelProvider); 99 builder.setObjectModelProvider(modelProvider);
96 100
97 /** Create credentials */ 101 /** Create credentials */
98 this.setServerWithCredentials(builder); 102 this.setServerWithCredentials(builder);
99 103
100 /** Set securityStore with new registrationStore */ 104 /** Set securityStore with new registrationStore */
101 - builder.setSecurityStore(lwM2mInMemorySecurityStore); 105 + builder.setSecurityStore(securityStore);
  106 + builder.setRegistrationStore(registrationStore);
102 107
103 108
104 /** Create DTLS Config */ 109 /** Create DTLS Config */
105 DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder(); 110 DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder();
106 - dtlsConfig.setRecommendedSupportedGroupsOnly(this.context.getCtxServer().isRecommendedSupportedGroups());  
107 - dtlsConfig.setRecommendedCipherSuitesOnly(this.context.getCtxServer().isRecommendedCiphers()); 111 + dtlsConfig.setRecommendedSupportedGroupsOnly(this.context.getLwM2MTransportConfigServer().isRecommendedSupportedGroups());
  112 + dtlsConfig.setRecommendedCipherSuitesOnly(this.context.getLwM2MTransportConfigServer().isRecommendedCiphers());
108 if (this.pskMode) { 113 if (this.pskMode) {
109 dtlsConfig.setSupportedCipherSuites( 114 dtlsConfig.setSupportedCipherSuites(
110 TLS_PSK_WITH_AES_128_CCM_8, 115 TLS_PSK_WITH_AES_128_CCM_8,
111 TLS_PSK_WITH_AES_128_CBC_SHA256); 116 TLS_PSK_WITH_AES_128_CBC_SHA256);
112 - }  
113 - else { 117 + } else {
114 dtlsConfig.setSupportedCipherSuites( 118 dtlsConfig.setSupportedCipherSuites(
115 TLS_PSK_WITH_AES_128_CCM_8, 119 TLS_PSK_WITH_AES_128_CCM_8,
116 TLS_PSK_WITH_AES_128_CBC_SHA256, 120 TLS_PSK_WITH_AES_128_CBC_SHA256,
@@ -118,7 +122,6 @@ public class LwM2MTransportServerConfiguration { @@ -118,7 +122,6 @@ public class LwM2MTransportServerConfiguration {
118 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256); 122 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256);
119 } 123 }
120 124
121 -  
122 /** Set DTLS Config */ 125 /** Set DTLS Config */
123 builder.setDtlsConfig(dtlsConfig); 126 builder.setDtlsConfig(dtlsConfig);
124 127
@@ -128,9 +131,9 @@ public class LwM2MTransportServerConfiguration { @@ -128,9 +131,9 @@ public class LwM2MTransportServerConfiguration {
128 131
129 private void setServerWithCredentials(LeshanServerBuilder builder) { 132 private void setServerWithCredentials(LeshanServerBuilder builder) {
130 try { 133 try {
131 - if (this.context.getCtxServer().getKeyStoreValue() != null) { 134 + if (this.context.getLwM2MTransportConfigServer().getKeyStoreValue() != null) {
132 if (this.setBuilderX509(builder)) { 135 if (this.setBuilderX509(builder)) {
133 - X509Certificate rootCAX509Cert = (X509Certificate) this.context.getCtxServer().getKeyStoreValue().getCertificate(this.context.getCtxServer().getRootAlias()); 136 + X509Certificate rootCAX509Cert = (X509Certificate) this.context.getLwM2MTransportConfigServer().getKeyStoreValue().getCertificate(this.context.getLwM2MTransportConfigServer().getRootAlias());
134 if (rootCAX509Cert != null) { 137 if (rootCAX509Cert != null) {
135 X509Certificate[] trustedCertificates = new X509Certificate[1]; 138 X509Certificate[] trustedCertificates = new X509Certificate[1];
136 trustedCertificates[0] = rootCAX509Cert; 139 trustedCertificates[0] = rootCAX509Cert;
@@ -140,7 +143,7 @@ public class LwM2MTransportServerConfiguration { @@ -140,7 +143,7 @@ public class LwM2MTransportServerConfiguration {
140 builder.setTrustedCertificates(new X509Certificate[0]); 143 builder.setTrustedCertificates(new X509Certificate[0]);
141 } 144 }
142 /** Set securityStore with registrationStore*/ 145 /** Set securityStore with registrationStore*/
143 - builder.setAuthorizer(new DefaultAuthorizer(lwM2mInMemorySecurityStore, new SecurityChecker() { 146 + builder.setAuthorizer(new DefaultAuthorizer(securityStore, new SecurityChecker() {
144 @Override 147 @Override
145 protected boolean matchX509Identity(String endpoint, String receivedX509CommonName, 148 protected boolean matchX509Identity(String endpoint, String receivedX509CommonName,
146 String expectedX509CommonName) { 149 String expectedX509CommonName) {
@@ -169,8 +172,8 @@ public class LwM2MTransportServerConfiguration { @@ -169,8 +172,8 @@ public class LwM2MTransportServerConfiguration {
169 * For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks 172 * For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks
170 */ 173 */
171 try { 174 try {
172 - X509Certificate serverCertificate = (X509Certificate) this.context.getCtxServer().getKeyStoreValue().getCertificate(this.context.getCtxServer().getServerAlias());  
173 - PrivateKey privateKey = (PrivateKey) this.context.getCtxServer().getKeyStoreValue().getKey(this.context.getCtxServer().getServerAlias(), this.context.getCtxServer().getKeyStorePasswordServer() == null ? null : this.context.getCtxServer().getKeyStorePasswordServer().toCharArray()); 175 + X509Certificate serverCertificate = (X509Certificate) this.context.getLwM2MTransportConfigServer().getKeyStoreValue().getCertificate(this.context.getLwM2MTransportConfigServer().getServerAlias());
  176 + PrivateKey privateKey = (PrivateKey) this.context.getLwM2MTransportConfigServer().getKeyStoreValue().getKey(this.context.getLwM2MTransportConfigServer().getServerAlias(), this.context.getLwM2MTransportConfigServer().getKeyStorePasswordServer() == null ? null : this.context.getLwM2MTransportConfigServer().getKeyStorePasswordServer().toCharArray());
174 PublicKey publicKey = serverCertificate.getPublicKey(); 177 PublicKey publicKey = serverCertificate.getPublicKey();
175 if (serverCertificate != null && 178 if (serverCertificate != null &&
176 privateKey != null && privateKey.getEncoded().length > 0 && 179 privateKey != null && privateKey.getEncoded().length > 0 &&
@@ -203,8 +206,8 @@ public class LwM2MTransportServerConfiguration { @@ -203,8 +206,8 @@ public class LwM2MTransportServerConfiguration {
203 private void infoPramsUri(String mode) { 206 private void infoPramsUri(String mode) {
204 log.info("Server uses [{}]: serverNoSecureURI : [{}], serverSecureURI : [{}]", 207 log.info("Server uses [{}]: serverNoSecureURI : [{}], serverSecureURI : [{}]",
205 mode, 208 mode,
206 - this.context.getCtxServer().getServerHost() + ":" + this.context.getCtxServer().getServerPortNoSec(),  
207 - this.context.getCtxServer().getServerHostSecurity() + ":" + this.context.getCtxServer().getServerPortSecurity()); 209 + this.context.getLwM2MTransportConfigServer().getServerHost() + ":" + this.context.getLwM2MTransportConfigServer().getServerPortNoSec(),
  210 + this.context.getLwM2MTransportConfigServer().getServerHostSecurity() + ":" + this.context.getLwM2MTransportConfigServer().getServerPortSecurity());
208 } 211 }
209 212
210 private boolean setServerRPK(LeshanServerBuilder builder) { 213 private boolean setServerRPK(LeshanServerBuilder builder) {
@@ -234,27 +237,27 @@ public class LwM2MTransportServerConfiguration { @@ -234,27 +237,27 @@ public class LwM2MTransportServerConfiguration {
234 AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC"); 237 AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
235 algoParameters.init(new ECGenParameterSpec("secp256r1")); 238 algoParameters.init(new ECGenParameterSpec("secp256r1"));
236 ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class); 239 ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
237 - if (this.context.getCtxServer().getServerPublicX() != null &&  
238 - !this.context.getCtxServer().getServerPublicX().isEmpty() &&  
239 - this.context.getCtxServer().getServerPublicY() != null &&  
240 - !this.context.getCtxServer().getServerPublicY().isEmpty()) { 240 + if (this.context.getLwM2MTransportConfigServer().getServerPublicX() != null &&
  241 + !this.context.getLwM2MTransportConfigServer().getServerPublicX().isEmpty() &&
  242 + this.context.getLwM2MTransportConfigServer().getServerPublicY() != null &&
  243 + !this.context.getLwM2MTransportConfigServer().getServerPublicY().isEmpty()) {
241 /** Get point values */ 244 /** Get point values */
242 - byte[] publicX = Hex.decodeHex(this.context.getCtxServer().getServerPublicX().toCharArray());  
243 - byte[] publicY = Hex.decodeHex(this.context.getCtxServer().getServerPublicY().toCharArray()); 245 + byte[] publicX = Hex.decodeHex(this.context.getLwM2MTransportConfigServer().getServerPublicX().toCharArray());
  246 + byte[] publicY = Hex.decodeHex(this.context.getLwM2MTransportConfigServer().getServerPublicY().toCharArray());
244 /** Create key specs */ 247 /** Create key specs */
245 KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)), 248 KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)),
246 parameterSpec); 249 parameterSpec);
247 /** Get keys */ 250 /** Get keys */
248 this.publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec); 251 this.publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec);
249 } 252 }
250 - if (this.context.getCtxServer().getServerPrivateEncoded() != null &&  
251 - !this.context.getCtxServer().getServerPrivateEncoded().isEmpty()) { 253 + if (this.context.getLwM2MTransportConfigServer().getServerPrivateEncoded() != null &&
  254 + !this.context.getLwM2MTransportConfigServer().getServerPrivateEncoded().isEmpty()) {
252 /** Get private key */ 255 /** Get private key */
253 - byte[] privateS = Hex.decodeHex(this.context.getCtxServer().getServerPrivateEncoded().toCharArray()); 256 + byte[] privateS = Hex.decodeHex(this.context.getLwM2MTransportConfigServer().getServerPrivateEncoded().toCharArray());
254 try { 257 try {
255 this.privateKey = KeyFactory.getInstance("EC").generatePrivate(new PKCS8EncodedKeySpec(privateS)); 258 this.privateKey = KeyFactory.getInstance("EC").generatePrivate(new PKCS8EncodedKeySpec(privateS));
256 } catch (InvalidKeySpecException ignore2) { 259 } catch (InvalidKeySpecException ignore2) {
257 - log.error("Invalid Server rpk.PrivateKey.getEncoded () [{}}]. PrivateKey has no EC algorithm", this.context.getCtxServer().getServerPrivateEncoded()); 260 + log.error("Invalid Server rpk.PrivateKey.getEncoded () [{}}]. PrivateKey has no EC algorithm", this.context.getLwM2MTransportConfigServer().getServerPrivateEncoded());
258 } 261 }
259 } 262 }
260 } 263 }
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerInitializer.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerInitializer.java
@@ -18,8 +18,8 @@ package org.thingsboard.server.transport.lwm2m.server; @@ -18,8 +18,8 @@ package org.thingsboard.server.transport.lwm2m.server;
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.eclipse.leshan.server.californium.LeshanServer; 19 import org.eclipse.leshan.server.californium.LeshanServer;
20 import org.springframework.beans.factory.annotation.Autowired; 20 import org.springframework.beans.factory.annotation.Autowired;
21 -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;  
22 import org.springframework.stereotype.Component; 21 import org.springframework.stereotype.Component;
  22 +import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
23 import org.thingsboard.server.transport.lwm2m.secure.LWM2MGenerationPSkRPkECC; 23 import org.thingsboard.server.transport.lwm2m.secure.LWM2MGenerationPSkRPkECC;
24 24
25 import javax.annotation.PostConstruct; 25 import javax.annotation.PostConstruct;
@@ -27,21 +27,21 @@ import javax.annotation.PreDestroy; @@ -27,21 +27,21 @@ import javax.annotation.PreDestroy;
27 27
28 @Slf4j 28 @Slf4j
29 @Component("LwM2MTransportServerInitializer") 29 @Component("LwM2MTransportServerInitializer")
30 -@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")  
31 -public class LwM2MTransportServerInitializer { 30 +@TbLwM2mTransportComponent
  31 +public class LwM2mTransportServerInitializer {
32 32
33 @Autowired 33 @Autowired
34 - private LwM2MTransportServiceImpl service; 34 + private LwM2mTransportServiceImpl service;
35 35
36 @Autowired(required = false) 36 @Autowired(required = false)
37 private LeshanServer leshanServer; 37 private LeshanServer leshanServer;
38 38
39 @Autowired 39 @Autowired
40 - private LwM2MTransportContextServer context; 40 + private LwM2mTransportContextServer context;
41 41
42 @PostConstruct 42 @PostConstruct
43 public void init() { 43 public void init() {
44 - if (this.context.getCtxServer().getEnableGenNewKeyPskRpk()) { 44 + if (this.context.getLwM2MTransportConfigServer().getEnableGenNewKeyPskRpk()) {
45 new LWM2MGenerationPSkRPkECC(); 45 new LWM2MGenerationPSkRPkECC();
46 } 46 }
47 this.startLhServer(); 47 this.startLhServer();
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportService.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportService.java
@@ -26,7 +26,7 @@ import org.thingsboard.server.gen.transport.TransportProtos; @@ -26,7 +26,7 @@ import org.thingsboard.server.gen.transport.TransportProtos;
26 import java.util.Collection; 26 import java.util.Collection;
27 import java.util.Optional; 27 import java.util.Optional;
28 28
29 -public interface LwM2MTransportService { 29 +public interface LwM2mTransportService {
30 30
31 void onRegistered(LeshanServer lwServer, Registration registration, Collection<Observation> previousObsersations); 31 void onRegistered(LeshanServer lwServer, Registration registration, Collection<Observation> previousObsersations);
32 32
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServiceImpl.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServiceImpl.java
@@ -36,7 +36,6 @@ import org.eclipse.leshan.core.util.NamedThreadFactory; @@ -36,7 +36,6 @@ import org.eclipse.leshan.core.util.NamedThreadFactory;
36 import org.eclipse.leshan.server.californium.LeshanServer; 36 import org.eclipse.leshan.server.californium.LeshanServer;
37 import org.eclipse.leshan.server.registration.Registration; 37 import org.eclipse.leshan.server.registration.Registration;
38 import org.springframework.beans.factory.annotation.Autowired; 38 import org.springframework.beans.factory.annotation.Autowired;
39 -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;  
40 import org.springframework.stereotype.Service; 39 import org.springframework.stereotype.Service;
41 import org.thingsboard.server.common.data.Device; 40 import org.thingsboard.server.common.data.Device;
42 import org.thingsboard.server.common.data.DeviceProfile; 41 import org.thingsboard.server.common.data.DeviceProfile;
@@ -48,11 +47,12 @@ import org.thingsboard.server.gen.transport.TransportProtos; @@ -48,11 +47,12 @@ import org.thingsboard.server.gen.transport.TransportProtos;
48 import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; 47 import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg;
49 import org.thingsboard.server.gen.transport.TransportProtos.SessionEvent; 48 import org.thingsboard.server.gen.transport.TransportProtos.SessionEvent;
50 import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; 49 import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
51 -import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClient;  
52 -import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClientProfile; 50 +import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
  51 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
  52 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
  53 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile;
53 import org.thingsboard.server.transport.lwm2m.server.client.ResourceValue; 54 import org.thingsboard.server.transport.lwm2m.server.client.ResourceValue;
54 import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters; 55 import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters;
55 -import org.thingsboard.server.transport.lwm2m.server.secure.LwM2mInMemorySecurityStore;  
56 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; 56 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
57 57
58 import javax.annotation.PostConstruct; 58 import javax.annotation.PostConstruct;
@@ -79,24 +79,24 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -79,24 +79,24 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
79 import java.util.stream.Collectors; 79 import java.util.stream.Collectors;
80 80
81 import static org.thingsboard.server.common.transport.util.JsonUtils.getJsonObject; 81 import static org.thingsboard.server.common.transport.util.JsonUtils.getJsonObject;
82 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.CLIENT_NOT_AUTHORIZED;  
83 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.DEVICE_ATTRIBUTES_REQUEST;  
84 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.DEVICE_ATTRIBUTES_TOPIC;  
85 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.DEVICE_TELEMETRY_TOPIC;  
86 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.GET_TYPE_OPER_OBSERVE;  
87 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.GET_TYPE_OPER_READ;  
88 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.LOG_LW2M_ERROR;  
89 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.LOG_LW2M_INFO;  
90 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.LOG_LW2M_TELEMETRY;  
91 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.POST_TYPE_OPER_EXECUTE;  
92 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.POST_TYPE_OPER_WRITE_REPLACE;  
93 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.SERVICE_CHANNEL;  
94 -import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.getAckCallback; 82 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.CLIENT_NOT_AUTHORIZED;
  83 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_ATTRIBUTES_REQUEST;
  84 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_ATTRIBUTES_TOPIC;
  85 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC;
  86 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_OBSERVE;
  87 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_READ;
  88 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR;
  89 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO;
  90 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY;
  91 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_EXECUTE;
  92 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_WRITE_REPLACE;
  93 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.SERVICE_CHANNEL;
  94 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getAckCallback;
95 95
96 @Slf4j 96 @Slf4j
97 -@Service("LwM2MTransportService")  
98 -@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")  
99 -public class LwM2MTransportServiceImpl implements LwM2MTransportService { 97 +@Service
  98 +@TbLwM2mTransportComponent
  99 +public class LwM2mTransportServiceImpl implements LwM2mTransportService {
100 100
101 private ExecutorService executorRegistered; 101 private ExecutorService executorRegistered;
102 private ExecutorService executorUpdateRegistered; 102 private ExecutorService executorUpdateRegistered;
@@ -105,27 +105,29 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -105,27 +105,29 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
105 protected final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); 105 protected final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
106 protected final Lock writeLock = readWriteLock.writeLock(); 106 protected final Lock writeLock = readWriteLock.writeLock();
107 107
108 -  
109 @Autowired 108 @Autowired
110 private TransportService transportService; 109 private TransportService transportService;
111 110
112 @Autowired 111 @Autowired
113 - public LwM2MTransportContextServer context; 112 + public LwM2mTransportContextServer context;
114 113
115 @Autowired 114 @Autowired
116 - private LwM2MTransportRequest lwM2MTransportRequest; 115 + private LwM2mTransportRequest lwM2mTransportRequest;
117 116
118 @Autowired 117 @Autowired
119 - LwM2mInMemorySecurityStore lwM2mInMemorySecurityStore; 118 + private LwM2mClientContext lwM2mClientContext;
  119 +
  120 + @Autowired(required = false)
  121 + private LeshanServer leshanServer;
120 122
121 @PostConstruct 123 @PostConstruct
122 public void init() { 124 public void init() {
123 - this.context.getScheduler().scheduleAtFixedRate(this::checkInactivityAndReportActivity, new Random().nextInt((int) context.getCtxServer().getSessionReportTimeout()), context.getCtxServer().getSessionReportTimeout(), TimeUnit.MILLISECONDS);  
124 - this.executorRegistered = Executors.newFixedThreadPool(this.context.getCtxServer().getRegisteredPoolSize(), 125 + this.context.getScheduler().scheduleAtFixedRate(this::checkInactivityAndReportActivity, new Random().nextInt((int) context.getLwM2MTransportConfigServer().getSessionReportTimeout()), context.getLwM2MTransportConfigServer().getSessionReportTimeout(), TimeUnit.MILLISECONDS);
  126 + this.executorRegistered = Executors.newFixedThreadPool(this.context.getLwM2MTransportConfigServer().getRegisteredPoolSize(),
125 new NamedThreadFactory(String.format("LwM2M %s channel registered", SERVICE_CHANNEL))); 127 new NamedThreadFactory(String.format("LwM2M %s channel registered", SERVICE_CHANNEL)));
126 - this.executorUpdateRegistered = Executors.newFixedThreadPool(this.context.getCtxServer().getUpdateRegisteredPoolSize(), 128 + this.executorUpdateRegistered = Executors.newFixedThreadPool(this.context.getLwM2MTransportConfigServer().getUpdateRegisteredPoolSize(),
127 new NamedThreadFactory(String.format("LwM2M %s channel update registered", SERVICE_CHANNEL))); 129 new NamedThreadFactory(String.format("LwM2M %s channel update registered", SERVICE_CHANNEL)));
128 - this.executorUnRegistered = Executors.newFixedThreadPool(this.context.getCtxServer().getUnRegisteredPoolSize(), 130 + this.executorUnRegistered = Executors.newFixedThreadPool(this.context.getLwM2MTransportConfigServer().getUnRegisteredPoolSize(),
129 new NamedThreadFactory(String.format("LwM2M %s channel un registered", SERVICE_CHANNEL))); 131 new NamedThreadFactory(String.format("LwM2M %s channel un registered", SERVICE_CHANNEL)));
130 this.converter = LwM2mValueConverterImpl.getInstance(); 132 this.converter = LwM2mValueConverterImpl.getInstance();
131 } 133 }
@@ -149,17 +151,16 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -149,17 +151,16 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
149 executorRegistered.submit(() -> { 151 executorRegistered.submit(() -> {
150 try { 152 try {
151 log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); 153 log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId());
152 - LwM2MClient lwM2MClient = this.lwM2mInMemorySecurityStore.updateInSessionsLwM2MClient(lwServer, registration); 154 + LwM2mClient lwM2MClient = this.lwM2mClientContext.updateInSessionsLwM2MClient(registration);
153 if (lwM2MClient != null) { 155 if (lwM2MClient != null) {
154 - lwM2MClient.setLwM2MTransportServiceImpl(this);  
155 this.sentLogsToThingsboard(LOG_LW2M_INFO + ": Client Registered", registration); 156 this.sentLogsToThingsboard(LOG_LW2M_INFO + ": Client Registered", registration);
156 SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration); 157 SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration);
157 if (sessionInfo != null) { 158 if (sessionInfo != null) {
158 - lwM2MClient.setDeviceUuid(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB()));  
159 - lwM2MClient.setProfileUuid(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); 159 + lwM2MClient.setDeviceId(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB()));
  160 + lwM2MClient.setProfileId(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));
160 lwM2MClient.setDeviceName(sessionInfo.getDeviceName()); 161 lwM2MClient.setDeviceName(sessionInfo.getDeviceName());
161 lwM2MClient.setDeviceProfileName(sessionInfo.getDeviceType()); 162 lwM2MClient.setDeviceProfileName(sessionInfo.getDeviceType());
162 - transportService.registerAsyncSession(sessionInfo, new LwM2MSessionMsgListener(this, sessionInfo)); 163 + transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo));
163 transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN), null); 164 transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN), null);
164 transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), null); 165 transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), null);
165 this.sentLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration); 166 this.sentLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration);
@@ -221,8 +222,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -221,8 +222,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
221 if (sessionInfo != null) { 222 if (sessionInfo != null) {
222 transportService.deregisterSession(sessionInfo); 223 transportService.deregisterSession(sessionInfo);
223 this.doCloseSession(sessionInfo); 224 this.doCloseSession(sessionInfo);
224 - lwM2mInMemorySecurityStore.delRemoveSessionAndListener(registration.getId());  
225 - if (lwM2mInMemorySecurityStore.getProfiles().size() > 0) { 225 + lwM2mClientContext.delRemoveSessionAndListener(registration.getId());
  226 + if (lwM2mClientContext.getProfiles().size() > 0) {
226 this.syncSessionsAndProfiles(); 227 this.syncSessionsAndProfiles();
227 } 228 }
228 log.info("Client close session: [{}] unReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType()); 229 log.info("Client close session: [{}] unReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType());
@@ -292,13 +293,13 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -292,13 +293,13 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
292 el.getAsJsonObject().entrySet().forEach(de -> { 293 el.getAsJsonObject().entrySet().forEach(de -> {
293 String path = this.getPathAttributeUpdate(sessionInfo, de.getKey()); 294 String path = this.getPathAttributeUpdate(sessionInfo, de.getKey());
294 String value = de.getValue().getAsString(); 295 String value = de.getValue().getAsString();
295 - LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getSession(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).entrySet().iterator().next().getValue();  
296 - LwM2MClientProfile profile = lwM2mInMemorySecurityStore.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));  
297 - ResourceModel resourceModel = context.getCtxServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(path)); 296 + LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
  297 + LwM2mClientProfile profile = lwM2mClientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));
  298 + ResourceModel resourceModel = context.getLwM2MTransportConfigServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(path));
298 if (!path.isEmpty() && (this.validatePathInAttrProfile(profile, path) || this.validatePathInTelemetryProfile(profile, path))) { 299 if (!path.isEmpty() && (this.validatePathInAttrProfile(profile, path) || this.validatePathInTelemetryProfile(profile, path))) {
299 if (resourceModel != null && resourceModel.operations.isWritable()) { 300 if (resourceModel != null && resourceModel.operations.isWritable()) {
300 - lwM2MTransportRequest.sendAllRequest(lwM2MClient.getLwServer(), lwM2MClient.getRegistration(), path, POST_TYPE_OPER_WRITE_REPLACE,  
301 - ContentFormat.TLV.getName(), null, value, this.context.getCtxServer().getTimeout()); 301 + lwM2mTransportRequest.sendAllRequest(leshanServer, lwM2MClient.getRegistration(), path, POST_TYPE_OPER_WRITE_REPLACE,
  302 + ContentFormat.TLV.getName(), null, value, this.context.getLwM2MTransportConfigServer().getTimeout());
302 } else { 303 } else {
303 log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", path, value); 304 log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", path, value);
304 String logMsg = String.format("%s: attributeUpdate: Resource path - %s value - %s is not Writable and cannot be updated", 305 String logMsg = String.format("%s: attributeUpdate: Resource path - %s value - %s is not Writable and cannot be updated",
@@ -323,9 +324,9 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -323,9 +324,9 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
323 */ 324 */
324 @Override 325 @Override
325 public void onDeviceProfileUpdate(SessionInfoProto sessionInfo, DeviceProfile deviceProfile) { 326 public void onDeviceProfileUpdate(SessionInfoProto sessionInfo, DeviceProfile deviceProfile) {
326 - Set<String> registrationIds = lwM2mInMemorySecurityStore.getSessions().entrySet() 327 + Set<String> registrationIds = lwM2mClientContext.getLwM2mClients().entrySet()
327 .stream() 328 .stream()
328 - .filter(e -> e.getValue().getProfileUuid().equals(deviceProfile.getUuidId())) 329 + .filter(e -> e.getValue().getProfileId().equals(deviceProfile.getUuidId()))
329 .map(Map.Entry::getKey).sorted().collect(Collectors.toCollection(LinkedHashSet::new)); 330 .map(Map.Entry::getKey).sorted().collect(Collectors.toCollection(LinkedHashSet::new));
330 if (registrationIds.size() > 0) { 331 if (registrationIds.size() > 0) {
331 this.onDeviceUpdateChangeProfile(registrationIds, deviceProfile); 332 this.onDeviceUpdateChangeProfile(registrationIds, deviceProfile);
@@ -339,8 +340,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -339,8 +340,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
339 */ 340 */
340 @Override 341 @Override
341 public void onDeviceUpdate(SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) { 342 public void onDeviceUpdate(SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) {
342 - Optional<String> registrationIdOpt = lwM2mInMemorySecurityStore.getSessions().entrySet().stream()  
343 - .filter(e -> device.getUuidId().equals(e.getValue().getDeviceUuid())) 343 + Optional<String> registrationIdOpt = lwM2mClientContext.getLwM2mClients().entrySet().stream()
  344 + .filter(e -> device.getUuidId().equals(e.getValue().getDeviceId()))
344 .map(Map.Entry::getKey) 345 .map(Map.Entry::getKey)
345 .findFirst(); 346 .findFirst();
346 registrationIdOpt.ifPresent(registrationId -> this.onDeviceUpdateLwM2MClient(registrationId, device, deviceProfileOpt)); 347 registrationIdOpt.ifPresent(registrationId -> this.onDeviceUpdateLwM2MClient(registrationId, device, deviceProfileOpt));
@@ -353,8 +354,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -353,8 +354,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
353 */ 354 */
354 @Override 355 @Override
355 public void doTrigger(LeshanServer lwServer, Registration registration, String path) { 356 public void doTrigger(LeshanServer lwServer, Registration registration, String path) {
356 - lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_EXECUTE,  
357 - ContentFormat.TLV.getName(), null, null, this.context.getCtxServer().getTimeout()); 357 + lwM2mTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_EXECUTE,
  358 + ContentFormat.TLV.getName(), null, null, this.context.getLwM2MTransportConfigServer().getTimeout());
358 } 359 }
359 360
360 /** 361 /**
@@ -397,18 +398,18 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -397,18 +398,18 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
397 * Removes a profile if not used in sessions 398 * Removes a profile if not used in sessions
398 */ 399 */
399 private void syncSessionsAndProfiles() { 400 private void syncSessionsAndProfiles() {
400 - Map<UUID, LwM2MClientProfile> profilesClone = lwM2mInMemorySecurityStore.getProfiles().entrySet() 401 + Map<UUID, LwM2mClientProfile> profilesClone = lwM2mClientContext.getProfiles().entrySet()
401 .stream() 402 .stream()
402 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); 403 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
403 profilesClone.forEach((k, v) -> { 404 profilesClone.forEach((k, v) -> {
404 - String registrationId = lwM2mInMemorySecurityStore.getSessions().entrySet() 405 + String registrationId = lwM2mClientContext.getLwM2mClients().entrySet()
405 .stream() 406 .stream()
406 - .filter(e -> e.getValue().getProfileUuid().equals(k)) 407 + .filter(e -> e.getValue().getProfileId().equals(k))
407 .findFirst() 408 .findFirst()
408 .map(Map.Entry::getKey) // return the key of the matching entry if found 409 .map(Map.Entry::getKey) // return the key of the matching entry if found
409 .orElse(""); 410 .orElse("");
410 if (registrationId.isEmpty()) { 411 if (registrationId.isEmpty()) {
411 - lwM2mInMemorySecurityStore.getProfiles().remove(k); 412 + lwM2mClientContext.getProfiles().remove(k);
412 } 413 }
413 }); 414 });
414 } 415 }
@@ -458,12 +459,12 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -458,12 +459,12 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
458 * @param registration - Registration LwM2M Client 459 * @param registration - Registration LwM2M Client
459 * @param lwM2MClient - object with All parameters off client 460 * @param lwM2MClient - object with All parameters off client
460 */ 461 */
461 - private void initLwM2mFromClientValue(LeshanServer lwServer, Registration registration, LwM2MClient lwM2MClient) {  
462 - LwM2MClientProfile lwM2MClientProfile = lwM2mInMemorySecurityStore.getProfile(registration.getId()); 462 + private void initLwM2mFromClientValue(LeshanServer lwServer, Registration registration, LwM2mClient lwM2MClient) {
  463 + LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration);
463 Set<String> clientObjects = this.getAllOjectsInClient(registration); 464 Set<String> clientObjects = this.getAllOjectsInClient(registration);
464 - if (clientObjects != null && !LwM2MTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { 465 + if (clientObjects != null && !LwM2mTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) {
465 // #2 466 // #2
466 - if (!LwM2MTransportHandler.getClientUpdateValueAfterConnect(lwM2MClientProfile)) { 467 + if (!LwM2mTransportHandler.getClientUpdateValueAfterConnect(lwM2MClientProfile)) {
467 this.initReadAttrTelemetryObserveToClient(lwServer, registration, lwM2MClient, GET_TYPE_OPER_READ); 468 this.initReadAttrTelemetryObserveToClient(lwServer, registration, lwM2MClient, GET_TYPE_OPER_READ);
468 469
469 } 470 }
@@ -471,8 +472,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -471,8 +472,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
471 else { 472 else {
472 lwM2MClient.getPendingRequests().addAll(clientObjects); 473 lwM2MClient.getPendingRequests().addAll(clientObjects);
473 clientObjects.forEach(path -> { 474 clientObjects.forEach(path -> {
474 - lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, GET_TYPE_OPER_READ, ContentFormat.TLV.getName(),  
475 - null, null, this.context.getCtxServer().getTimeout()); 475 + lwM2mTransportRequest.sendAllRequest(lwServer, registration, path, GET_TYPE_OPER_READ, ContentFormat.TLV.getName(),
  476 + null, null, this.context.getLwM2MTransportConfigServer().getTimeout());
476 }); 477 });
477 } 478 }
478 } 479 }
@@ -517,7 +518,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -517,7 +518,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
517 * @param path - resource 518 * @param path - resource
518 */ 519 */
519 private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) { 520 private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) {
520 - LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(registration, null); 521 + LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);
521 lwM2MClient.updateResourceValue(path, lwM2mResource); 522 lwM2MClient.updateResourceValue(path, lwM2mResource);
522 Set<String> paths = new HashSet<>(); 523 Set<String> paths = new HashSet<>();
523 paths.add(path); 524 paths.add(path);
@@ -565,8 +566,9 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -565,8 +566,9 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
565 * @param path - 566 * @param path -
566 * @return true if path isPresent in postAttributeProfile 567 * @return true if path isPresent in postAttributeProfile
567 */ 568 */
568 - private boolean validatePathInAttrProfile(LwM2MClientProfile profile, String path) {  
569 - Set<String> attributesSet = new Gson().fromJson(profile.getPostAttributeProfile(), new TypeToken<>(){}.getType()); 569 + private boolean validatePathInAttrProfile(LwM2mClientProfile profile, String path) {
  570 + Set<String> attributesSet = new Gson().fromJson(profile.getPostAttributeProfile(), new TypeToken<>() {
  571 + }.getType());
570 return attributesSet.stream().filter(p -> p.equals(path)).findFirst().isPresent(); 572 return attributesSet.stream().filter(p -> p.equals(path)).findFirst().isPresent();
571 } 573 }
572 574
@@ -575,8 +577,9 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -575,8 +577,9 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
575 * @param path - 577 * @param path -
576 * @return true if path isPresent in postAttributeProfile 578 * @return true if path isPresent in postAttributeProfile
577 */ 579 */
578 - private boolean validatePathInTelemetryProfile(LwM2MClientProfile profile, String path) {  
579 - Set<String> telemetriesSet = new Gson().fromJson(profile.getPostTelemetryProfile(), new TypeToken<>(){}.getType()); 580 + private boolean validatePathInTelemetryProfile(LwM2mClientProfile profile, String path) {
  581 + Set<String> telemetriesSet = new Gson().fromJson(profile.getPostTelemetryProfile(), new TypeToken<>() {
  582 + }.getType());
580 return telemetriesSet.stream().filter(p -> p.equals(path)).findFirst().isPresent(); 583 return telemetriesSet.stream().filter(p -> p.equals(path)).findFirst().isPresent();
581 } 584 }
582 585
@@ -588,16 +591,19 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -588,16 +591,19 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
588 * @param lwServer - 591 * @param lwServer -
589 * @param registration - 592 * @param registration -
590 */ 593 */
591 - private void initReadAttrTelemetryObserveToClient(LeshanServer lwServer, Registration registration, LwM2MClient lwM2MClient, String typeOper) { 594 + private void initReadAttrTelemetryObserveToClient(LeshanServer lwServer, Registration registration, LwM2mClient lwM2MClient, String typeOper) {
592 try { 595 try {
593 - LwM2MClientProfile lwM2MClientProfile = lwM2mInMemorySecurityStore.getProfile(registration.getId()); 596 + LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration);
594 Set<String> clientInstances = this.getAllInstancesInClient(registration); 597 Set<String> clientInstances = this.getAllInstancesInClient(registration);
595 Set<String> result; 598 Set<String> result;
596 if (GET_TYPE_OPER_READ.equals(typeOper)) { 599 if (GET_TYPE_OPER_READ.equals(typeOper)) {
597 - result = new ObjectMapper().readValue(lwM2MClientProfile.getPostAttributeProfile().getAsJsonArray().toString().getBytes(), new TypeReference<>() {});  
598 - result.addAll(new ObjectMapper().readValue(lwM2MClientProfile.getPostTelemetryProfile().getAsJsonArray().toString().getBytes(), new TypeReference<>() {})); 600 + result = new ObjectMapper().readValue(lwM2MClientProfile.getPostAttributeProfile().getAsJsonArray().toString().getBytes(), new TypeReference<>() {
  601 + });
  602 + result.addAll(new ObjectMapper().readValue(lwM2MClientProfile.getPostTelemetryProfile().getAsJsonArray().toString().getBytes(), new TypeReference<>() {
  603 + }));
599 } else { 604 } else {
600 - result = new ObjectMapper().readValue(lwM2MClientProfile.getPostObserveProfile().getAsJsonArray().toString().getBytes(), new TypeReference<>() {}); 605 + result = new ObjectMapper().readValue(lwM2MClientProfile.getPostObserveProfile().getAsJsonArray().toString().getBytes(), new TypeReference<>() {
  606 + });
601 } 607 }
602 Set<String> pathSent = ConcurrentHashMap.newKeySet(); 608 Set<String> pathSent = ConcurrentHashMap.newKeySet();
603 result.forEach(p -> { 609 result.forEach(p -> {
@@ -611,8 +617,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -611,8 +617,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
611 }); 617 });
612 lwM2MClient.getPendingRequests().addAll(pathSent); 618 lwM2MClient.getPendingRequests().addAll(pathSent);
613 pathSent.forEach(target -> { 619 pathSent.forEach(target -> {
614 - lwM2MTransportRequest.sendAllRequest(lwServer, registration, target, typeOper, ContentFormat.TLV.getName(),  
615 - null, null, this.context.getCtxServer().getTimeout()); 620 + lwM2mTransportRequest.sendAllRequest(lwServer, registration, target, typeOper, ContentFormat.TLV.getName(),
  621 + null, null, this.context.getLwM2MTransportConfigServer().getTimeout());
616 }); 622 });
617 if (GET_TYPE_OPER_OBSERVE.equals(typeOper)) { 623 if (GET_TYPE_OPER_OBSERVE.equals(typeOper)) {
618 lwM2MClient.initValue(this, null); 624 lwM2MClient.initValue(this, null);
@@ -630,15 +636,15 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -630,15 +636,15 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
630 * @param device - 636 * @param device -
631 */ 637 */
632 private void onDeviceUpdateLwM2MClient(String registrationId, Device device, Optional<DeviceProfile> deviceProfileOpt) { 638 private void onDeviceUpdateLwM2MClient(String registrationId, Device device, Optional<DeviceProfile> deviceProfileOpt) {
633 - LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getSessions().get(registrationId); 639 + LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClients().get(registrationId);
634 lwM2MClient.setDeviceName(device.getName()); 640 lwM2MClient.setDeviceName(device.getName());
635 - if (!lwM2MClient.getProfileUuid().equals(device.getDeviceProfileId().getId())) { 641 + if (!lwM2MClient.getProfileId().equals(device.getDeviceProfileId().getId())) {
636 Set<String> registrationIds = new HashSet<>(); 642 Set<String> registrationIds = new HashSet<>();
637 registrationIds.add(registrationId); 643 registrationIds.add(registrationId);
638 deviceProfileOpt.ifPresent(deviceProfile -> this.onDeviceUpdateChangeProfile(registrationIds, deviceProfile)); 644 deviceProfileOpt.ifPresent(deviceProfile -> this.onDeviceUpdateChangeProfile(registrationIds, deviceProfile));
639 } 645 }
640 646
641 - lwM2MClient.setProfileUuid(device.getDeviceProfileId().getId()); 647 + lwM2MClient.setProfileId(device.getDeviceProfileId().getId());
642 } 648 }
643 649
644 /** 650 /**
@@ -693,20 +699,20 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -693,20 +699,20 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
693 * @param path 699 * @param path
694 */ 700 */
695 private void getParametersFromProfile(JsonObject attributes, JsonObject telemetry, Registration registration, Set<String> path) { 701 private void getParametersFromProfile(JsonObject attributes, JsonObject telemetry, Registration registration, Set<String> path) {
696 - LwM2MClientProfile lwM2MClientProfile = lwM2mInMemorySecurityStore.getProfile(registration.getId()); 702 + LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration);
697 lwM2MClientProfile.getPostAttributeProfile().forEach(p -> { 703 lwM2MClientProfile.getPostAttributeProfile().forEach(p -> {
698 - LwM2mPath pathIds = new LwM2mPath(p.getAsString().toString()); 704 + LwM2mPath pathIds = new LwM2mPath(p.getAsString());
699 if (pathIds.isResource()) { 705 if (pathIds.isResource()) {
700 if (path == null || path.contains(p.getAsString())) { 706 if (path == null || path.contains(p.getAsString())) {
701 - this.addParameters(p.getAsString().toString(), attributes, registration); 707 + this.addParameters(p.getAsString(), attributes, registration);
702 } 708 }
703 } 709 }
704 }); 710 });
705 lwM2MClientProfile.getPostTelemetryProfile().forEach(p -> { 711 lwM2MClientProfile.getPostTelemetryProfile().forEach(p -> {
706 - LwM2mPath pathIds = new LwM2mPath(p.getAsString().toString()); 712 + LwM2mPath pathIds = new LwM2mPath(p.getAsString());
707 if (pathIds.isResource()) { 713 if (pathIds.isResource()) {
708 if (path == null || path.contains(p.getAsString())) { 714 if (path == null || path.contains(p.getAsString())) {
709 - this.addParameters(p.getAsString().toString(), telemetry, registration); 715 + this.addParameters(p.getAsString(), telemetry, registration);
710 } 716 }
711 } 717 }
712 }); 718 });
@@ -717,8 +723,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -717,8 +723,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
717 * @param registration - Registration LwM2M Client 723 * @param registration - Registration LwM2M Client
718 */ 724 */
719 private void addParameters(String path, JsonObject parameters, Registration registration) { 725 private void addParameters(String path, JsonObject parameters, Registration registration) {
720 - LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getSessions().get(registration.getId());  
721 - JsonObject names = lwM2mInMemorySecurityStore.getProfiles().get(lwM2MClient.getProfileUuid()).getPostKeyNameProfile(); 726 + LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);
  727 + JsonObject names = lwM2mClientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile();
722 String resName = String.valueOf(names.get(path)); 728 String resName = String.valueOf(names.get(path));
723 if (resName != null && !resName.isEmpty()) { 729 if (resName != null && !resName.isEmpty()) {
724 try { 730 try {
@@ -727,7 +733,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -727,7 +733,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
727 parameters.addProperty(resName, resValue); 733 parameters.addProperty(resName, resValue);
728 } 734 }
729 } catch (Exception e) { 735 } catch (Exception e) {
730 - log.error(e.getStackTrace().toString()); 736 + log.error("Failed to add parameters.", e);
731 } 737 }
732 } 738 }
733 } 739 }
@@ -736,11 +742,11 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -736,11 +742,11 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
736 * @param path - path resource 742 * @param path - path resource
737 * @return - value of Resource or null 743 * @return - value of Resource or null
738 */ 744 */
739 - private String getResourceValueToString(LwM2MClient lwM2MClient, String path) { 745 + private String getResourceValueToString(LwM2mClient lwM2MClient, String path) {
740 LwM2mPath pathIds = new LwM2mPath(path); 746 LwM2mPath pathIds = new LwM2mPath(path);
741 ResourceValue resourceValue = this.returnResourceValueFromLwM2MClient(lwM2MClient, pathIds); 747 ResourceValue resourceValue = this.returnResourceValueFromLwM2MClient(lwM2MClient, pathIds);
742 - return (resourceValue == null) ? null :  
743 - (String) this.converter.convertValue(resourceValue.getResourceValue(), this.context.getCtxServer().getResourceModelType(lwM2MClient.getRegistration(), pathIds), ResourceModel.Type.STRING, pathIds); 748 + return resourceValue == null ? null :
  749 + this.converter.convertValue(resourceValue.getResourceValue(), this.context.getLwM2MTransportConfigServer().getResourceModelType(lwM2MClient.getRegistration(), pathIds), ResourceModel.Type.STRING, pathIds).toString();
744 } 750 }
745 751
746 /** 752 /**
@@ -749,7 +755,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -749,7 +755,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
749 * @param pathIds - 755 * @param pathIds -
750 * @return - return value of Resource by idPath 756 * @return - return value of Resource by idPath
751 */ 757 */
752 - private ResourceValue returnResourceValueFromLwM2MClient(LwM2MClient lwM2MClient, LwM2mPath pathIds) { 758 + private ResourceValue returnResourceValueFromLwM2MClient(LwM2mClient lwM2MClient, LwM2mPath pathIds) {
753 ResourceValue resourceValue = null; 759 ResourceValue resourceValue = null;
754 if (pathIds.isResource()) { 760 if (pathIds.isResource()) {
755 resourceValue = lwM2MClient.getResources().get(pathIds.toString()); 761 resourceValue = lwM2MClient.getResources().get(pathIds.toString());
@@ -790,23 +796,25 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -790,23 +796,25 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
790 * @param deviceProfile - 796 * @param deviceProfile -
791 */ 797 */
792 private void onDeviceUpdateChangeProfile(Set<String> registrationIds, DeviceProfile deviceProfile) { 798 private void onDeviceUpdateChangeProfile(Set<String> registrationIds, DeviceProfile deviceProfile) {
793 -  
794 - LwM2MClientProfile lwM2MClientProfileOld = lwM2mInMemorySecurityStore.getProfiles().get(deviceProfile.getUuidId());  
795 - if (lwM2mInMemorySecurityStore.addUpdateProfileParameters(deviceProfile)) {  
796 - 799 + LwM2mClientProfile lwM2MClientProfileOld = lwM2mClientContext.getProfiles().get(deviceProfile.getUuidId());
  800 + if (lwM2mClientContext.addUpdateProfileParameters(deviceProfile)) {
797 // #1 801 // #1
798 JsonArray attributeOld = lwM2MClientProfileOld.getPostAttributeProfile(); 802 JsonArray attributeOld = lwM2MClientProfileOld.getPostAttributeProfile();
799 - Set<String> attributeSetOld = new Gson().fromJson(attributeOld, new TypeToken<>(){}.getType()); 803 + Set<String> attributeSetOld = new Gson().fromJson(attributeOld, new TypeToken<>() {
  804 + }.getType());
800 JsonArray telemetryOld = lwM2MClientProfileOld.getPostTelemetryProfile(); 805 JsonArray telemetryOld = lwM2MClientProfileOld.getPostTelemetryProfile();
801 - Set<String> telemetrySetOld = new Gson().fromJson(telemetryOld, new TypeToken<>(){}.getType()); 806 + Set<String> telemetrySetOld = new Gson().fromJson(telemetryOld, new TypeToken<>() {
  807 + }.getType());
802 JsonArray observeOld = lwM2MClientProfileOld.getPostObserveProfile(); 808 JsonArray observeOld = lwM2MClientProfileOld.getPostObserveProfile();
803 JsonObject keyNameOld = lwM2MClientProfileOld.getPostKeyNameProfile(); 809 JsonObject keyNameOld = lwM2MClientProfileOld.getPostKeyNameProfile();
804 810
805 - LwM2MClientProfile lwM2MClientProfileNew = lwM2mInMemorySecurityStore.getProfiles().get(deviceProfile.getUuidId()); 811 + LwM2mClientProfile lwM2MClientProfileNew = lwM2mClientContext.getProfiles().get(deviceProfile.getUuidId());
806 JsonArray attributeNew = lwM2MClientProfileNew.getPostAttributeProfile(); 812 JsonArray attributeNew = lwM2MClientProfileNew.getPostAttributeProfile();
807 - Set<String> attributeSetNew = new Gson().fromJson(attributeNew, new TypeToken<>(){}.getType()); 813 + Set<String> attributeSetNew = new Gson().fromJson(attributeNew, new TypeToken<>() {
  814 + }.getType());
808 JsonArray telemetryNew = lwM2MClientProfileNew.getPostTelemetryProfile(); 815 JsonArray telemetryNew = lwM2MClientProfileNew.getPostTelemetryProfile();
809 - Set<String> telemetrySetNew = new Gson().fromJson(telemetryNew, new TypeToken<>(){}.getType()); 816 + Set<String> telemetrySetNew = new Gson().fromJson(telemetryNew, new TypeToken<>() {
  817 + }.getType());
810 JsonArray observeNew = lwM2MClientProfileNew.getPostObserveProfile(); 818 JsonArray observeNew = lwM2MClientProfileNew.getPostObserveProfile();
811 JsonObject keyNameNew = lwM2MClientProfileNew.getPostKeyNameProfile(); 819 JsonObject keyNameNew = lwM2MClientProfileNew.getPostKeyNameProfile();
812 820
@@ -814,20 +822,24 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -814,20 +822,24 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
814 ResultsAnalyzerParameters sentAttrToThingsboard = new ResultsAnalyzerParameters(); 822 ResultsAnalyzerParameters sentAttrToThingsboard = new ResultsAnalyzerParameters();
815 // #3.1 823 // #3.1
816 if (!attributeOld.equals(attributeNew)) { 824 if (!attributeOld.equals(attributeNew)) {
817 - ResultsAnalyzerParameters postAttributeAnalyzer = this.getAnalyzerParameters(new Gson().fromJson(attributeOld, new TypeToken<Set<String>>(){}.getType()), attributeSetNew); 825 + ResultsAnalyzerParameters postAttributeAnalyzer = this.getAnalyzerParameters(new Gson().fromJson(attributeOld, new TypeToken<Set<String>>() {
  826 + }.getType()), attributeSetNew);
818 sentAttrToThingsboard.getPathPostParametersAdd().addAll(postAttributeAnalyzer.getPathPostParametersAdd()); 827 sentAttrToThingsboard.getPathPostParametersAdd().addAll(postAttributeAnalyzer.getPathPostParametersAdd());
819 sentAttrToThingsboard.getPathPostParametersDel().addAll(postAttributeAnalyzer.getPathPostParametersDel()); 828 sentAttrToThingsboard.getPathPostParametersDel().addAll(postAttributeAnalyzer.getPathPostParametersDel());
820 } 829 }
821 // #3.2 830 // #3.2
822 - if (!attributeOld.equals(attributeNew)) {  
823 - ResultsAnalyzerParameters postTelemetryAnalyzer = this.getAnalyzerParameters(new Gson().fromJson(telemetryOld, new TypeToken<Set<String>>(){}.getType()), telemetrySetNew); 831 + if (!telemetryOld.equals(telemetryNew)) {
  832 + ResultsAnalyzerParameters postTelemetryAnalyzer = this.getAnalyzerParameters(new Gson().fromJson(telemetryOld, new TypeToken<Set<String>>() {
  833 + }.getType()), telemetrySetNew);
824 sentAttrToThingsboard.getPathPostParametersAdd().addAll(postTelemetryAnalyzer.getPathPostParametersAdd()); 834 sentAttrToThingsboard.getPathPostParametersAdd().addAll(postTelemetryAnalyzer.getPathPostParametersAdd());
825 sentAttrToThingsboard.getPathPostParametersDel().addAll(postTelemetryAnalyzer.getPathPostParametersDel()); 835 sentAttrToThingsboard.getPathPostParametersDel().addAll(postTelemetryAnalyzer.getPathPostParametersDel());
826 } 836 }
827 // #3.3 837 // #3.3
828 if (!keyNameOld.equals(keyNameNew)) { 838 if (!keyNameOld.equals(keyNameNew)) {
829 - ResultsAnalyzerParameters keyNameChange = this.getAnalyzerKeyName(new Gson().fromJson(keyNameOld.toString(), new TypeToken<ConcurrentHashMap<String, String>>(){}.getType()),  
830 - new Gson().fromJson(keyNameNew.toString(), new TypeToken<ConcurrentHashMap<String, String>>(){}.getType())); 839 + ResultsAnalyzerParameters keyNameChange = this.getAnalyzerKeyName(new Gson().fromJson(keyNameOld.toString(), new TypeToken<ConcurrentHashMap<String, String>>() {
  840 + }.getType()),
  841 + new Gson().fromJson(keyNameNew.toString(), new TypeToken<ConcurrentHashMap<String, String>>() {
  842 + }.getType()));
831 sentAttrToThingsboard.getPathPostParametersAdd().addAll(keyNameChange.getPathPostParametersAdd()); 843 sentAttrToThingsboard.getPathPostParametersAdd().addAll(keyNameChange.getPathPostParametersAdd());
832 } 844 }
833 845
@@ -835,9 +847,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -835,9 +847,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
835 if (sentAttrToThingsboard.getPathPostParametersAdd().size() > 0) { 847 if (sentAttrToThingsboard.getPathPostParametersAdd().size() > 0) {
836 // update value in Resources 848 // update value in Resources
837 registrationIds.forEach(registrationId -> { 849 registrationIds.forEach(registrationId -> {
838 - LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(null, registrationId);  
839 - LeshanServer lwServer = lwM2MClient.getLwServer();  
840 - Registration registration = lwM2mInMemorySecurityStore.getByRegistration(registrationId); 850 + LeshanServer lwServer = leshanServer;
  851 + Registration registration = lwM2mClientContext.getRegistration(registrationId);
841 this.readResourceValueObserve(lwServer, registration, sentAttrToThingsboard.getPathPostParametersAdd(), GET_TYPE_OPER_READ); 852 this.readResourceValueObserve(lwServer, registration, sentAttrToThingsboard.getPathPostParametersAdd(), GET_TYPE_OPER_READ);
842 // sent attr/telemetry to tingsboard for new path 853 // sent attr/telemetry to tingsboard for new path
843 this.updateAttrTelemetry(registration, false, sentAttrToThingsboard.getPathPostParametersAdd()); 854 this.updateAttrTelemetry(registration, false, sentAttrToThingsboard.getPathPostParametersAdd());
@@ -851,8 +862,10 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -851,8 +862,10 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
851 862
852 // #5.1 863 // #5.1
853 if (!observeOld.equals(observeNew)) { 864 if (!observeOld.equals(observeNew)) {
854 - Set<String> observeSetOld = new Gson().fromJson(observeOld, new TypeToken<>(){}.getType());  
855 - Set<String> observeSetNew = new Gson().fromJson(observeNew, new TypeToken<>(){}.getType()); 865 + Set<String> observeSetOld = new Gson().fromJson(observeOld, new TypeToken<>() {
  866 + }.getType());
  867 + Set<String> observeSetNew = new Gson().fromJson(observeNew, new TypeToken<>() {
  868 + }.getType());
856 //#5.2 add 869 //#5.2 add
857 // path Attr/Telemetry includes newObserve 870 // path Attr/Telemetry includes newObserve
858 attributeSetOld.addAll(telemetrySetOld); 871 attributeSetOld.addAll(telemetrySetOld);
@@ -863,9 +876,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -863,9 +876,8 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
863 ResultsAnalyzerParameters postObserveAnalyzer = this.getAnalyzerParameters(sentObserveToClientOld.getPathPostParametersAdd(), sentObserveToClientNew.getPathPostParametersAdd()); 876 ResultsAnalyzerParameters postObserveAnalyzer = this.getAnalyzerParameters(sentObserveToClientOld.getPathPostParametersAdd(), sentObserveToClientNew.getPathPostParametersAdd());
864 // sent Request observe to Client 877 // sent Request observe to Client
865 registrationIds.forEach(registrationId -> { 878 registrationIds.forEach(registrationId -> {
866 - LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClient(null, registrationId);  
867 - LeshanServer lwServer = lwM2MClient.getLwServer();  
868 - Registration registration = lwM2mInMemorySecurityStore.getByRegistration(registrationId); 879 + LeshanServer lwServer = leshanServer;
  880 + Registration registration = lwM2mClientContext.getRegistration(registrationId);
869 this.readResourceValueObserve(lwServer, registration, postObserveAnalyzer.getPathPostParametersAdd(), GET_TYPE_OPER_OBSERVE); 881 this.readResourceValueObserve(lwServer, registration, postObserveAnalyzer.getPathPostParametersAdd(), GET_TYPE_OPER_OBSERVE);
870 // 5.3 del 882 // 5.3 del
871 // sent Request cancel observe to Client 883 // sent Request cancel observe to Client
@@ -914,11 +926,11 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -914,11 +926,11 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
914 LwM2mPath pathIds = new LwM2mPath(target); 926 LwM2mPath pathIds = new LwM2mPath(target);
915 if (pathIds.isResource()) { 927 if (pathIds.isResource()) {
916 if (GET_TYPE_OPER_READ.equals(typeOper)) { 928 if (GET_TYPE_OPER_READ.equals(typeOper)) {
917 - lwM2MTransportRequest.sendAllRequest(lwServer, registration, target, typeOper,  
918 - ContentFormat.TLV.getName(), null, null, this.context.getCtxServer().getTimeout()); 929 + lwM2mTransportRequest.sendAllRequest(lwServer, registration, target, typeOper,
  930 + ContentFormat.TLV.getName(), null, null, this.context.getLwM2MTransportConfigServer().getTimeout());
919 } else if (GET_TYPE_OPER_OBSERVE.equals(typeOper)) { 931 } else if (GET_TYPE_OPER_OBSERVE.equals(typeOper)) {
920 - lwM2MTransportRequest.sendAllRequest(lwServer, registration, target, typeOper,  
921 - null, null, null, this.context.getCtxServer().getTimeout()); 932 + lwM2mTransportRequest.sendAllRequest(lwServer, registration, target, typeOper,
  933 + null, null, null, this.context.getLwM2MTransportConfigServer().getTimeout());
922 } 934 }
923 } 935 }
924 }); 936 });
@@ -935,7 +947,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -935,7 +947,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
935 } 947 }
936 948
937 private void cancelObserveIsValue(LeshanServer lwServer, Registration registration, Set<String> paramAnallyzer) { 949 private void cancelObserveIsValue(LeshanServer lwServer, Registration registration, Set<String> paramAnallyzer) {
938 - LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(registration, null); 950 + LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);
939 paramAnallyzer.forEach(p -> { 951 paramAnallyzer.forEach(p -> {
940 if (this.returnResourceValueFromLwM2MClient(lwM2MClient, new LwM2mPath(p)) != null) { 952 if (this.returnResourceValueFromLwM2MClient(lwM2MClient, new LwM2mPath(p)) != null) {
941 this.setCancelObservationRecourse(lwServer, registration, p); 953 this.setCancelObservationRecourse(lwServer, registration, p);
@@ -944,10 +956,10 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -944,10 +956,10 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
944 ); 956 );
945 } 957 }
946 958
947 - private void putDelayedUpdateResourcesClient(LwM2MClient lwM2MClient, Object valueOld, Object valueNew, String path) { 959 + private void putDelayedUpdateResourcesClient(LwM2mClient lwM2MClient, Object valueOld, Object valueNew, String path) {
948 if (valueNew != null && (valueOld == null || !valueNew.toString().equals(valueOld.toString()))) { 960 if (valueNew != null && (valueOld == null || !valueNew.toString().equals(valueOld.toString()))) {
949 - lwM2MTransportRequest.sendAllRequest(lwM2MClient.getLwServer(), lwM2MClient.getRegistration(), path, POST_TYPE_OPER_WRITE_REPLACE,  
950 - ContentFormat.TLV.getName(), null, valueNew, this.context.getCtxServer().getTimeout()); 961 + lwM2mTransportRequest.sendAllRequest(leshanServer, lwM2MClient.getRegistration(), path, POST_TYPE_OPER_WRITE_REPLACE,
  962 + ContentFormat.TLV.getName(), null, valueNew, this.context.getLwM2MTransportConfigServer().getTimeout());
951 } else { 963 } else {
952 log.error("05 delayError"); 964 log.error("05 delayError");
953 } 965 }
@@ -982,7 +994,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -982,7 +994,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
982 * @return - 994 * @return -
983 */ 995 */
984 private String getPathAttributeUpdateProfile(TransportProtos.SessionInfoProto sessionInfo, String name) { 996 private String getPathAttributeUpdateProfile(TransportProtos.SessionInfoProto sessionInfo, String name) {
985 - LwM2MClientProfile profile = lwM2mInMemorySecurityStore.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); 997 + LwM2mClientProfile profile = lwM2mClientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));
986 return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() 998 return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream()
987 .filter(e -> e.getValue().getAsString().equals(name)).findFirst().map(Map.Entry::getKey) 999 .filter(e -> e.getValue().getAsString().equals(name)).findFirst().map(Map.Entry::getKey)
988 .orElse(""); 1000 .orElse("");
@@ -1002,7 +1014,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -1002,7 +1014,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
1002 */ 1014 */
1003 public void onGetAttributesResponse(TransportProtos.GetAttributeResponseMsg attributesResponse, TransportProtos.SessionInfoProto sessionInfo) { 1015 public void onGetAttributesResponse(TransportProtos.GetAttributeResponseMsg attributesResponse, TransportProtos.SessionInfoProto sessionInfo) {
1004 try { 1016 try {
1005 - LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClient(sessionInfo); 1017 + LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo);
1006 attributesResponse.getSharedAttributeListList().forEach(attr -> { 1018 attributesResponse.getSharedAttributeListList().forEach(attr -> {
1007 String path = this.getPathAttributeUpdate(sessionInfo, attr.getKv().getKey()); 1019 String path = this.getPathAttributeUpdate(sessionInfo, attr.getKv().getKey());
1008 // #1.1 1020 // #1.1
@@ -1027,18 +1039,18 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -1027,18 +1039,18 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
1027 * @param lwM2MClient - 1039 * @param lwM2MClient -
1028 * @return 1040 * @return
1029 */ 1041 */
1030 - private SessionInfoProto getNewSessionInfoProto(LwM2MClient lwM2MClient) { 1042 + private SessionInfoProto getNewSessionInfoProto(LwM2mClient lwM2MClient) {
1031 if (lwM2MClient != null) { 1043 if (lwM2MClient != null) {
1032 TransportProtos.ValidateDeviceCredentialsResponseMsg msg = lwM2MClient.getCredentialsResponse(); 1044 TransportProtos.ValidateDeviceCredentialsResponseMsg msg = lwM2MClient.getCredentialsResponse();
1033 if (msg == null || msg.getDeviceInfo() == null) { 1045 if (msg == null || msg.getDeviceInfo() == null) {
1034 - log.error("[{}] [{}]", lwM2MClient.getEndPoint(), CLIENT_NOT_AUTHORIZED); 1046 + log.error("[{}] [{}]", lwM2MClient.getEndpoint(), CLIENT_NOT_AUTHORIZED);
1035 this.closeClientSession(lwM2MClient.getRegistration()); 1047 this.closeClientSession(lwM2MClient.getRegistration());
1036 return null; 1048 return null;
1037 } else { 1049 } else {
1038 return SessionInfoProto.newBuilder() 1050 return SessionInfoProto.newBuilder()
1039 .setNodeId(this.context.getNodeId()) 1051 .setNodeId(this.context.getNodeId())
1040 - .setSessionIdMSB(lwM2MClient.getSessionUuid().getMostSignificantBits())  
1041 - .setSessionIdLSB(lwM2MClient.getSessionUuid().getLeastSignificantBits()) 1052 + .setSessionIdMSB(lwM2MClient.getSessionId().getMostSignificantBits())
  1053 + .setSessionIdLSB(lwM2MClient.getSessionId().getLeastSignificantBits())
1042 .setDeviceIdMSB(msg.getDeviceInfo().getDeviceIdMSB()) 1054 .setDeviceIdMSB(msg.getDeviceInfo().getDeviceIdMSB())
1043 .setDeviceIdLSB(msg.getDeviceInfo().getDeviceIdLSB()) 1055 .setDeviceIdLSB(msg.getDeviceInfo().getDeviceIdLSB())
1044 .setTenantIdMSB(msg.getDeviceInfo().getTenantIdMSB()) 1056 .setTenantIdMSB(msg.getDeviceInfo().getTenantIdMSB())
@@ -1053,13 +1065,12 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -1053,13 +1065,12 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
1053 return null; 1065 return null;
1054 } 1066 }
1055 1067
1056 -  
1057 /** 1068 /**
1058 * @param registration - Registration LwM2M Client 1069 * @param registration - Registration LwM2M Client
1059 * @return - sessionInfo after access connect client 1070 * @return - sessionInfo after access connect client
1060 */ 1071 */
1061 private SessionInfoProto getValidateSessionInfo(Registration registration) { 1072 private SessionInfoProto getValidateSessionInfo(Registration registration) {
1062 - LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(registration, null); 1073 + LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);
1063 return getNewSessionInfoProto(lwM2MClient); 1074 return getNewSessionInfoProto(lwM2MClient);
1064 } 1075 }
1065 1076
@@ -1068,7 +1079,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -1068,7 +1079,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
1068 * @return - 1079 * @return -
1069 */ 1080 */
1070 private SessionInfoProto getValidateSessionInfo(String registrationId) { 1081 private SessionInfoProto getValidateSessionInfo(String registrationId) {
1071 - LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(null, registrationId); 1082 + LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(null, registrationId);
1072 return getNewSessionInfoProto(lwM2MClient); 1083 return getNewSessionInfoProto(lwM2MClient);
1073 } 1084 }
1074 1085
@@ -1079,12 +1090,12 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -1079,12 +1090,12 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
1079 */ 1090 */
1080 private void checkInactivity(SessionInfoProto sessionInfo) { 1091 private void checkInactivity(SessionInfoProto sessionInfo) {
1081 if (transportService.reportActivity(sessionInfo) == null) { 1092 if (transportService.reportActivity(sessionInfo) == null) {
1082 - transportService.registerAsyncSession(sessionInfo, new LwM2MSessionMsgListener(this, sessionInfo)); 1093 + transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo));
1083 } 1094 }
1084 } 1095 }
1085 1096
1086 private void checkInactivityAndReportActivity() { 1097 private void checkInactivityAndReportActivity() {
1087 - lwM2mInMemorySecurityStore.getSessions().forEach((key, value) -> this.checkInactivity(this.getValidateSessionInfo(key))); 1098 + lwM2mClientContext.getLwM2mClients().forEach((key, value) -> this.checkInactivity(this.getValidateSessionInfo(key)));
1088 } 1099 }
1089 1100
1090 /** 1101 /**
@@ -1095,7 +1106,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -1095,7 +1106,7 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
1095 * 1106 *
1096 * @param lwM2MClient - LwM2M Client 1107 * @param lwM2MClient - LwM2M Client
1097 */ 1108 */
1098 - public void putDelayedUpdateResourcesThingsboard(LwM2MClient lwM2MClient) { 1109 + public void putDelayedUpdateResourcesThingsboard(LwM2mClient lwM2MClient) {
1099 SessionInfoProto sessionInfo = this.getValidateSessionInfo(lwM2MClient.getRegistration()); 1110 SessionInfoProto sessionInfo = this.getValidateSessionInfo(lwM2MClient.getRegistration());
1100 if (sessionInfo != null) { 1111 if (sessionInfo != null) {
1101 //#1.1 + #1.2 1112 //#1.1 + #1.2
@@ -1119,15 +1130,16 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService { @@ -1119,15 +1130,16 @@ public class LwM2MTransportServiceImpl implements LwM2MTransportService {
1119 * @param lwM2MClient - 1130 * @param lwM2MClient -
1120 * @return ArrayList keyNames from profile attr resources shared!!!! && IsWritable 1131 * @return ArrayList keyNames from profile attr resources shared!!!! && IsWritable
1121 */ 1132 */
1122 - private List<String> getNamesAttrFromProfileIsWritable(LwM2MClient lwM2MClient) {  
1123 - LwM2MClientProfile profile = lwM2mInMemorySecurityStore.getProfile(lwM2MClient.getProfileUuid()); 1133 + private List<String> getNamesAttrFromProfileIsWritable(LwM2mClient lwM2MClient) {
  1134 + LwM2mClientProfile profile = lwM2mClientContext.getProfile(lwM2MClient.getProfileId());
1124 Set attrSet = new Gson().fromJson(profile.getPostAttributeProfile(), Set.class); 1135 Set attrSet = new Gson().fromJson(profile.getPostAttributeProfile(), Set.class);
1125 - ConcurrentMap<String, String> keyNamesMap = new Gson().fromJson(profile.getPostKeyNameProfile().toString(), new TypeToken<ConcurrentHashMap<String, String>>(){}.getType()); 1136 + ConcurrentMap<String, String> keyNamesMap = new Gson().fromJson(profile.getPostKeyNameProfile().toString(), new TypeToken<ConcurrentHashMap<String, String>>() {
  1137 + }.getType());
1126 1138
1127 ConcurrentMap<String, String> keyNamesIsWritable = keyNamesMap.entrySet() 1139 ConcurrentMap<String, String> keyNamesIsWritable = keyNamesMap.entrySet()
1128 .stream() 1140 .stream()
1129 - .filter(e -> (attrSet.contains(e.getKey()) && context.getCtxServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(e.getKey())) != null &&  
1130 - context.getCtxServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(e.getKey())).operations.isWritable())) 1141 + .filter(e -> (attrSet.contains(e.getKey()) && context.getLwM2MTransportConfigServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(e.getKey())) != null &&
  1142 + context.getLwM2MTransportConfigServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(e.getKey())).operations.isWritable()))
1131 .collect(Collectors.toConcurrentMap(Map.Entry::getKey, Map.Entry::getValue)); 1143 .collect(Collectors.toConcurrentMap(Map.Entry::getKey, Map.Entry::getValue));
1132 1144
1133 Set<String> namesIsWritable = ConcurrentHashMap.newKeySet(); 1145 Set<String> namesIsWritable = ConcurrentHashMap.newKeySet();
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2MClient.java
@@ -20,13 +20,11 @@ import lombok.extern.slf4j.Slf4j; @@ -20,13 +20,11 @@ import lombok.extern.slf4j.Slf4j;
20 import org.eclipse.leshan.core.node.LwM2mMultipleResource; 20 import org.eclipse.leshan.core.node.LwM2mMultipleResource;
21 import org.eclipse.leshan.core.node.LwM2mResource; 21 import org.eclipse.leshan.core.node.LwM2mResource;
22 import org.eclipse.leshan.core.node.LwM2mSingleResource; 22 import org.eclipse.leshan.core.node.LwM2mSingleResource;
23 -import org.eclipse.leshan.server.californium.LeshanServer;  
24 import org.eclipse.leshan.server.registration.Registration; 23 import org.eclipse.leshan.server.registration.Registration;
25 import org.eclipse.leshan.server.security.SecurityInfo; 24 import org.eclipse.leshan.server.security.SecurityInfo;
26 import org.thingsboard.server.gen.transport.TransportProtos; 25 import org.thingsboard.server.gen.transport.TransportProtos;
27 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; 26 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
28 -import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportServiceImpl;  
29 -import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; 27 +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServiceImpl;
30 28
31 import java.util.List; 29 import java.util.List;
32 import java.util.Map; 30 import java.util.Map;
@@ -36,42 +34,36 @@ import java.util.concurrent.CopyOnWriteArrayList; @@ -36,42 +34,36 @@ import java.util.concurrent.CopyOnWriteArrayList;
36 34
37 @Slf4j 35 @Slf4j
38 @Data 36 @Data
39 -public class LwM2MClient implements Cloneable { 37 +public class LwM2mClient implements Cloneable {
40 private String deviceName; 38 private String deviceName;
41 private String deviceProfileName; 39 private String deviceProfileName;
42 - private String endPoint; 40 + private String endpoint;
43 private String identity; 41 private String identity;
44 private SecurityInfo securityInfo; 42 private SecurityInfo securityInfo;
45 - private UUID deviceUuid;  
46 - private UUID sessionUuid;  
47 - private UUID profileUuid;  
48 - private LeshanServer lwServer;  
49 - private LwM2MTransportServiceImpl lwM2MTransportServiceImpl; 43 + private UUID deviceId;
  44 + private UUID sessionId;
  45 + private UUID profileId;
50 private Registration registration; 46 private Registration registration;
51 private ValidateDeviceCredentialsResponseMsg credentialsResponse; 47 private ValidateDeviceCredentialsResponseMsg credentialsResponse;
52 - private final Map<String, String> attributes;  
53 private final Map<String, ResourceValue> resources; 48 private final Map<String, ResourceValue> resources;
54 private final Map<String, TransportProtos.TsKvProto> delayedRequests; 49 private final Map<String, TransportProtos.TsKvProto> delayedRequests;
55 private final List<String> pendingRequests; 50 private final List<String> pendingRequests;
56 private boolean init; 51 private boolean init;
57 - private final LwM2mValueConverterImpl converter;  
58 52
59 public Object clone() throws CloneNotSupportedException { 53 public Object clone() throws CloneNotSupportedException {
60 return super.clone(); 54 return super.clone();
61 } 55 }
62 56
63 - public LwM2MClient(String endPoint, String identity, SecurityInfo securityInfo, ValidateDeviceCredentialsResponseMsg credentialsResponse, UUID profileUuid, UUID sessionUuid) {  
64 - this.endPoint = endPoint; 57 + public LwM2mClient(String endpoint, String identity, SecurityInfo securityInfo, ValidateDeviceCredentialsResponseMsg credentialsResponse, UUID profileId, UUID sessionId) {
  58 + this.endpoint = endpoint;
65 this.identity = identity; 59 this.identity = identity;
66 this.securityInfo = securityInfo; 60 this.securityInfo = securityInfo;
67 this.credentialsResponse = credentialsResponse; 61 this.credentialsResponse = credentialsResponse;
68 - this.attributes = new ConcurrentHashMap<>();  
69 this.delayedRequests = new ConcurrentHashMap<>(); 62 this.delayedRequests = new ConcurrentHashMap<>();
70 this.pendingRequests = new CopyOnWriteArrayList<>(); 63 this.pendingRequests = new CopyOnWriteArrayList<>();
71 this.resources = new ConcurrentHashMap<>(); 64 this.resources = new ConcurrentHashMap<>();
72 - this.profileUuid = profileUuid;  
73 - this.sessionUuid = sessionUuid;  
74 - this.converter = LwM2mValueConverterImpl.getInstance(); 65 + this.profileId = profileId;
  66 + this.sessionId = sessionId;
75 this.init = false; 67 this.init = false;
76 } 68 }
77 69
@@ -83,7 +75,7 @@ public class LwM2MClient implements Cloneable { @@ -83,7 +75,7 @@ public class LwM2MClient implements Cloneable {
83 } 75 }
84 } 76 }
85 77
86 - public void initValue(LwM2MTransportServiceImpl lwM2MTransportService, String path) { 78 + public void initValue(LwM2mTransportServiceImpl lwM2MTransportService, String path) {
87 if (path != null) { 79 if (path != null) {
88 this.pendingRequests.remove(path); 80 this.pendingRequests.remove(path);
89 } 81 }
@@ -93,8 +85,8 @@ public class LwM2MClient implements Cloneable { @@ -93,8 +85,8 @@ public class LwM2MClient implements Cloneable {
93 } 85 }
94 } 86 }
95 87
96 - public LwM2MClient copy() {  
97 - return new LwM2MClient(this.endPoint, this.identity, this.securityInfo, this.credentialsResponse, this.profileUuid, this.sessionUuid); 88 + public LwM2mClient copy() {
  89 + return new LwM2mClient(this.endpoint, this.identity, this.securityInfo, this.credentialsResponse, this.profileId, this.sessionId);
98 } 90 }
99 } 91 }
100 92
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.transport.lwm2m.server.client;
  17 +
  18 +import org.eclipse.leshan.server.registration.Registration;
  19 +import org.thingsboard.server.common.data.DeviceProfile;
  20 +import org.thingsboard.server.gen.transport.TransportProtos;
  21 +
  22 +import java.util.Map;
  23 +import java.util.UUID;
  24 +
  25 +public interface LwM2mClientContext {
  26 +
  27 + void delRemoveSessionAndListener(String registrationId);
  28 +
  29 + LwM2mClient getLwM2MClient(String endPoint, String identity);
  30 +
  31 + LwM2mClient getLwM2MClient(TransportProtos.SessionInfoProto sessionInfo);
  32 +
  33 + LwM2mClient getLwM2mClient(UUID sessionId);
  34 +
  35 + LwM2mClient getLwM2mClientWithReg(Registration registration, String registrationId);
  36 +
  37 + LwM2mClient updateInSessionsLwM2MClient(Registration registration);
  38 +
  39 + LwM2mClient addLwM2mClientToSession(String identity);
  40 +
  41 + Registration getRegistration(String registrationId);
  42 +
  43 + Map<String, LwM2mClient> getLwM2mClients();
  44 +
  45 + Map<UUID, LwM2mClientProfile> getProfiles();
  46 +
  47 + LwM2mClientProfile getProfile(UUID profileUuId);
  48 +
  49 + LwM2mClientProfile getProfile(Registration registration);
  50 +
  51 + Map<UUID, LwM2mClientProfile> setProfiles(Map<UUID, LwM2mClientProfile> profiles);
  52 +
  53 + boolean addUpdateProfileParameters(DeviceProfile deviceProfile);
  54 +}
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.transport.lwm2m.server.client;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.eclipse.leshan.server.registration.Registration;
  20 +import org.eclipse.leshan.server.security.EditableSecurityStore;
  21 +import org.springframework.stereotype.Service;
  22 +import org.thingsboard.server.common.data.DeviceProfile;
  23 +import org.thingsboard.server.gen.transport.TransportProtos;
  24 +import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
  25 +import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
  26 +import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
  27 +import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore;
  28 +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler;
  29 +import org.thingsboard.server.transport.lwm2m.utils.TypeServer;
  30 +
  31 +import java.util.Map;
  32 +import java.util.UUID;
  33 +import java.util.concurrent.ConcurrentHashMap;
  34 +
  35 +import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC;
  36 +
  37 +@Service
  38 +@TbLwM2mTransportComponent
  39 +public class LwM2mClientContextImpl implements LwM2mClientContext {
  40 + private static final boolean INFOS_ARE_COMPROMISED = false;
  41 +
  42 + private final Map<String /** registrationId */, LwM2mClient> lwM2mClients = new ConcurrentHashMap<>();
  43 + private Map<UUID /** profileUUid */, LwM2mClientProfile> profiles = new ConcurrentHashMap<>();
  44 +
  45 + private final LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator;
  46 +
  47 + private final EditableSecurityStore securityStore;
  48 +
  49 + public LwM2mClientContextImpl(LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator, EditableSecurityStore securityStore) {
  50 + this.lwM2MCredentialsSecurityInfoValidator = lwM2MCredentialsSecurityInfoValidator;
  51 + this.securityStore = securityStore;
  52 + }
  53 +
  54 + public void delRemoveSessionAndListener(String registrationId) {
  55 + LwM2mClient lwM2MClient = lwM2mClients.get(registrationId);
  56 + if (lwM2MClient != null) {
  57 + securityStore.remove(lwM2MClient.getEndpoint(), INFOS_ARE_COMPROMISED);
  58 + lwM2mClients.remove(registrationId);
  59 + }
  60 + }
  61 +
  62 + @Override
  63 + public LwM2mClient getLwM2MClient(String endPoint, String identity) {
  64 + Map.Entry<String, LwM2mClient> modelClients = endPoint != null ?
  65 + this.lwM2mClients.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndpoint())).findAny().orElse(null) :
  66 + this.lwM2mClients.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).findAny().orElse(null);
  67 + return modelClients != null ? modelClients.getValue() : null;
  68 + }
  69 +
  70 + @Override
  71 + public LwM2mClient getLwM2MClient(TransportProtos.SessionInfoProto sessionInfo) {
  72 + return getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
  73 + }
  74 +
  75 + @Override
  76 + public LwM2mClient getLwM2mClient(UUID sessionId) {
  77 + return lwM2mClients.values().stream().filter(c -> c.getSessionId().equals(sessionId)).findAny().get();
  78 + }
  79 +
  80 + @Override
  81 + public LwM2mClient getLwM2mClientWithReg(Registration registration, String registrationId) {
  82 + LwM2mClient client = registrationId != null ?
  83 + this.lwM2mClients.get(registrationId) :
  84 + this.lwM2mClients.containsKey(registration.getId()) ?
  85 + this.lwM2mClients.get(registration.getId()) :
  86 + this.lwM2mClients.get(registration.getEndpoint());
  87 + return client != null ? client : updateInSessionsLwM2MClient(registration);
  88 + }
  89 +
  90 + @Override
  91 + public LwM2mClient updateInSessionsLwM2MClient(Registration registration) {
  92 + if (this.lwM2mClients.get(registration.getEndpoint()) == null) {
  93 + addLwM2mClientToSession(registration.getEndpoint());
  94 + }
  95 + LwM2mClient lwM2MClient = lwM2mClients.get(registration.getEndpoint());
  96 + lwM2MClient.setRegistration(registration);
  97 + this.lwM2mClients.remove(registration.getEndpoint());
  98 + this.lwM2mClients.put(registration.getId(), lwM2MClient);
  99 + return lwM2MClient;
  100 + }
  101 +
  102 + public Registration getRegistration(String registrationId) {
  103 + return this.lwM2mClients.get(registrationId).getRegistration();
  104 + }
  105 +
  106 + /**
  107 + * Add new LwM2MClient to session
  108 + * @param identity-
  109 + * @return SecurityInfo. If error - SecurityInfoError
  110 + * and log:
  111 + * - FORBIDDEN - if there is no authorization
  112 + * - profileUuid - if the device does not have a profile
  113 + * - device - if the thingsboard does not have a device with a name equal to the identity
  114 + */
  115 + @Override
  116 + public LwM2mClient addLwM2mClientToSession(String identity) {
  117 + ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, TypeServer.CLIENT);
  118 + if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
  119 + UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null;
  120 + LwM2mClient client;
  121 + if (store.getSecurityInfo() != null && profileUuid != null) {
  122 + String endpoint = store.getSecurityInfo().getEndpoint();
  123 + client = new LwM2mClient(endpoint, store.getSecurityInfo().getIdentity(), store.getSecurityInfo(), store.getMsg(), profileUuid, UUID.randomUUID());
  124 + lwM2mClients.put(endpoint, client);
  125 + } else if (store.getSecurityMode() == NO_SEC.code && profileUuid != null) {
  126 + client = new LwM2mClient(identity, null, null, store.getMsg(), profileUuid, UUID.randomUUID());
  127 + lwM2mClients.put(identity, client);
  128 + } else {
  129 + throw new RuntimeException(String.format("Registration failed: FORBIDDEN/profileUuid/device %s , endpointId: %s [PSK]", profileUuid, identity));
  130 + }
  131 + return client;
  132 + } else {
  133 + throw new RuntimeException(String.format("Registration failed: FORBIDDEN, endpointId: %s", identity));
  134 + }
  135 + }
  136 +
  137 + @Override
  138 + public Map<String, LwM2mClient> getLwM2mClients() {
  139 + return lwM2mClients;
  140 + }
  141 +
  142 + @Override
  143 + public Map<UUID, LwM2mClientProfile> getProfiles() {
  144 + return profiles;
  145 + }
  146 +
  147 + @Override
  148 + public LwM2mClientProfile getProfile(UUID profileId) {
  149 + return profiles.get(profileId);
  150 + }
  151 +
  152 + @Override
  153 + public LwM2mClientProfile getProfile(Registration registration) {
  154 + return this.getProfiles().get(getLwM2mClientWithReg(registration, null).getProfileId());
  155 + }
  156 +
  157 + @Override
  158 + public Map<UUID, LwM2mClientProfile> setProfiles(Map<UUID, LwM2mClientProfile> profiles) {
  159 + return this.profiles = profiles;
  160 + }
  161 +
  162 + @Override
  163 + public boolean addUpdateProfileParameters(DeviceProfile deviceProfile) {
  164 + LwM2mClientProfile lwM2MClientProfile = LwM2mTransportHandler.getLwM2MClientProfileFromThingsboard(deviceProfile);
  165 + if (lwM2MClientProfile != null) {
  166 + profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile);
  167 + return true;
  168 + }
  169 + return false;
  170 + }
  171 +}
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientProfile.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2MClientProfile.java
@@ -20,7 +20,7 @@ import com.google.gson.JsonObject; @@ -20,7 +20,7 @@ import com.google.gson.JsonObject;
20 import lombok.Data; 20 import lombok.Data;
21 21
22 @Data 22 @Data
23 -public class LwM2MClientProfile { 23 +public class LwM2mClientProfile {
24 /** 24 /**
25 * {"clientLwM2mSettings": { 25 * {"clientLwM2mSettings": {
26 * clientUpdateValueAfterConnect: false; 26 * clientUpdateValueAfterConnect: false;
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/LwM2mInMemorySecurityStore.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/secure/LwM2mInMemorySecurityStore.java
@@ -13,30 +13,26 @@ @@ -13,30 +13,26 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.transport.lwm2m.server.secure; 16 +package org.thingsboard.server.transport.lwm2m.server.store;
17 17
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.eclipse.leshan.core.util.Hex; 19 import org.eclipse.leshan.core.util.Hex;
20 -import org.eclipse.leshan.server.californium.LeshanServer;  
21 import org.eclipse.leshan.server.registration.Registration; 20 import org.eclipse.leshan.server.registration.Registration;
22 import org.eclipse.leshan.server.security.InMemorySecurityStore; 21 import org.eclipse.leshan.server.security.InMemorySecurityStore;
23 import org.eclipse.leshan.server.security.SecurityInfo; 22 import org.eclipse.leshan.server.security.SecurityInfo;
24 import org.eclipse.leshan.server.security.SecurityStoreListener; 23 import org.eclipse.leshan.server.security.SecurityStoreListener;
25 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
26 -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;  
27 -import org.springframework.stereotype.Service;  
28 import org.thingsboard.server.common.data.DeviceProfile; 25 import org.thingsboard.server.common.data.DeviceProfile;
29 import org.thingsboard.server.gen.transport.TransportProtos; 26 import org.thingsboard.server.gen.transport.TransportProtos;
30 import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; 27 import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
31 import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; 28 import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
32 import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; 29 import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore;
33 -import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler;  
34 -import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClient;  
35 -import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClientProfile; 30 +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler;
  31 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
  32 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile;
36 import org.thingsboard.server.transport.lwm2m.utils.TypeServer; 33 import org.thingsboard.server.transport.lwm2m.utils.TypeServer;
37 34
38 import java.util.Collection; 35 import java.util.Collection;
39 -import java.util.Collections;  
40 import java.util.List; 36 import java.util.List;
41 import java.util.Map; 37 import java.util.Map;
42 import java.util.UUID; 38 import java.util.UUID;
@@ -49,8 +45,9 @@ import java.util.stream.Collectors; @@ -49,8 +45,9 @@ import java.util.stream.Collectors;
49 import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC; 45 import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC;
50 46
51 @Slf4j 47 @Slf4j
52 -@Service("LwM2mInMemorySecurityStore")  
53 -@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' )|| ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") 48 +//@Service("LwM2mInMemorySecurityStore")
  49 +//@TbLwM2mTransportComponent
  50 +@Deprecated
54 public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { 51 public class LwM2mInMemorySecurityStore extends InMemorySecurityStore {
55 private static final boolean INFOS_ARE_COMPROMISED = false; 52 private static final boolean INFOS_ARE_COMPROMISED = false;
56 53
@@ -58,8 +55,8 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { @@ -58,8 +55,8 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore {
58 private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); 55 private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
59 private final Lock readLock = readWriteLock.readLock(); 56 private final Lock readLock = readWriteLock.readLock();
60 private final Lock writeLock = readWriteLock.writeLock(); 57 private final Lock writeLock = readWriteLock.writeLock();
61 - private final Map<String /** registrationId */, LwM2MClient> sessions = new ConcurrentHashMap<>();  
62 - private Map<UUID /** profileUUid */, LwM2MClientProfile> profiles = new ConcurrentHashMap<>(); 58 + private final Map<String /** registrationId */, LwM2mClient> sessions = new ConcurrentHashMap<>();
  59 + private Map<UUID /** profileUUid */, LwM2mClientProfile> profiles = new ConcurrentHashMap<>();
63 private SecurityStoreListener listener; 60 private SecurityStoreListener listener;
64 61
65 @Autowired 62 @Autowired
@@ -102,7 +99,7 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { @@ -102,7 +99,7 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore {
102 public Collection<SecurityInfo> getAll() { 99 public Collection<SecurityInfo> getAll() {
103 readLock.lock(); 100 readLock.lock();
104 try { 101 try {
105 - return Collections.unmodifiableCollection(this.sessions.values().stream().map(LwM2MClient::getSecurityInfo).collect(Collectors.toList())); 102 + return this.sessions.values().stream().map(LwM2mClient::getSecurityInfo).collect(Collectors.toUnmodifiableList());
106 } finally { 103 } finally {
107 readLock.unlock(); 104 readLock.unlock();
108 } 105 }
@@ -115,7 +112,7 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { @@ -115,7 +112,7 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore {
115 public void delRemoveSessionAndListener(String registrationId) { 112 public void delRemoveSessionAndListener(String registrationId) {
116 writeLock.lock(); 113 writeLock.lock();
117 try { 114 try {
118 - LwM2MClient lwM2MClient = (sessions.get(registrationId) != null) ? sessions.get(registrationId) : null; 115 + LwM2mClient lwM2MClient = (sessions.get(registrationId) != null) ? sessions.get(registrationId) : null;
119 if (lwM2MClient != null) { 116 if (lwM2MClient != null) {
120 if (listener != null) { 117 if (listener != null) {
121 listener.securityInfoRemoved(INFOS_ARE_COMPROMISED, lwM2MClient.getSecurityInfo()); 118 listener.securityInfoRemoved(INFOS_ARE_COMPROMISED, lwM2MClient.getSecurityInfo());
@@ -132,14 +129,14 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { @@ -132,14 +129,14 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore {
132 this.listener = listener; 129 this.listener = listener;
133 } 130 }
134 131
135 - public LwM2MClient getLwM2MClient(String endPoint, String identity) {  
136 - Map.Entry<String, LwM2MClient> modelClients = (endPoint != null) ?  
137 - this.sessions.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndPoint())).findAny().orElse(null) : 132 + public LwM2mClient getLwM2MClient(String endPoint, String identity) {
  133 + Map.Entry<String, LwM2mClient> modelClients = endPoint != null ?
  134 + this.sessions.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndpoint())).findAny().orElse(null) :
138 this.sessions.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).findAny().orElse(null); 135 this.sessions.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).findAny().orElse(null);
139 - return (modelClients != null) ? modelClients.getValue() : null; 136 + return modelClients != null ? modelClients.getValue() : null;
140 } 137 }
141 138
142 - public LwM2MClient getLwM2MClientWithReg(Registration registration, String registrationId) { 139 + public LwM2mClient getLwM2MClientWithReg(Registration registration, String registrationId) {
143 return registrationId != null ? 140 return registrationId != null ?
144 this.sessions.get(registrationId) : 141 this.sessions.get(registrationId) :
145 this.sessions.containsKey(registration.getId()) ? 142 this.sessions.containsKey(registration.getId()) ?
@@ -147,28 +144,25 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { @@ -147,28 +144,25 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore {
147 this.sessions.get(registration.getEndpoint()); 144 this.sessions.get(registration.getEndpoint());
148 } 145 }
149 146
150 - public LwM2MClient getLwM2MClient(TransportProtos.SessionInfoProto sessionInfo) { 147 + public LwM2mClient getLwM2MClient(TransportProtos.SessionInfoProto sessionInfo) {
151 return this.getSession(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).entrySet().iterator().next().getValue(); 148 return this.getSession(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).entrySet().iterator().next().getValue();
152 -  
153 } 149 }
154 150
155 /** 151 /**
156 * Update in sessions (LwM2MClient for key registration_Id) after starting registration LwM2MClient in LwM2MTransportServiceImpl 152 * Update in sessions (LwM2MClient for key registration_Id) after starting registration LwM2MClient in LwM2MTransportServiceImpl
157 * Remove from sessions LwM2MClient with key registration_Endpoint 153 * Remove from sessions LwM2MClient with key registration_Endpoint
158 - * @param lwServer -  
159 * @param registration - 154 * @param registration -
160 * @return LwM2MClient after adding it to session 155 * @return LwM2MClient after adding it to session
161 */ 156 */
162 - public LwM2MClient updateInSessionsLwM2MClient(LeshanServer lwServer, Registration registration) { 157 + public LwM2mClient updateInSessionsLwM2MClient(Registration registration) {
163 writeLock.lock(); 158 writeLock.lock();
164 try { 159 try {
165 if (this.sessions.get(registration.getEndpoint()) == null) { 160 if (this.sessions.get(registration.getEndpoint()) == null) {
166 this.addLwM2MClientToSession(registration.getEndpoint()); 161 this.addLwM2MClientToSession(registration.getEndpoint());
167 } 162 }
168 - LwM2MClient lwM2MClient = this.sessions.get(registration.getEndpoint());  
169 - lwM2MClient.setLwServer(lwServer); 163 + LwM2mClient lwM2MClient = this.sessions.get(registration.getEndpoint());
170 lwM2MClient.setRegistration(registration); 164 lwM2MClient.setRegistration(registration);
171 - lwM2MClient.getAttributes().putAll(registration.getAdditionalRegistrationAttributes()); 165 +// lwM2MClient.getAttributes().putAll(registration.getAdditionalRegistrationAttributes());
172 this.sessions.remove(registration.getEndpoint()); 166 this.sessions.remove(registration.getEndpoint());
173 this.sessions.put(registration.getId(), lwM2MClient); 167 this.sessions.put(registration.getId(), lwM2MClient);
174 return lwM2MClient; 168 return lwM2MClient;
@@ -179,7 +173,7 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { @@ -179,7 +173,7 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore {
179 173
180 private String getRegistrationId(String endPoint, String identity) { 174 private String getRegistrationId(String endPoint, String identity) {
181 List<String> registrationIds = (endPoint != null) ? 175 List<String> registrationIds = (endPoint != null) ?
182 - this.sessions.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndPoint())).map(Map.Entry::getKey).collect(Collectors.toList()) : 176 + this.sessions.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndpoint())).map(Map.Entry::getKey).collect(Collectors.toList()) :
183 this.sessions.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).map(Map.Entry::getKey).collect(Collectors.toList()); 177 this.sessions.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).map(Map.Entry::getKey).collect(Collectors.toList());
184 return (registrationIds != null && registrationIds.size() > 0) ? registrationIds.get(0) : null; 178 return (registrationIds != null && registrationIds.size() > 0) ? registrationIds.get(0) : null;
185 } 179 }
@@ -203,49 +197,51 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { @@ -203,49 +197,51 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore {
203 UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null; 197 UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null;
204 if (store.getSecurityInfo() != null && profileUuid != null) { 198 if (store.getSecurityInfo() != null && profileUuid != null) {
205 String endpoint = store.getSecurityInfo().getEndpoint(); 199 String endpoint = store.getSecurityInfo().getEndpoint();
206 - sessions.put(endpoint, new LwM2MClient(endpoint, store.getSecurityInfo().getIdentity(), store.getSecurityInfo(), store.getMsg(), profileUuid, UUID.randomUUID())); 200 + sessions.put(endpoint, new LwM2mClient(endpoint, store.getSecurityInfo().getIdentity(), store.getSecurityInfo(), store.getMsg(), profileUuid, UUID.randomUUID()));
207 } else if (store.getSecurityMode() == NO_SEC.code && profileUuid != null) { 201 } else if (store.getSecurityMode() == NO_SEC.code && profileUuid != null) {
208 - sessions.put(identity, new LwM2MClient(identity, null, null, store.getMsg(), profileUuid, UUID.randomUUID())); 202 + sessions.put(identity, new LwM2mClient(identity, null, null, store.getMsg(), profileUuid, UUID.randomUUID()));
209 } else { 203 } else {
210 - log.error("Registration failed: FORBIDDEN/profileUuid/device [{}] , endpointId: [{}]", profileUuid, identity);  
211 - /**  
212 - * Return Error securityInfo  
213 - */  
214 - byte[] preSharedKey = Hex.decodeHex("0A0B".toCharArray());  
215 - SecurityInfo infoError = SecurityInfo.newPreSharedKeyInfo("error", "error_identity", preSharedKey);  
216 - return infoError;  
217 - } 204 + log.error("Registration failed: FORBIDDEN/profileUuid/device [{}] , endpointId: [{}]", profileUuid, identity);
  205 + /**
  206 + * Return Error securityInfo
  207 + */
  208 + byte[] preSharedKey = Hex.decodeHex("0A0B".toCharArray());
  209 + SecurityInfo infoError = SecurityInfo.newPreSharedKeyInfo("error", "error_identity", preSharedKey);
  210 + return infoError;
218 } 211 }
219 - return store.getSecurityInfo(); 212 + }
  213 + return store.getSecurityInfo();
220 } 214 }
221 215
222 - public Map<String, LwM2MClient> getSession(UUID sessionUuId) {  
223 - return this.sessions.entrySet().stream().filter(e -> e.getValue().getSessionUuid().equals(sessionUuId)).collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue())); 216 + public Map<String, LwM2mClient> getSession(UUID sessionUuId) {
  217 + return this.sessions.entrySet().stream()
  218 + .filter(e -> e.getValue().getSessionId().equals(sessionUuId))
  219 + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
224 } 220 }
225 221
226 - public Map<String, LwM2MClient> getSessions() { 222 + public Map<String, LwM2mClient> getSessions() {
227 return this.sessions; 223 return this.sessions;
228 } 224 }
229 225
230 - public Map<UUID, LwM2MClientProfile> getProfiles() { 226 + public Map<UUID, LwM2mClientProfile> getProfiles() {
231 return this.profiles; 227 return this.profiles;
232 } 228 }
233 229
234 - public LwM2MClientProfile getProfile(UUID profileUuId) { 230 + public LwM2mClientProfile getProfile(UUID profileUuId) {
235 return this.profiles.get(profileUuId); 231 return this.profiles.get(profileUuId);
236 } 232 }
237 233
238 - public LwM2MClientProfile getProfile(String registrationId) {  
239 - UUID profileUUid = this.getSessions().get(registrationId).getProfileUuid(); 234 + public LwM2mClientProfile getProfile(String registrationId) {
  235 + UUID profileUUid = this.getSessions().get(registrationId).getProfileId();
240 return this.getProfiles().get(profileUUid); 236 return this.getProfiles().get(profileUUid);
241 } 237 }
242 238
243 - public Map<UUID, LwM2MClientProfile> setProfiles(Map<UUID, LwM2MClientProfile> profiles) { 239 + public Map<UUID, LwM2mClientProfile> setProfiles(Map<UUID, LwM2mClientProfile> profiles) {
244 return this.profiles = profiles; 240 return this.profiles = profiles;
245 } 241 }
246 242
247 public boolean addUpdateProfileParameters(DeviceProfile deviceProfile) { 243 public boolean addUpdateProfileParameters(DeviceProfile deviceProfile) {
248 - LwM2MClientProfile lwM2MClientProfile = LwM2MTransportHandler.getLwM2MClientProfileFromThingsboard(deviceProfile); 244 + LwM2mClientProfile lwM2MClientProfile = LwM2mTransportHandler.getLwM2MClientProfileFromThingsboard(deviceProfile);
249 if (lwM2MClientProfile != null) { 245 if (lwM2MClientProfile != null) {
250 profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile); 246 profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile);
251 return true; 247 return true;
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.transport.lwm2m.server.store;
  17 +
  18 +import org.eclipse.californium.core.coap.Token;
  19 +import org.eclipse.californium.core.observe.ObservationStoreException;
  20 +import org.eclipse.californium.elements.EndpointContext;
  21 +import org.eclipse.leshan.core.observation.Observation;
  22 +import org.eclipse.leshan.core.util.NamedThreadFactory;
  23 +import org.eclipse.leshan.core.util.Validate;
  24 +import org.eclipse.leshan.server.Destroyable;
  25 +import org.eclipse.leshan.server.Startable;
  26 +import org.eclipse.leshan.server.Stoppable;
  27 +import org.eclipse.leshan.server.californium.observation.ObserveUtil;
  28 +import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore;
  29 +import org.eclipse.leshan.server.redis.JedisLock;
  30 +import org.eclipse.leshan.server.redis.RedisRegistrationStore;
  31 +import org.eclipse.leshan.server.redis.SingleInstanceJedisLock;
  32 +import org.eclipse.leshan.server.redis.serialization.ObservationSerDes;
  33 +import org.eclipse.leshan.server.redis.serialization.RegistrationSerDes;
  34 +import org.eclipse.leshan.server.registration.Deregistration;
  35 +import org.eclipse.leshan.server.registration.ExpirationListener;
  36 +import org.eclipse.leshan.server.registration.Registration;
  37 +import org.eclipse.leshan.server.registration.RegistrationUpdate;
  38 +import org.eclipse.leshan.server.registration.UpdatedRegistration;
  39 +import org.slf4j.Logger;
  40 +import org.slf4j.LoggerFactory;
  41 +import org.springframework.data.redis.connection.RedisConnectionFactory;
  42 +import redis.clients.jedis.Jedis;
  43 +import redis.clients.jedis.ScanParams;
  44 +import redis.clients.jedis.ScanResult;
  45 +import redis.clients.jedis.Transaction;
  46 +
  47 +import java.net.InetSocketAddress;
  48 +import java.util.ArrayList;
  49 +import java.util.Arrays;
  50 +import java.util.Collection;
  51 +import java.util.Collections;
  52 +import java.util.Iterator;
  53 +import java.util.List;
  54 +import java.util.NoSuchElementException;
  55 +import java.util.Set;
  56 +import java.util.concurrent.Executors;
  57 +import java.util.concurrent.ScheduledExecutorService;
  58 +import java.util.concurrent.ScheduledFuture;
  59 +import java.util.concurrent.TimeUnit;
  60 +
  61 +import static java.nio.charset.StandardCharsets.UTF_8;
  62 +
  63 +public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationStore, Startable, Stoppable, Destroyable {
  64 + /** Default time in seconds between 2 cleaning tasks (used to remove expired registration). */
  65 + public static final long DEFAULT_CLEAN_PERIOD = 60;
  66 + public static final int DEFAULT_CLEAN_LIMIT = 500;
  67 + /** Defaut Extra time for registration lifetime in seconds */
  68 + public static final long DEFAULT_GRACE_PERIOD = 0;
  69 +
  70 + private static final Logger LOG = LoggerFactory.getLogger(RedisRegistrationStore.class);
  71 +
  72 + // Redis key prefixes
  73 + private static final String REG_EP = "REG:EP:"; // (Endpoint => Registration)
  74 + private static final String REG_EP_REGID_IDX = "EP:REGID:"; // secondary index key (Registration ID => Endpoint)
  75 + private static final String REG_EP_ADDR_IDX = "EP:ADDR:"; // secondary index key (Socket Address => Endpoint)
  76 + private static final String LOCK_EP = "LOCK:EP:";
  77 + private static final byte[] OBS_TKN = "OBS:TKN:".getBytes(UTF_8);
  78 + private static final String OBS_TKNS_REGID_IDX = "TKNS:REGID:"; // secondary index (token list by registration)
  79 + private static final byte[] EXP_EP = "EXP:EP".getBytes(UTF_8); // a sorted set used for registration expiration
  80 + // (expiration date, Endpoint)
  81 +
  82 + private final RedisConnectionFactory connectionFactory;
  83 +
  84 + // Listener use to notify when a registration expires
  85 + private ExpirationListener expirationListener;
  86 +
  87 + private final ScheduledExecutorService schedExecutor;
  88 + private ScheduledFuture<?> cleanerTask;
  89 + private boolean started = false;
  90 +
  91 + private final long cleanPeriod; // in seconds
  92 + private final int cleanLimit; // maximum number to clean in a clean period
  93 + private final long gracePeriod; // in seconds
  94 +
  95 + private final JedisLock lock;
  96 +
  97 + public TbLwM2mRedisRegistrationStore(RedisConnectionFactory connectionFactory) {
  98 + this(connectionFactory, DEFAULT_CLEAN_PERIOD, DEFAULT_GRACE_PERIOD, DEFAULT_CLEAN_LIMIT); // default clean period 60s
  99 + }
  100 +
  101 + public TbLwM2mRedisRegistrationStore(RedisConnectionFactory connectionFactory, long cleanPeriodInSec, long lifetimeGracePeriodInSec, int cleanLimit) {
  102 + this(connectionFactory, Executors.newScheduledThreadPool(1,
  103 + new NamedThreadFactory(String.format("RedisRegistrationStore Cleaner (%ds)", cleanPeriodInSec))),
  104 + cleanPeriodInSec, lifetimeGracePeriodInSec, cleanLimit);
  105 + }
  106 +
  107 + public TbLwM2mRedisRegistrationStore(RedisConnectionFactory connectionFactory, ScheduledExecutorService schedExecutor, long cleanPeriodInSec,
  108 + long lifetimeGracePeriodInSec, int cleanLimit) {
  109 + this(connectionFactory, schedExecutor, cleanPeriodInSec, lifetimeGracePeriodInSec, cleanLimit, new SingleInstanceJedisLock());
  110 + }
  111 +
  112 + /**
  113 + * @since 1.1
  114 + */
  115 + public TbLwM2mRedisRegistrationStore(RedisConnectionFactory connectionFactory, ScheduledExecutorService schedExecutor, long cleanPeriodInSec,
  116 + long lifetimeGracePeriodInSec, int cleanLimit, JedisLock redisLock) {
  117 + this.connectionFactory = connectionFactory;
  118 + this.schedExecutor = schedExecutor;
  119 + this.cleanPeriod = cleanPeriodInSec;
  120 + this.cleanLimit = cleanLimit;
  121 + this.gracePeriod = lifetimeGracePeriodInSec;
  122 + this.lock = redisLock;
  123 + }
  124 +
  125 + /* *************** Redis Key utility function **************** */
  126 +
  127 + private byte[] toKey(byte[] prefix, byte[] key) {
  128 + byte[] result = new byte[prefix.length + key.length];
  129 + System.arraycopy(prefix, 0, result, 0, prefix.length);
  130 + System.arraycopy(key, 0, result, prefix.length, key.length);
  131 + return result;
  132 + }
  133 +
  134 + private byte[] toKey(String prefix, String registrationID) {
  135 + return (prefix + registrationID).getBytes();
  136 + }
  137 +
  138 + private byte[] toLockKey(String endpoint) {
  139 + return toKey(LOCK_EP, endpoint);
  140 + }
  141 +
  142 + private byte[] toLockKey(byte[] endpoint) {
  143 + return toKey(LOCK_EP.getBytes(UTF_8), endpoint);
  144 + }
  145 +
  146 + /* *************** Leshan Registration API **************** */
  147 +
  148 + @Override
  149 + public Deregistration addRegistration(Registration registration) {
  150 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  151 + byte[] lockValue = null;
  152 + byte[] lockKey = toLockKey(registration.getEndpoint());
  153 +
  154 + try {
  155 + lockValue = lock.acquire(j, lockKey);
  156 +
  157 + // add registration
  158 + byte[] k = toEndpointKey(registration.getEndpoint());
  159 + byte[] old = j.getSet(k, serializeReg(registration));
  160 +
  161 + // add registration: secondary indexes
  162 + byte[] regid_idx = toRegIdKey(registration.getId());
  163 + j.set(regid_idx, registration.getEndpoint().getBytes(UTF_8));
  164 + byte[] addr_idx = toRegAddrKey(registration.getSocketAddress());
  165 + j.set(addr_idx, registration.getEndpoint().getBytes(UTF_8));
  166 +
  167 + // Add or update expiration
  168 + addOrUpdateExpiration(j, registration);
  169 +
  170 + if (old != null) {
  171 + Registration oldRegistration = deserializeReg(old);
  172 + // remove old secondary index
  173 + if (!registration.getId().equals(oldRegistration.getId()))
  174 + j.del(toRegIdKey(oldRegistration.getId()));
  175 + if (!oldRegistration.getSocketAddress().equals(registration.getSocketAddress())) {
  176 + removeAddrIndex(j, oldRegistration);
  177 + }
  178 + // remove old observation
  179 + Collection<Observation> obsRemoved = unsafeRemoveAllObservations(j, oldRegistration.getId());
  180 +
  181 + return new Deregistration(oldRegistration, obsRemoved);
  182 + }
  183 +
  184 + return null;
  185 + } finally {
  186 + lock.release(j, lockKey, lockValue);
  187 + }
  188 + }
  189 + }
  190 +
  191 + @Override
  192 + public UpdatedRegistration updateRegistration(RegistrationUpdate update) {
  193 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  194 +
  195 + // Fetch the registration ep by registration ID index
  196 + byte[] ep = j.get(toRegIdKey(update.getRegistrationId()));
  197 + if (ep == null) {
  198 + return null;
  199 + }
  200 +
  201 + byte[] lockValue = null;
  202 + byte[] lockKey = toLockKey(ep);
  203 + try {
  204 + lockValue = lock.acquire(j, lockKey);
  205 +
  206 + // Fetch the registration
  207 + byte[] data = j.get(toEndpointKey(ep));
  208 + if (data == null) {
  209 + return null;
  210 + }
  211 +
  212 + Registration r = deserializeReg(data);
  213 +
  214 + Registration updatedRegistration = update.update(r);
  215 +
  216 + // Store the new registration
  217 + j.set(toEndpointKey(updatedRegistration.getEndpoint()), serializeReg(updatedRegistration));
  218 +
  219 + // Add or update expiration
  220 + addOrUpdateExpiration(j, updatedRegistration);
  221 +
  222 + // Update secondary index :
  223 + // If registration is already associated to this address we don't care as we only want to keep the most
  224 + // recent binding.
  225 + byte[] addr_idx = toRegAddrKey(updatedRegistration.getSocketAddress());
  226 + j.set(addr_idx, updatedRegistration.getEndpoint().getBytes(UTF_8));
  227 + if (!r.getSocketAddress().equals(updatedRegistration.getSocketAddress())) {
  228 + removeAddrIndex(j, r);
  229 + }
  230 +
  231 + return new UpdatedRegistration(r, updatedRegistration);
  232 +
  233 + } finally {
  234 + lock.release(j, lockKey, lockValue);
  235 + }
  236 + }
  237 + }
  238 +
  239 + @Override
  240 + public Registration getRegistration(String registrationId) {
  241 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  242 + return getRegistration(j, registrationId);
  243 + }
  244 + }
  245 +
  246 + @Override
  247 + public Registration getRegistrationByEndpoint(String endpoint) {
  248 + Validate.notNull(endpoint);
  249 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  250 + byte[] data = j.get(toEndpointKey(endpoint));
  251 + if (data == null) {
  252 + return null;
  253 + }
  254 + return deserializeReg(data);
  255 + }
  256 + }
  257 +
  258 + @Override
  259 + public Registration getRegistrationByAdress(InetSocketAddress address) {
  260 + Validate.notNull(address);
  261 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  262 + byte[] ep = j.get(toRegAddrKey(address));
  263 + if (ep == null) {
  264 + return null;
  265 + }
  266 + byte[] data = j.get(toEndpointKey(ep));
  267 + if (data == null) {
  268 + return null;
  269 + }
  270 + return deserializeReg(data);
  271 + }
  272 + }
  273 +
  274 + @Override
  275 + public Iterator<Registration> getAllRegistrations() {
  276 + return new TbLwM2mRedisRegistrationStore.RedisIterator(connectionFactory, new ScanParams().match(REG_EP + "*").count(100));
  277 + }
  278 +
  279 + protected class RedisIterator implements Iterator<Registration> {
  280 +
  281 + private RedisConnectionFactory connectionFactory;
  282 + private ScanParams scanParams;
  283 +
  284 + private String cursor;
  285 + private List<Registration> scanResult;
  286 +
  287 + public RedisIterator(RedisConnectionFactory connectionFactory, ScanParams scanParams) {
  288 + this.connectionFactory = connectionFactory;
  289 + this.scanParams = scanParams;
  290 + // init scan result
  291 + scanNext("0");
  292 + }
  293 +
  294 + private void scanNext(String cursor) {
  295 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  296 + do {
  297 + ScanResult<byte[]> sr = j.scan(cursor.getBytes(), scanParams);
  298 +
  299 + this.scanResult = new ArrayList<>();
  300 + if (sr.getResult() != null && !sr.getResult().isEmpty()) {
  301 + for (byte[] value : j.mget(sr.getResult().toArray(new byte[][]{}))) {
  302 + this.scanResult.add(deserializeReg(value));
  303 + }
  304 + }
  305 +
  306 + cursor = sr.getCursor();
  307 + } while (!"0".equals(cursor) && scanResult.isEmpty());
  308 +
  309 + this.cursor = cursor;
  310 + }
  311 + }
  312 +
  313 + @Override
  314 + public boolean hasNext() {
  315 + if (!scanResult.isEmpty()) {
  316 + return true;
  317 + }
  318 + if ("0".equals(cursor)) {
  319 + // no more elements to scan
  320 + return false;
  321 + }
  322 +
  323 + // read more elements
  324 + scanNext(cursor);
  325 + return !scanResult.isEmpty();
  326 + }
  327 +
  328 + @Override
  329 + public Registration next() {
  330 + if (!hasNext()) {
  331 + throw new NoSuchElementException();
  332 + }
  333 + return scanResult.remove(0);
  334 + }
  335 +
  336 + @Override
  337 + public void remove() {
  338 + throw new UnsupportedOperationException();
  339 + }
  340 + }
  341 +
  342 + @Override
  343 + public Deregistration removeRegistration(String registrationId) {
  344 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  345 + return removeRegistration(j, registrationId, false);
  346 + }
  347 + }
  348 +
  349 + private Deregistration removeRegistration(Jedis j, String registrationId, boolean removeOnlyIfNotAlive) {
  350 + // fetch the client ep by registration ID index
  351 + byte[] ep = j.get(toRegIdKey(registrationId));
  352 + if (ep == null) {
  353 + return null;
  354 + }
  355 +
  356 + byte[] lockValue = null;
  357 + byte[] lockKey = toLockKey(ep);
  358 + try {
  359 + lockValue = lock.acquire(j, lockKey);
  360 +
  361 + // fetch the client
  362 + byte[] data = j.get(toEndpointKey(ep));
  363 + if (data == null) {
  364 + return null;
  365 + }
  366 + Registration r = deserializeReg(data);
  367 +
  368 + if (!removeOnlyIfNotAlive || !r.isAlive(gracePeriod)) {
  369 + long nbRemoved = j.del(toRegIdKey(r.getId()));
  370 + if (nbRemoved > 0) {
  371 + j.del(toEndpointKey(r.getEndpoint()));
  372 + Collection<Observation> obsRemoved = unsafeRemoveAllObservations(j, r.getId());
  373 + removeAddrIndex(j, r);
  374 + removeExpiration(j, r);
  375 + return new Deregistration(r, obsRemoved);
  376 + }
  377 + }
  378 + return null;
  379 + } finally {
  380 + lock.release(j, lockKey, lockValue);
  381 + }
  382 + }
  383 +
  384 + private void removeAddrIndex(Jedis j, Registration registration) {
  385 + // Watch the key to remove.
  386 + byte[] regAddrKey = toRegAddrKey(registration.getSocketAddress());
  387 + j.watch(regAddrKey);
  388 +
  389 + byte[] epFromAddr = j.get(regAddrKey);
  390 + // Delete the key if needed.
  391 + if (Arrays.equals(epFromAddr, registration.getEndpoint().getBytes(UTF_8))) {
  392 + // Try to delete the key
  393 + Transaction transaction = j.multi();
  394 + transaction.del(regAddrKey);
  395 + transaction.exec();
  396 + // if transaction failed this is not an issue as the socket address is probably reused and we don't neeed to
  397 + // delete it anymore.
  398 + } else {
  399 + // the key must not be deleted.
  400 + j.unwatch();
  401 + }
  402 + }
  403 +
  404 + private void addOrUpdateExpiration(Jedis j, Registration registration) {
  405 + j.zadd(EXP_EP, registration.getExpirationTimeStamp(gracePeriod), registration.getEndpoint().getBytes(UTF_8));
  406 + }
  407 +
  408 + private void removeExpiration(Jedis j, Registration registration) {
  409 + j.zrem(EXP_EP, registration.getEndpoint().getBytes(UTF_8));
  410 + }
  411 +
  412 + private byte[] toRegIdKey(String registrationId) {
  413 + return toKey(REG_EP_REGID_IDX, registrationId);
  414 + }
  415 +
  416 + private byte[] toRegAddrKey(InetSocketAddress addr) {
  417 + return toKey(REG_EP_ADDR_IDX, addr.getAddress().toString() + ":" + addr.getPort());
  418 + }
  419 +
  420 + private byte[] toEndpointKey(String endpoint) {
  421 + return toKey(REG_EP, endpoint);
  422 + }
  423 +
  424 + private byte[] toEndpointKey(byte[] endpoint) {
  425 + return toKey(REG_EP.getBytes(UTF_8), endpoint);
  426 + }
  427 +
  428 + private byte[] serializeReg(Registration registration) {
  429 + return RegistrationSerDes.bSerialize(registration);
  430 + }
  431 +
  432 + private Registration deserializeReg(byte[] data) {
  433 + return RegistrationSerDes.deserialize(data);
  434 + }
  435 +
  436 + /* *************** Leshan Observation API **************** */
  437 +
  438 + /*
  439 + * The observation is not persisted here, it is done by the Californium layer (in the implementation of the
  440 + * org.eclipse.californium.core.observe.ObservationStore#add method)
  441 + */
  442 + @Override
  443 + public Collection<Observation> addObservation(String registrationId, Observation observation) {
  444 +
  445 + List<Observation> removed = new ArrayList<>();
  446 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  447 +
  448 + // fetch the client ep by registration ID index
  449 + byte[] ep = j.get(toRegIdKey(registrationId));
  450 + if (ep == null) {
  451 + return null;
  452 + }
  453 +
  454 + byte[] lockValue = null;
  455 + byte[] lockKey = toLockKey(ep);
  456 +
  457 + try {
  458 + lockValue = lock.acquire(j, lockKey);
  459 +
  460 + // cancel existing observations for the same path and registration id.
  461 + for (Observation obs : getObservations(j, registrationId)) {
  462 + if (observation.getPath().equals(obs.getPath())
  463 + && !Arrays.equals(observation.getId(), obs.getId())) {
  464 + removed.add(obs);
  465 + unsafeRemoveObservation(j, registrationId, obs.getId());
  466 + }
  467 + }
  468 +
  469 + } finally {
  470 + lock.release(j, lockKey, lockValue);
  471 + }
  472 + }
  473 + return removed;
  474 + }
  475 +
  476 + @Override
  477 + public Observation removeObservation(String registrationId, byte[] observationId) {
  478 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  479 +
  480 + // fetch the client ep by registration ID index
  481 + byte[] ep = j.get(toRegIdKey(registrationId));
  482 + if (ep == null) {
  483 + return null;
  484 + }
  485 +
  486 + // remove observation
  487 + byte[] lockValue = null;
  488 + byte[] lockKey = toLockKey(ep);
  489 + try {
  490 + lockValue = lock.acquire(j, lockKey);
  491 +
  492 + Observation observation = build(get(new Token(observationId)));
  493 + if (observation != null && registrationId.equals(observation.getRegistrationId())) {
  494 + unsafeRemoveObservation(j, registrationId, observationId);
  495 + return observation;
  496 + }
  497 + return null;
  498 +
  499 + } finally {
  500 + lock.release(j, lockKey, lockValue);
  501 + }
  502 + }
  503 + }
  504 +
  505 + @Override
  506 + public Observation getObservation(String registrationId, byte[] observationId) {
  507 + return build(get(new Token(observationId)));
  508 + }
  509 +
  510 + @Override
  511 + public Collection<Observation> getObservations(String registrationId) {
  512 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  513 + return getObservations(j, registrationId);
  514 + }
  515 + }
  516 +
  517 + private Collection<Observation> getObservations(Jedis j, String registrationId) {
  518 + Collection<Observation> result = new ArrayList<>();
  519 + for (byte[] token : j.lrange(toKey(OBS_TKNS_REGID_IDX, registrationId), 0, -1)) {
  520 + byte[] obs = j.get(toKey(OBS_TKN, token));
  521 + if (obs != null) {
  522 + result.add(build(deserializeObs(obs)));
  523 + }
  524 + }
  525 + return result;
  526 + }
  527 +
  528 + @Override
  529 + public Collection<Observation> removeObservations(String registrationId) {
  530 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  531 + // check registration exists
  532 + Registration registration = getRegistration(j, registrationId);
  533 + if (registration == null)
  534 + return Collections.emptyList();
  535 +
  536 + // get endpoint and create lock
  537 + String endpoint = registration.getEndpoint();
  538 + byte[] lockValue = null;
  539 + byte[] lockKey = toKey(LOCK_EP, endpoint);
  540 + try {
  541 + lockValue = lock.acquire(j, lockKey);
  542 +
  543 + return unsafeRemoveAllObservations(j, registrationId);
  544 + } finally {
  545 + lock.release(j, lockKey, lockValue);
  546 + }
  547 + }
  548 + }
  549 +
  550 + /* *************** Californium ObservationStore API **************** */
  551 +
  552 + @Override
  553 + public org.eclipse.californium.core.observe.Observation putIfAbsent(Token token,
  554 + org.eclipse.californium.core.observe.Observation obs) throws ObservationStoreException {
  555 + return add(token, obs, true);
  556 + }
  557 +
  558 + @Override
  559 + public org.eclipse.californium.core.observe.Observation put(Token token,
  560 + org.eclipse.californium.core.observe.Observation obs) throws ObservationStoreException {
  561 + return add(token, obs, false);
  562 + }
  563 +
  564 + private org.eclipse.californium.core.observe.Observation add(Token token,
  565 + org.eclipse.californium.core.observe.Observation obs, boolean ifAbsent) throws ObservationStoreException {
  566 + String endpoint = ObserveUtil.validateCoapObservation(obs);
  567 + org.eclipse.californium.core.observe.Observation previousObservation = null;
  568 +
  569 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  570 + byte[] lockValue = null;
  571 + byte[] lockKey = toKey(LOCK_EP, endpoint);
  572 + try {
  573 + lockValue = lock.acquire(j, lockKey);
  574 +
  575 + String registrationId = ObserveUtil.extractRegistrationId(obs);
  576 + if (!j.exists(toRegIdKey(registrationId)))
  577 + throw new ObservationStoreException("no registration for this Id");
  578 + byte[] key = toKey(OBS_TKN, obs.getRequest().getToken().getBytes());
  579 + byte[] serializeObs = serializeObs(obs);
  580 + byte[] previousValue = null;
  581 + if (ifAbsent) {
  582 + previousValue = j.get(key);
  583 + if (previousValue == null || previousValue.length == 0) {
  584 + j.set(key, serializeObs);
  585 + } else {
  586 + return deserializeObs(previousValue);
  587 + }
  588 + } else {
  589 + previousValue = j.getSet(key, serializeObs);
  590 + }
  591 +
  592 + // secondary index to get the list by registrationId
  593 + j.lpush(toKey(OBS_TKNS_REGID_IDX, registrationId), obs.getRequest().getToken().getBytes());
  594 +
  595 + // log any collisions
  596 + if (previousValue != null && previousValue.length != 0) {
  597 + previousObservation = deserializeObs(previousValue);
  598 + LOG.warn(
  599 + "Token collision ? observation from request [{}] will be replaced by observation from request [{}] ",
  600 + previousObservation.getRequest(), obs.getRequest());
  601 + }
  602 + } finally {
  603 + lock.release(j, lockKey, lockValue);
  604 + }
  605 + }
  606 + return previousObservation;
  607 + }
  608 +
  609 + @Override
  610 + public void remove(Token token) {
  611 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  612 + byte[] tokenKey = toKey(OBS_TKN, token.getBytes());
  613 +
  614 + // fetch the observation by token
  615 + byte[] serializedObs = j.get(tokenKey);
  616 + if (serializedObs == null)
  617 + return;
  618 +
  619 + org.eclipse.californium.core.observe.Observation obs = deserializeObs(serializedObs);
  620 + String registrationId = ObserveUtil.extractRegistrationId(obs);
  621 + Registration registration = getRegistration(j, registrationId);
  622 + if (registration == null) {
  623 + LOG.warn("Unable to remove observation {}, registration {} does not exist anymore", obs.getRequest(),
  624 + registrationId);
  625 + return;
  626 + }
  627 +
  628 + String endpoint = registration.getEndpoint();
  629 + byte[] lockValue = null;
  630 + byte[] lockKey = toKey(LOCK_EP, endpoint);
  631 + try {
  632 + lockValue = lock.acquire(j, lockKey);
  633 +
  634 + unsafeRemoveObservation(j, registrationId, token.getBytes());
  635 + } finally {
  636 + lock.release(j, lockKey, lockValue);
  637 + }
  638 + }
  639 +
  640 + }
  641 +
  642 + @Override
  643 + public org.eclipse.californium.core.observe.Observation get(Token token) {
  644 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  645 + byte[] obs = j.get(toKey(OBS_TKN, token.getBytes()));
  646 + if (obs == null) {
  647 + return null;
  648 + } else {
  649 + return deserializeObs(obs);
  650 + }
  651 + }
  652 + }
  653 +
  654 + /* *************** Observation utility functions **************** */
  655 +
  656 + private Registration getRegistration(Jedis j, String registrationId) {
  657 + byte[] ep = j.get(toRegIdKey(registrationId));
  658 + if (ep == null) {
  659 + return null;
  660 + }
  661 + byte[] data = j.get(toEndpointKey(ep));
  662 + if (data == null) {
  663 + return null;
  664 + }
  665 +
  666 + return deserializeReg(data);
  667 + }
  668 +
  669 + private void unsafeRemoveObservation(Jedis j, String registrationId, byte[] observationId) {
  670 + if (j.del(toKey(OBS_TKN, observationId)) > 0L) {
  671 + j.lrem(toKey(OBS_TKNS_REGID_IDX, registrationId), 0, observationId);
  672 + }
  673 + }
  674 +
  675 + private Collection<Observation> unsafeRemoveAllObservations(Jedis j, String registrationId) {
  676 + Collection<Observation> removed = new ArrayList<>();
  677 + byte[] regIdKey = toKey(OBS_TKNS_REGID_IDX, registrationId);
  678 +
  679 + // fetch all observations by token
  680 + for (byte[] token : j.lrange(regIdKey, 0, -1)) {
  681 + byte[] obs = j.get(toKey(OBS_TKN, token));
  682 + if (obs != null) {
  683 + removed.add(build(deserializeObs(obs)));
  684 + }
  685 + j.del(toKey(OBS_TKN, token));
  686 + }
  687 + j.del(regIdKey);
  688 +
  689 + return removed;
  690 + }
  691 +
  692 + @Override
  693 + public void setContext(Token token, EndpointContext correlationContext) {
  694 + // In Leshan we always set context when we send the request, so this should not be needed to implement this.
  695 + }
  696 +
  697 + private byte[] serializeObs(org.eclipse.californium.core.observe.Observation obs) {
  698 + return ObservationSerDes.serialize(obs);
  699 + }
  700 +
  701 + private org.eclipse.californium.core.observe.Observation deserializeObs(byte[] data) {
  702 + return ObservationSerDes.deserialize(data);
  703 + }
  704 +
  705 + private Observation build(org.eclipse.californium.core.observe.Observation cfObs) {
  706 + if (cfObs == null)
  707 + return null;
  708 +
  709 + return ObserveUtil.createLwM2mObservation(cfObs.getRequest());
  710 + }
  711 +
  712 + /* *************** Expiration handling **************** */
  713 +
  714 + /**
  715 + * Start regular cleanup of dead registrations.
  716 + */
  717 + @Override
  718 + public synchronized void start() {
  719 + if (!started) {
  720 + started = true;
  721 + cleanerTask = schedExecutor.scheduleAtFixedRate(new TbLwM2mRedisRegistrationStore.Cleaner(), cleanPeriod, cleanPeriod, TimeUnit.SECONDS);
  722 + }
  723 + }
  724 +
  725 + /**
  726 + * Stop the underlying cleanup of the registrations.
  727 + */
  728 + @Override
  729 + public synchronized void stop() {
  730 + if (started) {
  731 + started = false;
  732 + if (cleanerTask != null) {
  733 + cleanerTask.cancel(false);
  734 + cleanerTask = null;
  735 + }
  736 + }
  737 + }
  738 +
  739 + /**
  740 + * Destroy "cleanup" scheduler.
  741 + */
  742 + @Override
  743 + public synchronized void destroy() {
  744 + started = false;
  745 + schedExecutor.shutdownNow();
  746 + try {
  747 + schedExecutor.awaitTermination(5, TimeUnit.SECONDS);
  748 + } catch (InterruptedException e) {
  749 + LOG.warn("Destroying RedisRegistrationStore was interrupted.", e);
  750 + }
  751 + }
  752 +
  753 + private class Cleaner implements Runnable {
  754 +
  755 + @Override
  756 + public void run() {
  757 +
  758 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  759 + Set<byte[]> endpointsExpired = j.zrangeByScore(EXP_EP, Double.NEGATIVE_INFINITY,
  760 + System.currentTimeMillis(), 0, cleanLimit);
  761 +
  762 + for (byte[] endpoint : endpointsExpired) {
  763 + Registration r = deserializeReg(j.get(toEndpointKey(endpoint)));
  764 + if (!r.isAlive(gracePeriod)) {
  765 + Deregistration dereg = removeRegistration(j, r.getId(), true);
  766 + if (dereg != null)
  767 + expirationListener.registrationExpired(dereg.getRegistration(), dereg.getObservations());
  768 + }
  769 + }
  770 + } catch (Exception e) {
  771 + LOG.warn("Unexpected Exception while registration cleaning", e);
  772 + }
  773 + }
  774 + }
  775 +
  776 + @Override
  777 + public void setExpirationListener(ExpirationListener listener) {
  778 + expirationListener = listener;
  779 + }
  780 +
  781 + @Override
  782 + public void setExecutor(ScheduledExecutorService executor) {
  783 + // TODO should we reuse californium executor ?
  784 + }
  785 +}
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.transport.lwm2m.server.store;
  17 +
  18 +import org.eclipse.leshan.server.redis.serialization.SecurityInfoSerDes;
  19 +import org.eclipse.leshan.server.security.EditableSecurityStore;
  20 +import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException;
  21 +import org.eclipse.leshan.server.security.SecurityInfo;
  22 +import org.eclipse.leshan.server.security.SecurityStoreListener;
  23 +import org.springframework.data.redis.connection.RedisConnectionFactory;
  24 +import org.springframework.stereotype.Service;
  25 +import redis.clients.jedis.Jedis;
  26 +import redis.clients.jedis.ScanParams;
  27 +import redis.clients.jedis.ScanResult;
  28 +
  29 +import java.util.Collection;
  30 +import java.util.LinkedList;
  31 +
  32 +@Service
  33 +public class TbLwM2mRedisSecurityStore implements EditableSecurityStore {
  34 + private static final String SEC_EP = "SEC#EP#";
  35 +
  36 + private static final String PSKID_SEC = "PSKID#SEC";
  37 +
  38 + private final RedisConnectionFactory connectionFactory;
  39 + private SecurityStoreListener listener;
  40 +
  41 + public TbLwM2mRedisSecurityStore(RedisConnectionFactory connectionFactory) {
  42 + this.connectionFactory = connectionFactory;
  43 + }
  44 +
  45 + @Override
  46 + public SecurityInfo getByEndpoint(String endpoint) {
  47 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  48 + byte[] data = j.get((SEC_EP + endpoint).getBytes());
  49 + if (data == null) {
  50 + return null;
  51 + } else {
  52 + return deserialize(data);
  53 + }
  54 + }
  55 + }
  56 +
  57 + @Override
  58 + public SecurityInfo getByIdentity(String identity) {
  59 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  60 + String ep = j.hget(PSKID_SEC, identity);
  61 + if (ep == null) {
  62 + return null;
  63 + } else {
  64 + byte[] data = j.get((SEC_EP + ep).getBytes());
  65 + if (data == null) {
  66 + return null;
  67 + } else {
  68 + return deserialize(data);
  69 + }
  70 + }
  71 + }
  72 + }
  73 +
  74 + @Override
  75 + public Collection<SecurityInfo> getAll() {
  76 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  77 + ScanParams params = new ScanParams().match(SEC_EP + "*").count(100);
  78 + Collection<SecurityInfo> list = new LinkedList<>();
  79 + String cursor = "0";
  80 + do {
  81 + ScanResult<byte[]> res = j.scan(cursor.getBytes(), params);
  82 + for (byte[] key : res.getResult()) {
  83 + byte[] element = j.get(key);
  84 + list.add(deserialize(element));
  85 + }
  86 + cursor = res.getCursor();
  87 + } while (!"0".equals(cursor));
  88 + return list;
  89 + }
  90 + }
  91 +
  92 + @Override
  93 + public SecurityInfo add(SecurityInfo info) throws NonUniqueSecurityInfoException {
  94 + byte[] data = serialize(info);
  95 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  96 + if (info.getIdentity() != null) {
  97 + // populate the secondary index (security info by PSK id)
  98 + String oldEndpoint = j.hget(PSKID_SEC, info.getIdentity());
  99 + if (oldEndpoint != null && !oldEndpoint.equals(info.getEndpoint())) {
  100 + throw new NonUniqueSecurityInfoException("PSK Identity " + info.getIdentity() + " is already used");
  101 + }
  102 + j.hset(PSKID_SEC.getBytes(), info.getIdentity().getBytes(), info.getEndpoint().getBytes());
  103 + }
  104 +
  105 + byte[] previousData = j.getSet((SEC_EP + info.getEndpoint()).getBytes(), data);
  106 + SecurityInfo previous = previousData == null ? null : deserialize(previousData);
  107 + String previousIdentity = previous == null ? null : previous.getIdentity();
  108 + if (previousIdentity != null && !previousIdentity.equals(info.getIdentity())) {
  109 + j.hdel(PSKID_SEC, previousIdentity);
  110 + }
  111 +
  112 + return previous;
  113 + }
  114 + }
  115 +
  116 + @Override
  117 + public SecurityInfo remove(String endpoint, boolean infosAreCompromised) {
  118 + try (Jedis j = (Jedis) connectionFactory.getConnection().getNativeConnection()) {
  119 + byte[] data = j.get((SEC_EP + endpoint).getBytes());
  120 +
  121 + if (data != null) {
  122 + SecurityInfo info = deserialize(data);
  123 + if (info.getIdentity() != null) {
  124 + j.hdel(PSKID_SEC.getBytes(), info.getIdentity().getBytes());
  125 + }
  126 + j.del((SEC_EP + endpoint).getBytes());
  127 + if (listener != null) {
  128 + listener.securityInfoRemoved(infosAreCompromised, info);
  129 + }
  130 + return info;
  131 + }
  132 + }
  133 + return null;
  134 + }
  135 +
  136 + private byte[] serialize(SecurityInfo secInfo) {
  137 + return SecurityInfoSerDes.serialize(secInfo);
  138 + }
  139 +
  140 + private SecurityInfo deserialize(byte[] data) {
  141 + return SecurityInfoSerDes.deserialize(data);
  142 + }
  143 +
  144 + @Override
  145 + public void setListener(SecurityStoreListener listener) {
  146 + this.listener = listener;
  147 + }
  148 +}
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.transport.lwm2m.server.store;
  17 +
  18 +import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore;
  19 +import org.eclipse.leshan.server.californium.registration.InMemoryRegistrationStore;
  20 +import org.eclipse.leshan.server.security.EditableSecurityStore;
  21 +import org.eclipse.leshan.server.security.InMemorySecurityStore;
  22 +import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException;
  23 +import org.eclipse.leshan.server.security.SecurityInfo;
  24 +import org.eclipse.leshan.server.security.SecurityStoreListener;
  25 +import org.springframework.beans.factory.annotation.Autowired;
  26 +import org.springframework.beans.factory.annotation.Value;
  27 +import org.springframework.context.annotation.Bean;
  28 +import org.springframework.context.annotation.Lazy;
  29 +import org.springframework.stereotype.Service;
  30 +import org.thingsboard.server.cache.TBRedisCacheConfiguration;
  31 +import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
  32 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
  33 +
  34 +import java.util.Collection;
  35 +import java.util.Optional;
  36 +
  37 +@Service
  38 +@TbLwM2mTransportComponent
  39 +public class TbLwM2mStoreConfiguration {
  40 +
  41 + @Autowired(required = false)
  42 + private Optional<TBRedisCacheConfiguration> redisConfiguration;
  43 +
  44 + @Autowired
  45 + @Lazy
  46 + private LwM2mClientContext clientContext;
  47 +
  48 + @Value("${transport.lwm2m.redis.enabled:false}")
  49 + private boolean useRedis;
  50 +
  51 + @Bean
  52 + private CaliforniumRegistrationStore registrationStore() {
  53 + return redisConfiguration.isPresent() && useRedis ?
  54 + new TbLwM2mRedisRegistrationStore(redisConfiguration.get().redisConnectionFactory()) : new InMemoryRegistrationStore();
  55 + }
  56 +
  57 + @Bean
  58 + private EditableSecurityStore securityStore() {
  59 + return new TbLwM2mSecurityStoreWrapper(redisConfiguration.isPresent() && useRedis ?
  60 + new TbLwM2mRedisSecurityStore(redisConfiguration.get().redisConnectionFactory()) : new InMemorySecurityStore());
  61 + }
  62 +
  63 + public class TbLwM2mSecurityStoreWrapper implements EditableSecurityStore {
  64 +
  65 + private final EditableSecurityStore securityStore;
  66 +
  67 + public TbLwM2mSecurityStoreWrapper(EditableSecurityStore securityStore) {
  68 + this.securityStore = securityStore;
  69 + }
  70 +
  71 + @Override
  72 + public Collection<SecurityInfo> getAll() {
  73 + return securityStore.getAll();
  74 + }
  75 +
  76 + @Override
  77 + public SecurityInfo add(SecurityInfo info) throws NonUniqueSecurityInfoException {
  78 + return securityStore.add(info);
  79 + }
  80 +
  81 + @Override
  82 + public SecurityInfo remove(String endpoint, boolean infosAreCompromised) {
  83 + return securityStore.remove(endpoint, infosAreCompromised);
  84 + }
  85 +
  86 + @Override
  87 + public void setListener(SecurityStoreListener listener) {
  88 + securityStore.setListener(listener);
  89 + }
  90 +
  91 + @Override
  92 + public SecurityInfo getByEndpoint(String endpoint) {
  93 + SecurityInfo securityInfo = securityStore.getByEndpoint(endpoint);
  94 + if (securityInfo == null) {
  95 + securityInfo = clientContext.addLwM2mClientToSession(endpoint).getSecurityInfo();
  96 + try {
  97 + if (securityInfo != null) {
  98 + add(securityInfo);
  99 + }
  100 + } catch (NonUniqueSecurityInfoException e) {
  101 + e.printStackTrace();
  102 + }
  103 + }
  104 + return securityInfo;
  105 + }
  106 +
  107 + @Override
  108 + public SecurityInfo getByIdentity(String pskIdentity) {
  109 + SecurityInfo securityInfo = securityStore.getByIdentity(pskIdentity);
  110 + if (securityInfo == null) {
  111 + securityInfo = clientContext.addLwM2mClientToSession(pskIdentity).getSecurityInfo();
  112 + try {
  113 + if (securityInfo != null) {
  114 + add(securityInfo);
  115 + }
  116 + } catch (NonUniqueSecurityInfoException e) {
  117 + e.printStackTrace();
  118 + }
  119 + }
  120 + return securityInfo;
  121 + }
  122 + }
  123 +}
@@ -54,6 +54,10 @@ @@ -54,6 +54,10 @@
54 </dependency> 54 </dependency>
55 <dependency> 55 <dependency>
56 <groupId>org.thingsboard.common</groupId> 56 <groupId>org.thingsboard.common</groupId>
  57 + <artifactId>cache</artifactId>
  58 + </dependency>
  59 + <dependency>
  60 + <groupId>org.thingsboard.common</groupId>
57 <artifactId>util</artifactId> 61 <artifactId>util</artifactId>
58 </dependency> 62 </dependency>
59 <dependency> 63 <dependency>
@@ -20,10 +20,10 @@ import lombok.Data; @@ -20,10 +20,10 @@ import lombok.Data;
20 import lombok.Getter; 20 import lombok.Getter;
21 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
22 import org.springframework.beans.factory.annotation.Autowired; 22 import org.springframework.beans.factory.annotation.Autowired;
23 -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;  
24 import org.springframework.stereotype.Service; 23 import org.springframework.stereotype.Service;
25 import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; 24 import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
26 import org.thingsboard.server.queue.scheduler.SchedulerComponent; 25 import org.thingsboard.server.queue.scheduler.SchedulerComponent;
  26 +import org.thingsboard.server.queue.util.TbTransportComponent;
27 27
28 import javax.annotation.PostConstruct; 28 import javax.annotation.PostConstruct;
29 import javax.annotation.PreDestroy; 29 import javax.annotation.PreDestroy;
@@ -35,8 +35,6 @@ import java.util.concurrent.Executors; @@ -35,8 +35,6 @@ import java.util.concurrent.Executors;
35 */ 35 */
36 @Slf4j 36 @Slf4j
37 @Data 37 @Data
38 -@Service  
39 -@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true')")  
40 public abstract class TransportContext { 38 public abstract class TransportContext {
41 39
42 protected final ObjectMapper mapper = new ObjectMapper(); 40 protected final ObjectMapper mapper = new ObjectMapper();
@@ -186,10 +186,6 @@ public class LwM2MTransportConfigServer { @@ -186,10 +186,6 @@ public class LwM2MTransportConfigServer {
186 @Value("${transport.lwm2m.server.secure.alias:}") 186 @Value("${transport.lwm2m.server.secure.alias:}")
187 private String serverAlias; 187 private String serverAlias;
188 188
189 - @Getter  
190 - @Value("${transport.lwm2m.secure.redis_url:}")  
191 - private String redisUrl;  
192 -  
193 @PostConstruct 189 @PostConstruct
194 public void init() { 190 public void init() {
195 modelsValue = ObjectLoader.loadDefault(); 191 modelsValue = ObjectLoader.loadDefault();
@@ -46,6 +46,10 @@ @@ -46,6 +46,10 @@
46 <artifactId>javax.annotation-api</artifactId> 46 <artifactId>javax.annotation-api</artifactId>
47 </dependency> 47 </dependency>
48 <dependency> 48 <dependency>
  49 + <groupId>com.fasterxml.jackson.core</groupId>
  50 + <artifactId>jackson-databind</artifactId>
  51 + </dependency>
  52 + <dependency>
49 <groupId>org.slf4j</groupId> 53 <groupId>org.slf4j</groupId>
50 <artifactId>slf4j-api</artifactId> 54 <artifactId>slf4j-api</artifactId>
51 </dependency> 55 </dependency>
common/util/src/main/java/org/thingsboard/common/util/JacksonUtil.java renamed from common/dao-api/src/main/java/org/thingsboard/server/dao/util/mapping/JacksonUtil.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.dao.util.mapping; 16 +package org.thingsboard.common.util;
17 17
18 import com.fasterxml.jackson.core.JsonProcessingException; 18 import com.fasterxml.jackson.core.JsonProcessingException;
19 import com.fasterxml.jackson.core.type.TypeReference; 19 import com.fasterxml.jackson.core.type.TypeReference;
@@ -41,6 +41,10 @@ @@ -41,6 +41,10 @@
41 </dependency> 41 </dependency>
42 <dependency> 42 <dependency>
43 <groupId>org.thingsboard.common</groupId> 43 <groupId>org.thingsboard.common</groupId>
  44 + <artifactId>cache</artifactId>
  45 + </dependency>
  46 + <dependency>
  47 + <groupId>org.thingsboard.common</groupId>
44 <artifactId>message</artifactId> 48 <artifactId>message</artifactId>
45 </dependency> 49 </dependency>
46 <dependency> 50 <dependency>
@@ -49,7 +49,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionRequest; @@ -49,7 +49,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionRequest;
49 import org.thingsboard.server.dao.entity.EntityService; 49 import org.thingsboard.server.dao.entity.EntityService;
50 import org.thingsboard.server.dao.exception.DataValidationException; 50 import org.thingsboard.server.dao.exception.DataValidationException;
51 import org.thingsboard.server.dao.service.DataValidator; 51 import org.thingsboard.server.dao.service.DataValidator;
52 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 52 +import org.thingsboard.common.util.JacksonUtil;
53 53
54 import java.io.PrintWriter; 54 import java.io.PrintWriter;
55 import java.io.StringWriter; 55 import java.io.StringWriter;
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.dao.cache; 16 package org.thingsboard.server.dao.cache;
17 17
18 import org.springframework.cache.interceptor.KeyGenerator; 18 import org.springframework.cache.interceptor.KeyGenerator;
  19 +import org.springframework.stereotype.Component;
19 import org.thingsboard.server.common.data.id.TenantId; 20 import org.thingsboard.server.common.data.id.TenantId;
20 import org.thingsboard.server.common.data.security.DeviceCredentials; 21 import org.thingsboard.server.common.data.security.DeviceCredentials;
21 import org.thingsboard.server.dao.device.DeviceCredentialsService; 22 import org.thingsboard.server.dao.device.DeviceCredentialsService;
@@ -24,6 +25,7 @@ import java.lang.reflect.Method; @@ -24,6 +25,7 @@ import java.lang.reflect.Method;
24 25
25 import static org.thingsboard.server.common.data.CacheConstants.DEVICE_CREDENTIALS_CACHE; 26 import static org.thingsboard.server.common.data.CacheConstants.DEVICE_CREDENTIALS_CACHE;
26 27
  28 +@Component("previousDeviceCredentialsId")
27 public class PreviousDeviceCredentialsIdKeyGenerator implements KeyGenerator { 29 public class PreviousDeviceCredentialsIdKeyGenerator implements KeyGenerator {
28 30
29 private static final String NOT_VALID_DEVICE = DEVICE_CREDENTIALS_CACHE + "_notValidDeviceCredentialsId"; 31 private static final String NOT_VALID_DEVICE = DEVICE_CREDENTIALS_CACHE + "_notValidDeviceCredentialsId";
@@ -33,7 +33,7 @@ import org.thingsboard.server.common.msg.EncryptionUtil; @@ -33,7 +33,7 @@ import org.thingsboard.server.common.msg.EncryptionUtil;
33 import org.thingsboard.server.dao.entity.AbstractEntityService; 33 import org.thingsboard.server.dao.entity.AbstractEntityService;
34 import org.thingsboard.server.dao.exception.DataValidationException; 34 import org.thingsboard.server.dao.exception.DataValidationException;
35 import org.thingsboard.server.dao.service.DataValidator; 35 import org.thingsboard.server.dao.service.DataValidator;
36 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 36 +import org.thingsboard.common.util.JacksonUtil;
37 37
38 import static org.thingsboard.server.common.data.CacheConstants.DEVICE_CREDENTIALS_CACHE; 38 import static org.thingsboard.server.common.data.CacheConstants.DEVICE_CREDENTIALS_CACHE;
39 import static org.thingsboard.server.dao.service.Validator.validateId; 39 import static org.thingsboard.server.dao.service.Validator.validateId;
@@ -75,7 +75,7 @@ import org.thingsboard.server.dao.service.DataValidator; @@ -75,7 +75,7 @@ import org.thingsboard.server.dao.service.DataValidator;
75 import org.thingsboard.server.dao.service.PaginatedRemover; 75 import org.thingsboard.server.dao.service.PaginatedRemover;
76 import org.thingsboard.server.dao.tenant.TbTenantProfileCache; 76 import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
77 import org.thingsboard.server.dao.tenant.TenantDao; 77 import org.thingsboard.server.dao.tenant.TenantDao;
78 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 78 +import org.thingsboard.common.util.JacksonUtil;
79 79
80 import javax.annotation.Nullable; 80 import javax.annotation.Nullable;
81 import java.util.ArrayList; 81 import java.util.ArrayList;
@@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.id.TenantId; @@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.id.TenantId;
31 import org.thingsboard.server.dao.model.BaseSqlEntity; 31 import org.thingsboard.server.dao.model.BaseSqlEntity;
32 import org.thingsboard.server.dao.model.ModelConstants; 32 import org.thingsboard.server.dao.model.ModelConstants;
33 import org.thingsboard.server.dao.model.SearchTextEntity; 33 import org.thingsboard.server.dao.model.SearchTextEntity;
34 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 34 +import org.thingsboard.common.util.JacksonUtil;
35 import org.thingsboard.server.dao.util.mapping.JsonBinaryType; 35 import org.thingsboard.server.dao.util.mapping.JsonBinaryType;
36 import org.thingsboard.server.dao.util.mapping.JsonStringType; 36 import org.thingsboard.server.dao.util.mapping.JsonStringType;
37 37
@@ -32,7 +32,7 @@ import org.thingsboard.server.common.data.id.TenantId; @@ -32,7 +32,7 @@ import org.thingsboard.server.common.data.id.TenantId;
32 import org.thingsboard.server.dao.model.BaseSqlEntity; 32 import org.thingsboard.server.dao.model.BaseSqlEntity;
33 import org.thingsboard.server.dao.model.ModelConstants; 33 import org.thingsboard.server.dao.model.ModelConstants;
34 import org.thingsboard.server.dao.model.SearchTextEntity; 34 import org.thingsboard.server.dao.model.SearchTextEntity;
35 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 35 +import org.thingsboard.common.util.JacksonUtil;
36 import org.thingsboard.server.dao.util.mapping.JsonBinaryType; 36 import org.thingsboard.server.dao.util.mapping.JsonBinaryType;
37 37
38 import javax.persistence.Column; 38 import javax.persistence.Column;
@@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; @@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
27 import org.thingsboard.server.dao.model.BaseSqlEntity; 27 import org.thingsboard.server.dao.model.BaseSqlEntity;
28 import org.thingsboard.server.dao.model.ModelConstants; 28 import org.thingsboard.server.dao.model.ModelConstants;
29 import org.thingsboard.server.dao.model.SearchTextEntity; 29 import org.thingsboard.server.dao.model.SearchTextEntity;
30 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 30 +import org.thingsboard.common.util.JacksonUtil;
31 import org.thingsboard.server.dao.util.mapping.JsonBinaryType; 31 import org.thingsboard.server.dao.util.mapping.JsonBinaryType;
32 32
33 import javax.persistence.Column; 33 import javax.persistence.Column;
@@ -48,7 +48,7 @@ import org.thingsboard.server.dao.service.DataValidator; @@ -48,7 +48,7 @@ import org.thingsboard.server.dao.service.DataValidator;
48 import org.thingsboard.server.dao.service.PaginatedRemover; 48 import org.thingsboard.server.dao.service.PaginatedRemover;
49 import org.thingsboard.server.dao.tenant.TbTenantProfileCache; 49 import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
50 import org.thingsboard.server.dao.tenant.TenantDao; 50 import org.thingsboard.server.dao.tenant.TenantDao;
51 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 51 +import org.thingsboard.common.util.JacksonUtil;
52 52
53 import java.util.HashMap; 53 import java.util.HashMap;
54 import java.util.Map; 54 import java.util.Map;
@@ -19,6 +19,7 @@ import org.hibernate.type.descriptor.WrapperOptions; @@ -19,6 +19,7 @@ import org.hibernate.type.descriptor.WrapperOptions;
19 import org.hibernate.type.descriptor.java.AbstractTypeDescriptor; 19 import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
20 import org.hibernate.type.descriptor.java.MutableMutabilityPlan; 20 import org.hibernate.type.descriptor.java.MutableMutabilityPlan;
21 import org.hibernate.usertype.DynamicParameterizedType; 21 import org.hibernate.usertype.DynamicParameterizedType;
  22 +import org.thingsboard.common.util.JacksonUtil;
22 23
23 import java.util.Properties; 24 import java.util.Properties;
24 25
@@ -46,7 +46,7 @@ import org.thingsboard.server.common.data.query.EntityKeyType; @@ -46,7 +46,7 @@ import org.thingsboard.server.common.data.query.EntityKeyType;
46 import org.thingsboard.server.common.data.relation.EntityRelation; 46 import org.thingsboard.server.common.data.relation.EntityRelation;
47 import org.thingsboard.server.common.data.relation.RelationTypeGroup; 47 import org.thingsboard.server.common.data.relation.RelationTypeGroup;
48 import org.thingsboard.server.dao.alarm.AlarmOperationResult; 48 import org.thingsboard.server.dao.alarm.AlarmOperationResult;
49 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 49 +import org.thingsboard.common.util.JacksonUtil;
50 50
51 import java.util.Arrays; 51 import java.util.Arrays;
52 import java.util.Collections; 52 import java.util.Collections;
@@ -854,6 +854,11 @@ @@ -854,6 +854,11 @@
854 </dependency> 854 </dependency>
855 <dependency> 855 <dependency>
856 <groupId>org.thingsboard.common</groupId> 856 <groupId>org.thingsboard.common</groupId>
  857 + <artifactId>cache</artifactId>
  858 + <version>${project.version}</version>
  859 + </dependency>
  860 + <dependency>
  861 + <groupId>org.thingsboard.common</groupId>
857 <artifactId>actor</artifactId> 862 <artifactId>actor</artifactId>
858 <version>${project.version}</version> 863 <version>${project.version}</version>
859 </dependency> 864 </dependency>
@@ -23,7 +23,7 @@ import org.mockito.junit.MockitoJUnitRunner; @@ -23,7 +23,7 @@ import org.mockito.junit.MockitoJUnitRunner;
23 import org.thingsboard.server.common.data.id.TenantId; 23 import org.thingsboard.server.common.data.id.TenantId;
24 import org.thingsboard.server.common.msg.TbMsg; 24 import org.thingsboard.server.common.msg.TbMsg;
25 import org.thingsboard.server.common.msg.TbMsgMetaData; 25 import org.thingsboard.server.common.msg.TbMsgMetaData;
26 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 26 +import org.thingsboard.common.util.JacksonUtil;
27 27
28 @RunWith(MockitoJUnitRunner.class) 28 @RunWith(MockitoJUnitRunner.class)
29 public class TbNodeUtilsTest { 29 public class TbNodeUtilsTest {
@@ -28,7 +28,7 @@ import org.thingsboard.rule.engine.api.TbNodeException; @@ -28,7 +28,7 @@ import org.thingsboard.rule.engine.api.TbNodeException;
28 import org.thingsboard.server.common.data.DataConstants; 28 import org.thingsboard.server.common.data.DataConstants;
29 import org.thingsboard.server.common.msg.TbMsg; 29 import org.thingsboard.server.common.msg.TbMsg;
30 import org.thingsboard.server.common.msg.TbMsgMetaData; 30 import org.thingsboard.server.common.msg.TbMsgMetaData;
31 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 31 +import org.thingsboard.common.util.JacksonUtil;
32 32
33 import static org.thingsboard.common.util.DonAsynchron.withCallback; 33 import static org.thingsboard.common.util.DonAsynchron.withCallback;
34 34
@@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.plugin.ComponentType; @@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.plugin.ComponentType;
35 import org.thingsboard.server.common.msg.TbMsg; 35 import org.thingsboard.server.common.msg.TbMsg;
36 import org.thingsboard.server.common.msg.session.SessionMsgType; 36 import org.thingsboard.server.common.msg.session.SessionMsgType;
37 import org.thingsboard.server.dao.timeseries.TimeseriesService; 37 import org.thingsboard.server.dao.timeseries.TimeseriesService;
38 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 38 +import org.thingsboard.common.util.JacksonUtil;
39 39
40 import java.math.BigDecimal; 40 import java.math.BigDecimal;
41 import java.math.RoundingMode; 41 import java.math.RoundingMode;
@@ -25,20 +25,17 @@ import org.thingsboard.rule.engine.api.TbContext; @@ -25,20 +25,17 @@ import org.thingsboard.rule.engine.api.TbContext;
25 import org.thingsboard.rule.engine.profile.state.PersistedAlarmRuleState; 25 import org.thingsboard.rule.engine.profile.state.PersistedAlarmRuleState;
26 import org.thingsboard.rule.engine.profile.state.PersistedAlarmState; 26 import org.thingsboard.rule.engine.profile.state.PersistedAlarmState;
27 import org.thingsboard.server.common.data.DataConstants; 27 import org.thingsboard.server.common.data.DataConstants;
28 -import org.thingsboard.server.common.data.Tenant;  
29 import org.thingsboard.server.common.data.alarm.Alarm; 28 import org.thingsboard.server.common.data.alarm.Alarm;
30 import org.thingsboard.server.common.data.alarm.AlarmSeverity; 29 import org.thingsboard.server.common.data.alarm.AlarmSeverity;
31 import org.thingsboard.server.common.data.alarm.AlarmStatus; 30 import org.thingsboard.server.common.data.alarm.AlarmStatus;
32 import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; 31 import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm;
33 -import org.thingsboard.server.common.data.id.CustomerId;  
34 import org.thingsboard.server.common.data.id.EntityId; 32 import org.thingsboard.server.common.data.id.EntityId;
35 -import org.thingsboard.server.common.data.id.TenantId;  
36 import org.thingsboard.server.common.data.query.EntityKeyType; 33 import org.thingsboard.server.common.data.query.EntityKeyType;
37 import org.thingsboard.server.common.data.query.KeyFilter; 34 import org.thingsboard.server.common.data.query.KeyFilter;
38 import org.thingsboard.server.common.msg.TbMsg; 35 import org.thingsboard.server.common.msg.TbMsg;
39 import org.thingsboard.server.common.msg.TbMsgMetaData; 36 import org.thingsboard.server.common.msg.TbMsgMetaData;
40 import org.thingsboard.server.common.msg.queue.ServiceQueue; 37 import org.thingsboard.server.common.msg.queue.ServiceQueue;
41 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 38 +import org.thingsboard.common.util.JacksonUtil;
42 39
43 import java.util.ArrayList; 40 import java.util.ArrayList;
44 import java.util.Comparator; 41 import java.util.Comparator;
@@ -40,7 +40,7 @@ import org.thingsboard.server.common.msg.TbMsg; @@ -40,7 +40,7 @@ import org.thingsboard.server.common.msg.TbMsg;
40 import org.thingsboard.server.common.msg.session.SessionMsgType; 40 import org.thingsboard.server.common.msg.session.SessionMsgType;
41 import org.thingsboard.server.common.transport.adaptor.JsonConverter; 41 import org.thingsboard.server.common.transport.adaptor.JsonConverter;
42 import org.thingsboard.server.dao.sql.query.EntityKeyMapping; 42 import org.thingsboard.server.dao.sql.query.EntityKeyMapping;
43 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 43 +import org.thingsboard.common.util.JacksonUtil;
44 44
45 import java.util.ArrayList; 45 import java.util.ArrayList;
46 import java.util.HashMap; 46 import java.util.HashMap;
@@ -38,7 +38,7 @@ import org.thingsboard.server.common.data.rule.RuleNodeState; @@ -38,7 +38,7 @@ import org.thingsboard.server.common.data.rule.RuleNodeState;
38 import org.thingsboard.server.common.msg.TbMsg; 38 import org.thingsboard.server.common.msg.TbMsg;
39 import org.thingsboard.server.common.msg.TbMsgMetaData; 39 import org.thingsboard.server.common.msg.TbMsgMetaData;
40 import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; 40 import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
41 -import org.thingsboard.server.dao.util.mapping.JacksonUtil; 41 +import org.thingsboard.common.util.JacksonUtil;
42 42
43 import java.util.Map; 43 import java.util.Map;
44 import java.util.UUID; 44 import java.util.UUID;
@@ -16,31 +16,8 @@ @@ -16,31 +16,8 @@
16 package org.thingsboard.rule.engine.profile; 16 package org.thingsboard.rule.engine.profile;
17 17
18 import lombok.Data; 18 import lombok.Data;
19 -import lombok.extern.slf4j.Slf4j;  
20 import org.codehaus.jackson.annotate.JsonIgnoreProperties; 19 import org.codehaus.jackson.annotate.JsonIgnoreProperties;
21 -import org.thingsboard.rule.engine.api.EmptyNodeConfiguration;  
22 import org.thingsboard.rule.engine.api.NodeConfiguration; 20 import org.thingsboard.rule.engine.api.NodeConfiguration;
23 -import org.thingsboard.rule.engine.api.RuleEngineDeviceProfileCache;  
24 -import org.thingsboard.rule.engine.api.RuleNode;  
25 -import org.thingsboard.rule.engine.api.TbContext;  
26 -import org.thingsboard.rule.engine.api.TbNode;  
27 -import org.thingsboard.rule.engine.api.TbNodeConfiguration;  
28 -import org.thingsboard.rule.engine.api.TbNodeException;  
29 -import org.thingsboard.server.common.data.DataConstants;  
30 -import org.thingsboard.server.common.data.Device;  
31 -import org.thingsboard.server.common.data.DeviceProfile;  
32 -import org.thingsboard.server.common.data.EntityType;  
33 -import org.thingsboard.server.common.data.id.DeviceId;  
34 -import org.thingsboard.server.common.data.id.DeviceProfileId;  
35 -import org.thingsboard.server.common.data.plugin.ComponentType;  
36 -import org.thingsboard.server.common.msg.TbMsg;  
37 -import org.thingsboard.server.common.msg.TbMsgMetaData;  
38 -import org.thingsboard.server.dao.util.mapping.JacksonUtil;  
39 -  
40 -import java.util.Map;  
41 -import java.util.concurrent.ConcurrentHashMap;  
42 -import java.util.concurrent.ExecutionException;  
43 -import java.util.concurrent.TimeUnit;  
44 21
45 @Data 22 @Data
46 @JsonIgnoreProperties(ignoreUnknown = true) 23 @JsonIgnoreProperties(ignoreUnknown = true)
@@ -45,9 +45,21 @@ @@ -45,9 +45,21 @@
45 </properties> 45 </properties>
46 46
47 <dependencies> 47 <dependencies>
  48 +<!-- <dependency>-->
  49 +<!-- <groupId>org.thingsboard.common.transport</groupId>-->
  50 +<!-- <artifactId>transport-api</artifactId>-->
  51 +<!-- </dependency>-->
48 <dependency> 52 <dependency>
49 <groupId>org.thingsboard.common.transport</groupId> 53 <groupId>org.thingsboard.common.transport</groupId>
50 - <artifactId>transport-api</artifactId> 54 + <artifactId>lwm2m</artifactId>
  55 + </dependency>
  56 + <dependency>
  57 + <groupId>org.thingsboard.common</groupId>
  58 + <artifactId>queue</artifactId>
  59 + </dependency>
  60 + <dependency>
  61 + <groupId>org.thingsboard.common</groupId>
  62 + <artifactId>cache</artifactId>
51 </dependency> 63 </dependency>
52 <dependency> 64 <dependency>
53 <groupId>org.springframework</groupId> 65 <groupId>org.springframework</groupId>
@@ -26,7 +26,7 @@ import java.util.Arrays; @@ -26,7 +26,7 @@ import java.util.Arrays;
26 @SpringBootConfiguration 26 @SpringBootConfiguration
27 @EnableAsync 27 @EnableAsync
28 @EnableScheduling 28 @EnableScheduling
29 -@ComponentScan({"org.thingsboard.server.lwm2m", "org.thingsboard.server.common", "org.thingsboard.server.transport.lwm2m", "org.thingsboard.server.queue"}) 29 +@ComponentScan({"org.thingsboard.server.lwm2m", "org.thingsboard.server.common", "org.thingsboard.server.transport.lwm2m", "org.thingsboard.server.queue", "org.thingsboard.server.cache"})
30 public class ThingsboardLwm2mTransportApplication { 30 public class ThingsboardLwm2mTransportApplication {
31 31
32 private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name"; 32 private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name";
@@ -40,6 +40,83 @@ zk: @@ -40,6 +40,83 @@ zk:
40 # Name of the directory in zookeeper 'filesystem' 40 # Name of the directory in zookeeper 'filesystem'
41 zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}" 41 zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}"
42 42
  43 +cache:
  44 + # caffeine or redis
  45 + type: "${CACHE_TYPE:caffeine}"
  46 +
  47 +caffeine:
  48 + specs:
  49 + relations:
  50 + timeToLiveInMinutes: 1440
  51 + maxSize: 0
  52 + deviceCredentials:
  53 + timeToLiveInMinutes: 1440
  54 + maxSize: 0
  55 + devices:
  56 + timeToLiveInMinutes: 1440
  57 + maxSize: 0
  58 + sessions:
  59 + timeToLiveInMinutes: 1440
  60 + maxSize: 0
  61 + assets:
  62 + timeToLiveInMinutes: 1440
  63 + maxSize: 0
  64 + entityViews:
  65 + timeToLiveInMinutes: 1440
  66 + maxSize: 0
  67 + claimDevices:
  68 + timeToLiveInMinutes: 1
  69 + maxSize: 0
  70 + securitySettings:
  71 + timeToLiveInMinutes: 1440
  72 + maxSize: 0
  73 + tenantProfiles:
  74 + timeToLiveInMinutes: 1440
  75 + maxSize: 0
  76 + deviceProfiles:
  77 + timeToLiveInMinutes: 1440
  78 + maxSize: 0
  79 +
  80 +redis:
  81 + # standalone or cluster
  82 + connection:
  83 + type: "${REDIS_CONNECTION_TYPE:standalone}"
  84 + standalone:
  85 + host: "${REDIS_HOST:localhost}"
  86 + port: "${REDIS_PORT:6379}"
  87 + useDefaultClientConfig: "${REDIS_USE_DEFAULT_CLIENT_CONFIG:true}"
  88 + # this value may be used only if you used not default ClientConfig
  89 + clientName: "${REDIS_CLIENT_NAME:standalone}"
  90 + # this value may be used only if you used not default ClientConfig
  91 + connectTimeout: "${REDIS_CLIENT_CONNECT_TIMEOUT:30000}"
  92 + # this value may be used only if you used not default ClientConfig
  93 + readTimeout: "${REDIS_CLIENT_READ_TIMEOUT:60000}"
  94 + # this value may be used only if you used not default ClientConfig
  95 + usePoolConfig: "${REDIS_CLIENT_USE_POOL_CONFIG:false}"
  96 + cluster:
  97 + # Comma-separated list of "host:port" pairs to bootstrap from.
  98 + nodes: "${REDIS_NODES:}"
  99 + # Maximum number of redirects to follow when executing commands across the cluster.
  100 + max-redirects: "${REDIS_MAX_REDIRECTS:12}"
  101 + useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}"
  102 + # db index
  103 + db: "${REDIS_DB:0}"
  104 + # db password
  105 + password: "${REDIS_PASSWORD:}"
  106 + # pool config
  107 + pool_config:
  108 + maxTotal: "${REDIS_POOL_CONFIG_MAX_TOTAL:128}"
  109 + maxIdle: "${REDIS_POOL_CONFIG_MAX_IDLE:128}"
  110 + minIdle: "${REDIS_POOL_CONFIG_MIN_IDLE:16}"
  111 + testOnBorrow: "${REDIS_POOL_CONFIG_TEST_ON_BORROW:true}"
  112 + testOnReturn: "${REDIS_POOL_CONFIG_TEST_ON_RETURN:true}"
  113 + testWhileIdle: "${REDIS_POOL_CONFIG_TEST_WHILE_IDLE:true}"
  114 + minEvictableMs: "${REDIS_POOL_CONFIG_MIN_EVICTABLE_MS:60000}"
  115 + evictionRunsMs: "${REDIS_POOL_CONFIG_EVICTION_RUNS_MS:30000}"
  116 + maxWaitMills: "${REDIS_POOL_CONFIG_MAX_WAIT_MS:60000}"
  117 + numberTestsPerEvictionRun: "${REDIS_POOL_CONFIG_NUMBER_TESTS_PER_EVICTION_RUN:3}"
  118 + blockWhenExhausted: "${REDIS_POOL_CONFIG_BLOCK_WHEN_EXHAUSTED:true}"
  119 +
43 # LWM2M server parameters 120 # LWM2M server parameters
44 transport: 121 transport:
45 # Local LwM2M transport parameters 122 # Local LwM2M transport parameters
@@ -102,8 +179,8 @@ transport: @@ -102,8 +179,8 @@ transport:
102 public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:3fc4e61bcd8901ec27c424114c3e887ed372497f0c2cf85839b8443e76988b34}" 179 public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:3fc4e61bcd8901ec27c424114c3e887ed372497f0c2cf85839b8443e76988b34}"
103 private_encoded: "${LWM2M_SERVER_PRIVATE_ENCODED_BS:308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104205ecafd90caa7be45c42e1f3f32571632b8409e6e6249d7124f4ba56fab3c8083a00a06082a8648ce3d030107a144034200045017c87a1c1768264656b3b355434b0def6edb8b9bf166a4762d9930cd730f913fc4e61bcd8901ec27c424114c3e887ed372497f0c2cf85839b8443e76988b34}" # Only Certificate_x509: 180 private_encoded: "${LWM2M_SERVER_PRIVATE_ENCODED_BS:308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104205ecafd90caa7be45c42e1f3f32571632b8409e6e6249d7124f4ba56fab3c8083a00a06082a8648ce3d030107a144034200045017c87a1c1768264656b3b355434b0def6edb8b9bf166a4762d9930cd730f913fc4e61bcd8901ec27c424114c3e887ed372497f0c2cf85839b8443e76988b34}" # Only Certificate_x509:
104 alias: "${LWM2M_KEYSTORE_ALIAS_BOOTSTRAP:bootstrap}" 181 alias: "${LWM2M_KEYSTORE_ALIAS_BOOTSTRAP:bootstrap}"
105 - # Redis  
106 - redis_url: "${LWM2M_REDIS_URL:''}" 182 + # Use redis for Security and Registration stores
  183 + redis.enabled: "${LWM2M_REDIS_ENABLED:false}"
107 184
108 sessions: 185 sessions:
109 inactivity_timeout: "${TB_TRANSPORT_SESSIONS_INACTIVITY_TIMEOUT:300000}" 186 inactivity_timeout: "${TB_TRANSPORT_SESSIONS_INACTIVITY_TIMEOUT:300000}"
@@ -88,6 +88,9 @@ @@ -88,6 +88,9 @@
88 <mat-error *ngIf="deviceCredentialsFormGroup.get('credentialsValue').hasError('required')"> 88 <mat-error *ngIf="deviceCredentialsFormGroup.get('credentialsValue').hasError('required')">
89 {{ 'device.lwm2m-value-required' | translate }} 89 {{ 'device.lwm2m-value-required' | translate }}
90 </mat-error> 90 </mat-error>
  91 + <mat-error *ngIf="deviceCredentialsFormGroup.get('credentialsValue').hasError('jsonError')">
  92 + {{ 'device.lwm2m-value-json-error' | translate }}
  93 + </mat-error>
91 <div mat-dialog-actions fxLayoutAlign="center center"> 94 <div mat-dialog-actions fxLayoutAlign="center center">
92 <button mat-raised-button color="primary" 95 <button mat-raised-button color="primary"
93 matTooltip="{{'device.lwm2m-value-edit-tip' | translate }}" 96 matTooltip="{{'device.lwm2m-value-edit-tip' | translate }}"
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 /// limitations under the License. 14 /// limitations under the License.
15 /// 15 ///
16 16
17 -import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; 17 +import {Component, forwardRef, Input, OnDestroy, OnInit} from '@angular/core';
18 import { 18 import {
19 ControlValueAccessor, 19 ControlValueAccessor,
20 FormBuilder, 20 FormBuilder,
@@ -33,19 +33,19 @@ import { @@ -33,19 +33,19 @@ import {
33 DeviceCredentials, 33 DeviceCredentials,
34 DeviceCredentialsType 34 DeviceCredentialsType
35 } from '@shared/models/device.models'; 35 } from '@shared/models/device.models';
36 -import { Subscription } from 'rxjs';  
37 -import { distinctUntilChanged } from 'rxjs/operators';  
38 -import { SecurityConfigComponent } from '@home/pages/device/lwm2m/security-config.component'; 36 +import {Subscription} from 'rxjs';
  37 +import {distinctUntilChanged} from 'rxjs/operators';
  38 +import {SecurityConfigComponent} from '@home/pages/device/lwm2m/security-config.component';
39 import { 39 import {
40 DEFAULT_END_POINT, 40 DEFAULT_END_POINT,
41 DeviceCredentialsDialogLwm2mData, 41 DeviceCredentialsDialogLwm2mData,
42 END_POINT, 42 END_POINT,
43 getDefaultSecurityConfig, 43 getDefaultSecurityConfig,
44 - JSON_ALL_CONFIG 44 + JSON_ALL_CONFIG, SecurityConfigModels, validateSecurityConfig
45 } from '@home/pages/device/lwm2m/security-config.models'; 45 } from '@home/pages/device/lwm2m/security-config.models';
46 -import { TranslateService } from '@ngx-translate/core';  
47 -import { MatDialog } from '@angular/material/dialog';  
48 -import { isDefinedAndNotNull } from '@core/utils'; 46 +import {TranslateService} from '@ngx-translate/core';
  47 +import {MatDialog} from '@angular/material/dialog';
  48 +import {isDefinedAndNotNull} from '@core/utils';
49 49
50 @Component({ 50 @Component({
51 selector: 'tb-device-credentials', 51 selector: 'tb-device-credentials',
@@ -196,13 +196,19 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit, @@ -196,13 +196,19 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit,
196 this.deviceCredentialsFormGroup.get('credentialsBasic').disable({emitEvent: false}); 196 this.deviceCredentialsFormGroup.get('credentialsBasic').disable({emitEvent: false});
197 break; 197 break;
198 case DeviceCredentialsType.X509_CERTIFICATE: 198 case DeviceCredentialsType.X509_CERTIFICATE:
199 - case DeviceCredentialsType.LWM2M_CREDENTIALS:  
200 this.deviceCredentialsFormGroup.get('credentialsValue').setValidators([Validators.required]); 199 this.deviceCredentialsFormGroup.get('credentialsValue').setValidators([Validators.required]);
201 this.deviceCredentialsFormGroup.get('credentialsValue').updateValueAndValidity({emitEvent: false}); 200 this.deviceCredentialsFormGroup.get('credentialsValue').updateValueAndValidity({emitEvent: false});
202 this.deviceCredentialsFormGroup.get('credentialsId').setValidators([]); 201 this.deviceCredentialsFormGroup.get('credentialsId').setValidators([]);
203 this.deviceCredentialsFormGroup.get('credentialsId').updateValueAndValidity({emitEvent: false}); 202 this.deviceCredentialsFormGroup.get('credentialsId').updateValueAndValidity({emitEvent: false});
204 this.deviceCredentialsFormGroup.get('credentialsBasic').disable({emitEvent: false}); 203 this.deviceCredentialsFormGroup.get('credentialsBasic').disable({emitEvent: false});
205 break; 204 break;
  205 + case DeviceCredentialsType.LWM2M_CREDENTIALS:
  206 + this.deviceCredentialsFormGroup.get('credentialsValue').setValidators([Validators.required, this.jsonValidator]);
  207 + this.deviceCredentialsFormGroup.get('credentialsValue').updateValueAndValidity({emitEvent: false});
  208 + this.deviceCredentialsFormGroup.get('credentialsId').setValidators([]);
  209 + this.deviceCredentialsFormGroup.get('credentialsId').updateValueAndValidity({emitEvent: false});
  210 + this.deviceCredentialsFormGroup.get('credentialsBasic').disable({emitEvent: false});
  211 + break;
206 case DeviceCredentialsType.MQTT_BASIC: 212 case DeviceCredentialsType.MQTT_BASIC:
207 this.deviceCredentialsFormGroup.get('credentialsBasic').enable({emitEvent: false}); 213 this.deviceCredentialsFormGroup.get('credentialsBasic').enable({emitEvent: false});
208 this.deviceCredentialsFormGroup.get('credentialsBasic').updateValueAndValidity({emitEvent: false}); 214 this.deviceCredentialsFormGroup.get('credentialsBasic').updateValueAndValidity({emitEvent: false});
@@ -247,7 +253,11 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit, @@ -247,7 +253,11 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit,
247 if (credentialsValue === null || credentialsValue.length === 0) { 253 if (credentialsValue === null || credentialsValue.length === 0) {
248 credentialsValue = getDefaultSecurityConfig(); 254 credentialsValue = getDefaultSecurityConfig();
249 } else { 255 } else {
250 - credentialsValue = JSON.parse(credentialsValue); 256 + try {
  257 + credentialsValue = JSON.parse(credentialsValue);
  258 + } catch (e) {
  259 + credentialsValue = getDefaultSecurityConfig();
  260 + }
251 } 261 }
252 const credentialsId = this.deviceCredentialsFormGroup.get('credentialsId').value || DEFAULT_END_POINT; 262 const credentialsId = this.deviceCredentialsFormGroup.get('credentialsId').value || DEFAULT_END_POINT;
253 this.dialog.open<SecurityConfigComponent, DeviceCredentialsDialogLwm2mData, object>(SecurityConfigComponent, { 263 this.dialog.open<SecurityConfigComponent, DeviceCredentialsDialogLwm2mData, object>(SecurityConfigComponent, {
@@ -273,4 +283,8 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit, @@ -273,4 +283,8 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit,
273 private isDefautLw2mResponse(response: object): boolean { 283 private isDefautLw2mResponse(response: object): boolean {
274 return Object.keys(response).length === 0 || JSON.stringify(response) === '[{}]'; 284 return Object.keys(response).length === 0 || JSON.stringify(response) === '[{}]';
275 } 285 }
  286 +
  287 + private jsonValidator(control: FormControl) {
  288 + return validateSecurityConfig(control.value) ? null: {jsonError: {parsedJson: "error"}};
  289 + }
276 } 290 }
@@ -395,21 +395,4 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro @@ -395,21 +395,4 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
395 } 395 }
396 }); 396 });
397 } 397 }
398 -  
399 - isPathInJson(path: string): boolean {  
400 - let isPath = this.findPathInJson(path, ATTRIBUTE);  
401 - if (!isPath) {  
402 - isPath = this.findPathInJson(path, TELEMETRY);  
403 - }  
404 - return !!isPath;  
405 - }  
406 -  
407 - private findPathInJson = (path: string, side: string): string => {  
408 - if (this.configurationValue.observeAttr) {  
409 - if (this.configurationValue.observeAttr[side]) {  
410 - return this.configurationValue.bootstrap[side].find(  
411 - pathJs => pathJs === path);  
412 - }  
413 - }  
414 - }  
415 } 398 }
@@ -134,7 +134,7 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V @@ -134,7 +134,7 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V
134 } 134 }
135 135
136 private add(object: ObjectLwM2M): void { 136 private add(object: ObjectLwM2M): void {
137 - if (this.modelValue.indexOf(object.id) === -1) { 137 + if (isDefinedAndNotNull(this.modelValue) && this.modelValue.indexOf(object.id) === -1) {
138 this.modelValue.push(object.id); 138 this.modelValue.push(object.id);
139 this.objectsList.push(object); 139 this.objectsList.push(object);
140 this.lwm2mListFormGroup.get('objectsList').setValue(this.objectsList); 140 this.lwm2mListFormGroup.get('objectsList').setValue(this.objectsList);
@@ -151,9 +151,6 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V @@ -151,9 +151,6 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V
151 index = this.modelValue.indexOf(object.id); 151 index = this.modelValue.indexOf(object.id);
152 this.modelValue.splice(index, 1); 152 this.modelValue.splice(index, 1);
153 this.removeList.next(object); 153 this.removeList.next(object);
154 - if (!this.modelValue.length) {  
155 - this.modelValue = null;  
156 - }  
157 this.clear(); 154 this.clear();
158 } 155 }
159 } 156 }
@@ -27,7 +27,7 @@ export const DEFAULT_ID_SERVER = 123; @@ -27,7 +27,7 @@ export const DEFAULT_ID_SERVER = 123;
27 export const DEFAULT_ID_BOOTSTRAP = 111; 27 export const DEFAULT_ID_BOOTSTRAP = 111;
28 export const DEFAULT_HOST_NAME = 'localhost'; 28 export const DEFAULT_HOST_NAME = 'localhost';
29 export const DEFAULT_PORT_SERVER_NO_SEC = 5685; 29 export const DEFAULT_PORT_SERVER_NO_SEC = 5685;
30 -export const DEFAULT_PORT_BOOTSTRAP_NO_SEC = 5686; 30 +export const DEFAULT_PORT_BOOTSTRAP_NO_SEC = 5687;
31 export const DEFAULT_CLIENT_HOLD_OFF_TIME = 1; 31 export const DEFAULT_CLIENT_HOLD_OFF_TIME = 1;
32 export const DEFAULT_LIFE_TIME = 300; 32 export const DEFAULT_LIFE_TIME = 300;
33 export const DEFAULT_MIN_PERIOD = 1; 33 export const DEFAULT_MIN_PERIOD = 1;
@@ -20,7 +20,6 @@ export const DEFAULT_END_POINT = 'default_client_lwm2m_end_point_no_sec'; @@ -20,7 +20,6 @@ export const DEFAULT_END_POINT = 'default_client_lwm2m_end_point_no_sec';
20 export const BOOTSTRAP_SERVERS = 'servers'; 20 export const BOOTSTRAP_SERVERS = 'servers';
21 export const BOOTSTRAP_SERVER = 'bootstrapServer'; 21 export const BOOTSTRAP_SERVER = 'bootstrapServer';
22 export const LWM2M_SERVER = 'lwm2mServer'; 22 export const LWM2M_SERVER = 'lwm2mServer';
23 -export const JSON_OBSERVE = 'jsonObserve';  
24 export const LEN_MAX_PSK = 64; 23 export const LEN_MAX_PSK = 64;
25 export const LEN_MAX_PRIVATE_KEY = 134; 24 export const LEN_MAX_PRIVATE_KEY = 134;
26 export const LEN_MAX_PUBLIC_KEY_RPK = 182; 25 export const LEN_MAX_PUBLIC_KEY_RPK = 182;
@@ -148,4 +147,41 @@ export function getDefaultSecurityConfig(): SecurityConfigModels { @@ -148,4 +147,41 @@ export function getDefaultSecurityConfig(): SecurityConfigModels {
148 return securityConfigModels; 147 return securityConfigModels;
149 } 148 }
150 149
  150 +const isSecurityConfigModels = (p: any): p is SecurityConfigModels =>
  151 + p.hasOwnProperty('client') &&
  152 + isClientSecurityConfigType(p['client']) &&
  153 + p.hasOwnProperty('bootstrap') &&
  154 + isBootstrapSecurityConfig(p['bootstrap']);
  155 +
  156 +const isClientSecurityConfigType = (p: any): p is ClientSecurityConfigType =>
  157 + p.hasOwnProperty('securityConfigClientMode') &&
  158 + p.hasOwnProperty('endpoint') &&
  159 + p.hasOwnProperty('identity') &&
  160 + p.hasOwnProperty('key') &&
  161 + p.hasOwnProperty('x509');
  162 +
  163 +const isBootstrapSecurityConfig = (p: any): p is BootstrapSecurityConfig =>
  164 + p.hasOwnProperty('bootstrapServer') &&
  165 + isServerSecurityConfig(p['bootstrapServer']) &&
  166 + p.hasOwnProperty('lwm2mServer') &&
  167 + isServerSecurityConfig(p['lwm2mServer']);
  168 +
  169 +const isServerSecurityConfig = (p: any): p is ServerSecurityConfig =>
  170 + p.hasOwnProperty('securityMode') &&
  171 + p.hasOwnProperty('clientPublicKeyOrId') &&
  172 + p.hasOwnProperty('clientSecretKey');
  173 +
  174 +export function validateSecurityConfig(config: string): boolean {
  175 + try {
  176 + const securityConfig= JSON.parse(config);
  177 + if (isSecurityConfigModels(securityConfig)) {
  178 + return true;
  179 + } else {
  180 + return false;
  181 + }
  182 + } catch (e) {
  183 + return false;
  184 + }
  185 +}
  186 +
151 187
@@ -912,6 +912,7 @@ @@ -912,6 +912,7 @@
912 "lwm2m-key-required": "LwM2M Security config key is required.", 912 "lwm2m-key-required": "LwM2M Security config key is required.",
913 "lwm2m-value": "LwM2M Security config", 913 "lwm2m-value": "LwM2M Security config",
914 "lwm2m-value-required": "LwM2M Security config value is required.", 914 "lwm2m-value-required": "LwM2M Security config value is required.",
  915 + "lwm2m-value-json-error": "LwM2M Security config value is not json format.",
915 "lwm2m-endpoint": "Client endpoint/identity", 916 "lwm2m-endpoint": "Client endpoint/identity",
916 "lwm2m-security-info": "Security Config Info", 917 "lwm2m-security-info": "Security Config Info",
917 "lwm2m-value-edit": "Edit Security config", 918 "lwm2m-value-edit": "Edit Security config",