Commit e96452cdcf527f6f4b624a8fa78b3086943d9191
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; |
common/cache/pom.xml
0 → 100644
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 |
common/queue/src/main/java/org/thingsboard/server/queue/util/TbLwM2mTransportComponent.java
0 → 100644
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; |
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java
@@ -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> |
transport/lwm2m/src/main/java/org/thingsboard/server/lwm2m/ThingsboardLwm2mTransportApplication.java
@@ -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", |