Commit e86af4b677af78d7d1f60cb5914be70f9cffe6b9
Committed by
GitHub
Merge pull request #4707 from thingsboard/lwm2m-refactoring
LwM2M Refactoring
Showing
38 changed files
with
971 additions
and
789 deletions
@@ -72,15 +72,15 @@ public class DefaultTbResourceService implements TbResourceService { | @@ -72,15 +72,15 @@ public class DefaultTbResourceService implements TbResourceService { | ||
72 | if (ResourceType.LWM2M_MODEL.equals(resource.getResourceType())) { | 72 | if (ResourceType.LWM2M_MODEL.equals(resource.getResourceType())) { |
73 | try { | 73 | try { |
74 | List<ObjectModel> objectModels = | 74 | List<ObjectModel> objectModels = |
75 | - ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(resource.getData())), resource.getSearchText()); | 75 | + ddfFileParser.parse(new ByteArrayInputStream(Base64.getDecoder().decode(resource.getData())), resource.getSearchText()); |
76 | if (!objectModels.isEmpty()) { | 76 | if (!objectModels.isEmpty()) { |
77 | ObjectModel objectModel = objectModels.get(0); | 77 | ObjectModel objectModel = objectModels.get(0); |
78 | 78 | ||
79 | - String resourceKey = objectModel.id + LWM2M_SEPARATOR_KEY + objectModel.getVersion(); | 79 | + String resourceKey = objectModel.id + LWM2M_SEPARATOR_KEY + objectModel.version; |
80 | String name = objectModel.name; | 80 | String name = objectModel.name; |
81 | resource.setResourceKey(resourceKey); | 81 | resource.setResourceKey(resourceKey); |
82 | if (resource.getId() == null) { | 82 | if (resource.getId() == null) { |
83 | - resource.setTitle(name + " id=" + objectModel.id + " v" + objectModel.getVersion()); | 83 | + resource.setTitle(name + " id=" + objectModel.id + " v" + objectModel.version); |
84 | } | 84 | } |
85 | resource.setSearchText(resourceKey + LWM2M_SEPARATOR_SEARCH_TEXT + name); | 85 | resource.setSearchText(resourceKey + LWM2M_SEPARATOR_SEARCH_TEXT + name); |
86 | } else { | 86 | } else { |
@@ -176,7 +176,7 @@ public class DefaultTbResourceService implements TbResourceService { | @@ -176,7 +176,7 @@ public class DefaultTbResourceService implements TbResourceService { | ||
176 | try { | 176 | try { |
177 | DDFFileParser ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator()); | 177 | DDFFileParser ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator()); |
178 | List<ObjectModel> objectModels = | 178 | List<ObjectModel> objectModels = |
179 | - ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(resource.getData())), resource.getSearchText()); | 179 | + ddfFileParser.parse(new ByteArrayInputStream(Base64.getDecoder().decode(resource.getData())), resource.getSearchText()); |
180 | if (objectModels.size() == 0) { | 180 | if (objectModels.size() == 0) { |
181 | return null; | 181 | return null; |
182 | } else { | 182 | } else { |
@@ -60,6 +60,53 @@ import java.util.concurrent.ScheduledExecutorService; | @@ -60,6 +60,53 @@ import java.util.concurrent.ScheduledExecutorService; | ||
60 | @DaoSqlTest | 60 | @DaoSqlTest |
61 | public class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest { | 61 | public class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest { |
62 | 62 | ||
63 | + protected final String TRANSPORT_CONFIGURATION = "{\n" + | ||
64 | + " \"type\": \"LWM2M\",\n" + | ||
65 | + " \"observeAttr\": {\n" + | ||
66 | + " \"keyName\": {\n" + | ||
67 | + " \"/3_1.0/0/9\": \"batteryLevel\"\n" + | ||
68 | + " },\n" + | ||
69 | + " \"observe\": [],\n" + | ||
70 | + " \"attribute\": [\n" + | ||
71 | + " ],\n" + | ||
72 | + " \"telemetry\": [\n" + | ||
73 | + " \"/3_1.0/0/9\"\n" + | ||
74 | + " ],\n" + | ||
75 | + " \"attributeLwm2m\": {}\n" + | ||
76 | + " },\n" + | ||
77 | + " \"bootstrap\": {\n" + | ||
78 | + " \"servers\": {\n" + | ||
79 | + " \"binding\": \"U\",\n" + | ||
80 | + " \"shortId\": 123,\n" + | ||
81 | + " \"lifetime\": 300,\n" + | ||
82 | + " \"notifIfDisabled\": true,\n" + | ||
83 | + " \"defaultMinPeriod\": 1\n" + | ||
84 | + " },\n" + | ||
85 | + " \"lwm2mServer\": {\n" + | ||
86 | + " \"host\": \"localhost\",\n" + | ||
87 | + " \"port\": 5686,\n" + | ||
88 | + " \"serverId\": 123,\n" + | ||
89 | + " \"serverPublicKey\": \"\",\n" + | ||
90 | + " \"bootstrapServerIs\": false,\n" + | ||
91 | + " \"clientHoldOffTime\": 1,\n" + | ||
92 | + " \"bootstrapServerAccountTimeout\": 0\n" + | ||
93 | + " },\n" + | ||
94 | + " \"bootstrapServer\": {\n" + | ||
95 | + " \"host\": \"localhost\",\n" + | ||
96 | + " \"port\": 5687,\n" + | ||
97 | + " \"serverId\": 111,\n" + | ||
98 | + " \"securityMode\": \"NO_SEC\",\n" + | ||
99 | + " \"serverPublicKey\": \"\",\n" + | ||
100 | + " \"bootstrapServerIs\": true,\n" + | ||
101 | + " \"clientHoldOffTime\": 1,\n" + | ||
102 | + " \"bootstrapServerAccountTimeout\": 0\n" + | ||
103 | + " }\n" + | ||
104 | + " },\n" + | ||
105 | + " \"clientLwM2mSettings\": {\n" + | ||
106 | + " \"clientOnlyObserveAfterConnect\": 1\n" + | ||
107 | + " }\n" + | ||
108 | + "}"; | ||
109 | + | ||
63 | protected DeviceProfile deviceProfile; | 110 | protected DeviceProfile deviceProfile; |
64 | protected ScheduledExecutorService executor; | 111 | protected ScheduledExecutorService executor; |
65 | protected TbTestWebSocketClient wsClient; | 112 | protected TbTestWebSocketClient wsClient; |
@@ -22,6 +22,7 @@ import org.junit.Assert; | @@ -22,6 +22,7 @@ import org.junit.Assert; | ||
22 | import org.junit.Test; | 22 | import org.junit.Test; |
23 | import org.thingsboard.common.util.JacksonUtil; | 23 | import org.thingsboard.common.util.JacksonUtil; |
24 | import org.thingsboard.server.common.data.Device; | 24 | import org.thingsboard.server.common.data.Device; |
25 | +import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecClientCredentials; | ||
25 | import org.thingsboard.server.common.data.query.EntityData; | 26 | import org.thingsboard.server.common.data.query.EntityData; |
26 | import org.thingsboard.server.common.data.query.EntityDataPageLink; | 27 | import org.thingsboard.server.common.data.query.EntityDataPageLink; |
27 | import org.thingsboard.server.common.data.query.EntityDataQuery; | 28 | import org.thingsboard.server.common.data.query.EntityDataQuery; |
@@ -36,7 +37,6 @@ import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataUpdate; | @@ -36,7 +37,6 @@ import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataUpdate; | ||
36 | import org.thingsboard.server.service.telemetry.cmd.v2.LatestValueCmd; | 37 | import org.thingsboard.server.service.telemetry.cmd.v2.LatestValueCmd; |
37 | import org.thingsboard.server.transport.lwm2m.client.LwM2MTestClient; | 38 | import org.thingsboard.server.transport.lwm2m.client.LwM2MTestClient; |
38 | import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials; | 39 | import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials; |
39 | -import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecClientCredentials; | ||
40 | 40 | ||
41 | import java.util.Collections; | 41 | import java.util.Collections; |
42 | import java.util.List; | 42 | import java.util.List; |
@@ -46,60 +46,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | @@ -46,60 +46,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | ||
46 | 46 | ||
47 | public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | 47 | public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { |
48 | 48 | ||
49 | - protected final String TRANSPORT_CONFIGURATION = "{\n" + | ||
50 | - " \"type\": \"LWM2M\",\n" + | ||
51 | - " \"observeAttr\": {\n" + | ||
52 | - " \"keyName\": {\n" + | ||
53 | - " \"/3_1.0/0/9\": \"batteryLevel\"\n" + | ||
54 | - " },\n" + | ||
55 | - " \"observe\": [],\n" + | ||
56 | - " \"attribute\": [\n" + | ||
57 | - " ],\n" + | ||
58 | - " \"telemetry\": [\n" + | ||
59 | - " \"/3_1.0/0/9\"\n" + | ||
60 | - " ],\n" + | ||
61 | - " \"attributeLwm2m\": {}\n" + | ||
62 | - " },\n" + | ||
63 | - " \"bootstrap\": {\n" + | ||
64 | - " \"servers\": {\n" + | ||
65 | - " \"binding\": \"UQ\",\n" + | ||
66 | - " \"shortId\": 123,\n" + | ||
67 | - " \"lifetime\": 300,\n" + | ||
68 | - " \"notifIfDisabled\": true,\n" + | ||
69 | - " \"defaultMinPeriod\": 1\n" + | ||
70 | - " },\n" + | ||
71 | - " \"lwm2mServer\": {\n" + | ||
72 | - " \"host\": \"localhost\",\n" + | ||
73 | - " \"port\": 5685,\n" + | ||
74 | - " \"serverId\": 123,\n" + | ||
75 | - " \"securityMode\": \"NO_SEC\",\n" + | ||
76 | - " \"serverPublicKey\": \"\",\n" + | ||
77 | - " \"bootstrapServerIs\": false,\n" + | ||
78 | - " \"clientHoldOffTime\": 1,\n" + | ||
79 | - " \"bootstrapServerAccountTimeout\": 0\n" + | ||
80 | - " },\n" + | ||
81 | - " \"bootstrapServer\": {\n" + | ||
82 | - " \"host\": \"localhost\",\n" + | ||
83 | - " \"port\": 5687,\n" + | ||
84 | - " \"serverId\": 111,\n" + | ||
85 | - " \"securityMode\": \"NO_SEC\",\n" + | ||
86 | - " \"serverPublicKey\": \"\",\n" + | ||
87 | - " \"bootstrapServerIs\": true,\n" + | ||
88 | - " \"clientHoldOffTime\": 1,\n" + | ||
89 | - " \"bootstrapServerAccountTimeout\": 0\n" + | ||
90 | - " }\n" + | ||
91 | - " },\n" + | ||
92 | - " \"clientLwM2mSettings\": {\n" + | ||
93 | - " \"clientOnlyObserveAfterConnect\": 1\n" + | ||
94 | - " }\n" + | ||
95 | - "}"; | ||
96 | - | ||
97 | - private final int port = 5685; | ||
98 | - private final Security security = noSec("coap://localhost:" + port, 123); | ||
99 | - private final NetworkConfig coapConfig = new NetworkConfig().setString("COAP_PORT", Integer.toString(port)); | 49 | + private final int PORT = 5685; |
50 | + private final Security SECURITY = noSec("coap://localhost:" + PORT, 123); | ||
51 | + private final NetworkConfig COAP_CONFIG = new NetworkConfig().setString("COAP_PORT", Integer.toString(PORT)); | ||
52 | + private final String ENDPOINT = "deviceAEndpoint"; | ||
100 | 53 | ||
101 | @NotNull | 54 | @NotNull |
102 | - private Device createDevice(String deviceAEndpoint) throws Exception { | 55 | + private Device createDevice() throws Exception { |
103 | Device device = new Device(); | 56 | Device device = new Device(); |
104 | device.setName("Device A"); | 57 | device.setName("Device A"); |
105 | device.setDeviceProfileId(deviceProfile.getId()); | 58 | device.setDeviceProfileId(deviceProfile.getId()); |
@@ -114,7 +67,7 @@ public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | @@ -114,7 +67,7 @@ public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | ||
114 | 67 | ||
115 | LwM2MCredentials noSecCredentials = new LwM2MCredentials(); | 68 | LwM2MCredentials noSecCredentials = new LwM2MCredentials(); |
116 | NoSecClientCredentials clientCredentials = new NoSecClientCredentials(); | 69 | NoSecClientCredentials clientCredentials = new NoSecClientCredentials(); |
117 | - clientCredentials.setEndpoint(deviceAEndpoint); | 70 | + clientCredentials.setEndpoint(ENDPOINT); |
118 | noSecCredentials.setClient(clientCredentials); | 71 | noSecCredentials.setClient(clientCredentials); |
119 | deviceCredentials.setCredentialsValue(JacksonUtil.toString(noSecCredentials)); | 72 | deviceCredentials.setCredentialsValue(JacksonUtil.toString(noSecCredentials)); |
120 | doPost("/api/device/credentials", deviceCredentials).andExpect(status().isOk()); | 73 | doPost("/api/device/credentials", deviceCredentials).andExpect(status().isOk()); |
@@ -125,9 +78,7 @@ public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | @@ -125,9 +78,7 @@ public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | ||
125 | public void testConnectAndObserveTelemetry() throws Exception { | 78 | public void testConnectAndObserveTelemetry() throws Exception { |
126 | createDeviceProfile(TRANSPORT_CONFIGURATION); | 79 | createDeviceProfile(TRANSPORT_CONFIGURATION); |
127 | 80 | ||
128 | - String deviceAEndpoint = "deviceAEndpoint"; | ||
129 | - | ||
130 | - Device device = createDevice(deviceAEndpoint); | 81 | + Device device = createDevice(); |
131 | 82 | ||
132 | SingleEntityFilter sef = new SingleEntityFilter(); | 83 | SingleEntityFilter sef = new SingleEntityFilter(); |
133 | sef.setSingleEntity(device.getId()); | 84 | sef.setSingleEntity(device.getId()); |
@@ -144,8 +95,8 @@ public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | @@ -144,8 +95,8 @@ public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | ||
144 | wsClient.waitForReply(); | 95 | wsClient.waitForReply(); |
145 | 96 | ||
146 | wsClient.registerWaitForUpdate(); | 97 | wsClient.registerWaitForUpdate(); |
147 | - LwM2MTestClient client = new LwM2MTestClient(executor, deviceAEndpoint); | ||
148 | - client.init(security, coapConfig); | 98 | + LwM2MTestClient client = new LwM2MTestClient(executor, ENDPOINT); |
99 | + client.init(SECURITY, COAP_CONFIG); | ||
149 | String msg = wsClient.waitForUpdate(); | 100 | String msg = wsClient.waitForUpdate(); |
150 | 101 | ||
151 | EntityDataUpdate update = mapper.readValue(msg, EntityDataUpdate.class); | 102 | EntityDataUpdate update = mapper.readValue(msg, EntityDataUpdate.class); |
@@ -47,54 +47,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | @@ -47,54 +47,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | ||
47 | 47 | ||
48 | public class X509LwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | 48 | public class X509LwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { |
49 | 49 | ||
50 | - protected final String TRANSPORT_CONFIGURATION = "{\n" + | ||
51 | - " \"type\": \"LWM2M\",\n" + | ||
52 | - " \"observeAttr\": {\n" + | ||
53 | - " \"keyName\": {\n" + | ||
54 | - " \"/3_1.0/0/9\": \"batteryLevel\"\n" + | ||
55 | - " },\n" + | ||
56 | - " \"observe\": [],\n" + | ||
57 | - " \"attribute\": [\n" + | ||
58 | - " ],\n" + | ||
59 | - " \"telemetry\": [\n" + | ||
60 | - " \"/3_1.0/0/9\"\n" + | ||
61 | - " ],\n" + | ||
62 | - " \"attributeLwm2m\": {}\n" + | ||
63 | - " },\n" + | ||
64 | - " \"bootstrap\": {\n" + | ||
65 | - " \"servers\": {\n" + | ||
66 | - " \"binding\": \"UQ\",\n" + | ||
67 | - " \"shortId\": 123,\n" + | ||
68 | - " \"lifetime\": 300,\n" + | ||
69 | - " \"notifIfDisabled\": true,\n" + | ||
70 | - " \"defaultMinPeriod\": 1\n" + | ||
71 | - " },\n" + | ||
72 | - " \"lwm2mServer\": {\n" + | ||
73 | - " \"host\": \"localhost\",\n" + | ||
74 | - " \"port\": 5686,\n" + | ||
75 | - " \"serverId\": 123,\n" + | ||
76 | - " \"serverPublicKey\": \"\",\n" + | ||
77 | - " \"bootstrapServerIs\": false,\n" + | ||
78 | - " \"clientHoldOffTime\": 1,\n" + | ||
79 | - " \"bootstrapServerAccountTimeout\": 0\n" + | ||
80 | - " },\n" + | ||
81 | - " \"bootstrapServer\": {\n" + | ||
82 | - " \"host\": \"localhost\",\n" + | ||
83 | - " \"port\": 5687,\n" + | ||
84 | - " \"serverId\": 111,\n" + | ||
85 | - " \"securityMode\": \"NO_SEC\",\n" + | ||
86 | - " \"serverPublicKey\": \"\",\n" + | ||
87 | - " \"bootstrapServerIs\": true,\n" + | ||
88 | - " \"clientHoldOffTime\": 1,\n" + | ||
89 | - " \"bootstrapServerAccountTimeout\": 0\n" + | ||
90 | - " }\n" + | ||
91 | - " },\n" + | ||
92 | - " \"clientLwM2mSettings\": {\n" + | ||
93 | - " \"clientOnlyObserveAfterConnect\": 1\n" + | ||
94 | - " }\n" + | ||
95 | - "}"; | ||
96 | - | ||
97 | - | ||
98 | private final int port = 5686; | 50 | private final int port = 5686; |
99 | private final NetworkConfig coapConfig = new NetworkConfig().setString("COAP_SECURE_PORT", Integer.toString(port)); | 51 | private final NetworkConfig coapConfig = new NetworkConfig().setString("COAP_SECURE_PORT", Integer.toString(port)); |
100 | private final String endpoint = "deviceAEndpoint"; | 52 | private final String endpoint = "deviceAEndpoint"; |
@@ -17,40 +17,37 @@ package org.thingsboard.server.transport.lwm2m.client; | @@ -17,40 +17,37 @@ package org.thingsboard.server.transport.lwm2m.client; | ||
17 | 17 | ||
18 | import lombok.Data; | 18 | import lombok.Data; |
19 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
20 | +import org.eclipse.californium.core.network.CoapEndpoint; | ||
20 | import org.eclipse.californium.core.network.config.NetworkConfig; | 21 | import org.eclipse.californium.core.network.config.NetworkConfig; |
21 | -import org.eclipse.californium.elements.Connector; | 22 | +import org.eclipse.californium.core.observe.ObservationStore; |
22 | import org.eclipse.californium.scandium.DTLSConnector; | 23 | import org.eclipse.californium.scandium.DTLSConnector; |
23 | import org.eclipse.californium.scandium.config.DtlsConnectorConfig; | 24 | import org.eclipse.californium.scandium.config.DtlsConnectorConfig; |
24 | -import org.eclipse.californium.scandium.dtls.ClientHandshaker; | ||
25 | -import org.eclipse.californium.scandium.dtls.DTLSSession; | ||
26 | -import org.eclipse.californium.scandium.dtls.HandshakeException; | ||
27 | -import org.eclipse.californium.scandium.dtls.Handshaker; | ||
28 | -import org.eclipse.californium.scandium.dtls.ResumingClientHandshaker; | ||
29 | -import org.eclipse.californium.scandium.dtls.ResumingServerHandshaker; | ||
30 | -import org.eclipse.californium.scandium.dtls.ServerHandshaker; | ||
31 | -import org.eclipse.californium.scandium.dtls.SessionAdapter; | ||
32 | import org.eclipse.leshan.client.californium.LeshanClient; | 25 | import org.eclipse.leshan.client.californium.LeshanClient; |
33 | import org.eclipse.leshan.client.californium.LeshanClientBuilder; | 26 | import org.eclipse.leshan.client.californium.LeshanClientBuilder; |
34 | import org.eclipse.leshan.client.engine.DefaultRegistrationEngineFactory; | 27 | import org.eclipse.leshan.client.engine.DefaultRegistrationEngineFactory; |
35 | import org.eclipse.leshan.client.object.Security; | 28 | import org.eclipse.leshan.client.object.Security; |
36 | import org.eclipse.leshan.client.object.Server; | 29 | import org.eclipse.leshan.client.object.Server; |
37 | import org.eclipse.leshan.client.observer.LwM2mClientObserver; | 30 | import org.eclipse.leshan.client.observer.LwM2mClientObserver; |
31 | +import org.eclipse.leshan.client.resource.DummyInstanceEnabler; | ||
38 | import org.eclipse.leshan.client.resource.ObjectsInitializer; | 32 | import org.eclipse.leshan.client.resource.ObjectsInitializer; |
39 | import org.eclipse.leshan.client.servers.ServerIdentity; | 33 | import org.eclipse.leshan.client.servers.ServerIdentity; |
34 | +import org.eclipse.leshan.core.LwM2mId; | ||
40 | import org.eclipse.leshan.core.ResponseCode; | 35 | import org.eclipse.leshan.core.ResponseCode; |
41 | -import org.eclipse.leshan.core.californium.DefaultEndpointFactory; | 36 | +import org.eclipse.leshan.core.californium.EndpointFactory; |
37 | +import org.eclipse.leshan.core.model.InvalidDDFFileException; | ||
42 | import org.eclipse.leshan.core.model.LwM2mModel; | 38 | import org.eclipse.leshan.core.model.LwM2mModel; |
43 | import org.eclipse.leshan.core.model.ObjectLoader; | 39 | import org.eclipse.leshan.core.model.ObjectLoader; |
44 | import org.eclipse.leshan.core.model.ObjectModel; | 40 | import org.eclipse.leshan.core.model.ObjectModel; |
45 | import org.eclipse.leshan.core.model.StaticModel; | 41 | import org.eclipse.leshan.core.model.StaticModel; |
46 | import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeDecoder; | 42 | import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeDecoder; |
47 | import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeEncoder; | 43 | import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeEncoder; |
48 | -import org.eclipse.leshan.core.request.BindingMode; | ||
49 | import org.eclipse.leshan.core.request.BootstrapRequest; | 44 | import org.eclipse.leshan.core.request.BootstrapRequest; |
50 | import org.eclipse.leshan.core.request.DeregisterRequest; | 45 | import org.eclipse.leshan.core.request.DeregisterRequest; |
51 | import org.eclipse.leshan.core.request.RegisterRequest; | 46 | import org.eclipse.leshan.core.request.RegisterRequest; |
52 | import org.eclipse.leshan.core.request.UpdateRequest; | 47 | import org.eclipse.leshan.core.request.UpdateRequest; |
53 | 48 | ||
49 | +import java.io.IOException; | ||
50 | +import java.net.InetSocketAddress; | ||
54 | import java.util.ArrayList; | 51 | import java.util.ArrayList; |
55 | import java.util.List; | 52 | import java.util.List; |
56 | import java.util.concurrent.ScheduledExecutorService; | 53 | import java.util.concurrent.ScheduledExecutorService; |
@@ -67,7 +64,7 @@ public class LwM2MTestClient { | @@ -67,7 +64,7 @@ public class LwM2MTestClient { | ||
67 | private final String endpoint; | 64 | private final String endpoint; |
68 | private LeshanClient client; | 65 | private LeshanClient client; |
69 | 66 | ||
70 | - public void init(Security security, NetworkConfig coapConfig) { | 67 | + public void init(Security security, NetworkConfig coapConfig) throws InvalidDDFFileException, IOException { |
71 | String[] resources = new String[]{"0.xml", "1.xml", "2.xml", "3.xml"}; | 68 | String[] resources = new String[]{"0.xml", "1.xml", "2.xml", "3.xml"}; |
72 | List<ObjectModel> models = new ArrayList<>(); | 69 | List<ObjectModel> models = new ArrayList<>(); |
73 | for (String resourceName : resources) { | 70 | for (String resourceName : resources) { |
@@ -76,82 +73,51 @@ public class LwM2MTestClient { | @@ -76,82 +73,51 @@ public class LwM2MTestClient { | ||
76 | LwM2mModel model = new StaticModel(models); | 73 | LwM2mModel model = new StaticModel(models); |
77 | ObjectsInitializer initializer = new ObjectsInitializer(model); | 74 | ObjectsInitializer initializer = new ObjectsInitializer(model); |
78 | initializer.setInstancesForObject(SECURITY, security); | 75 | initializer.setInstancesForObject(SECURITY, security); |
79 | - initializer.setInstancesForObject(SERVER, new Server(123, 300, BindingMode.U, false)); | 76 | + initializer.setInstancesForObject(SERVER, new Server(123, 300)); |
80 | initializer.setInstancesForObject(DEVICE, new SimpleLwM2MDevice()); | 77 | initializer.setInstancesForObject(DEVICE, new SimpleLwM2MDevice()); |
78 | + initializer.setClassForObject(LwM2mId.ACCESS_CONTROL, DummyInstanceEnabler.class); | ||
81 | 79 | ||
82 | DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder(); | 80 | DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder(); |
83 | dtlsConfig.setRecommendedCipherSuitesOnly(true); | 81 | dtlsConfig.setRecommendedCipherSuitesOnly(true); |
82 | + dtlsConfig.setClientOnly(); | ||
84 | 83 | ||
85 | DefaultRegistrationEngineFactory engineFactory = new DefaultRegistrationEngineFactory(); | 84 | DefaultRegistrationEngineFactory engineFactory = new DefaultRegistrationEngineFactory(); |
86 | engineFactory.setReconnectOnUpdate(false); | 85 | engineFactory.setReconnectOnUpdate(false); |
87 | engineFactory.setResumeOnConnect(true); | 86 | engineFactory.setResumeOnConnect(true); |
88 | 87 | ||
89 | - DefaultEndpointFactory endpointFactory = new DefaultEndpointFactory(endpoint) { | 88 | + EndpointFactory endpointFactory = new EndpointFactory() { |
89 | + | ||
90 | @Override | 90 | @Override |
91 | - protected Connector createSecuredConnector(DtlsConnectorConfig dtlsConfig) { | ||
92 | - | ||
93 | - return new DTLSConnector(dtlsConfig) { | ||
94 | - @Override | ||
95 | - protected void onInitializeHandshaker(Handshaker handshaker) { | ||
96 | - handshaker.addSessionListener(new SessionAdapter() { | ||
97 | - | ||
98 | - @Override | ||
99 | - public void handshakeStarted(Handshaker handshaker) throws HandshakeException { | ||
100 | - if (handshaker instanceof ServerHandshaker) { | ||
101 | - log.info("DTLS Full Handshake initiated by server : STARTED ..."); | ||
102 | - } else if (handshaker instanceof ResumingServerHandshaker) { | ||
103 | - log.info("DTLS abbreviated Handshake initiated by server : STARTED ..."); | ||
104 | - } else if (handshaker instanceof ClientHandshaker) { | ||
105 | - log.info("DTLS Full Handshake initiated by client : STARTED ..."); | ||
106 | - } else if (handshaker instanceof ResumingClientHandshaker) { | ||
107 | - log.info("DTLS abbreviated Handshake initiated by client : STARTED ..."); | ||
108 | - } | ||
109 | - } | ||
110 | - | ||
111 | - @Override | ||
112 | - public void sessionEstablished(Handshaker handshaker, DTLSSession establishedSession) | ||
113 | - throws HandshakeException { | ||
114 | - if (handshaker instanceof ServerHandshaker) { | ||
115 | - log.info("DTLS Full Handshake initiated by server : SUCCEED, handshaker {}", handshaker); | ||
116 | - } else if (handshaker instanceof ResumingServerHandshaker) { | ||
117 | - log.info("DTLS abbreviated Handshake initiated by server : SUCCEED, handshaker {}", handshaker); | ||
118 | - } else if (handshaker instanceof ClientHandshaker) { | ||
119 | - log.info("DTLS Full Handshake initiated by client : SUCCEED, handshaker {}", handshaker); | ||
120 | - } else if (handshaker instanceof ResumingClientHandshaker) { | ||
121 | - log.info("DTLS abbreviated Handshake initiated by client : SUCCEED, handshaker {}", handshaker); | ||
122 | - } | ||
123 | - } | ||
124 | - | ||
125 | - @Override | ||
126 | - public void handshakeFailed(Handshaker handshaker, Throwable error) { | ||
127 | - /** get cause */ | ||
128 | - String cause; | ||
129 | - if (error != null) { | ||
130 | - if (error.getMessage() != null) { | ||
131 | - cause = error.getMessage(); | ||
132 | - } else { | ||
133 | - cause = error.getClass().getName(); | ||
134 | - } | ||
135 | - } else { | ||
136 | - cause = "unknown cause"; | ||
137 | - } | ||
138 | - | ||
139 | - if (handshaker instanceof ServerHandshaker) { | ||
140 | - log.info("DTLS Full Handshake initiated by server : FAILED [{}]", cause); | ||
141 | - } else if (handshaker instanceof ResumingServerHandshaker) { | ||
142 | - log.info("DTLS abbreviated Handshake initiated by server : FAILED [{}]", cause); | ||
143 | - } else if (handshaker instanceof ClientHandshaker) { | ||
144 | - log.info("DTLS Full Handshake initiated by client : FAILED [{}]", cause); | ||
145 | - } else if (handshaker instanceof ResumingClientHandshaker) { | ||
146 | - log.info("DTLS abbreviated Handshake initiated by client : FAILED [{}]", cause); | ||
147 | - } | ||
148 | - } | ||
149 | - }); | ||
150 | - } | ||
151 | - }; | 91 | + public CoapEndpoint createUnsecuredEndpoint(InetSocketAddress address, NetworkConfig coapConfig, |
92 | + ObservationStore store) { | ||
93 | + CoapEndpoint.Builder builder = new CoapEndpoint.Builder(); | ||
94 | + builder.setInetSocketAddress(address); | ||
95 | + builder.setNetworkConfig(coapConfig); | ||
96 | + return builder.build(); | ||
97 | + } | ||
98 | + | ||
99 | + @Override | ||
100 | + public CoapEndpoint createSecuredEndpoint(DtlsConnectorConfig dtlsConfig, NetworkConfig coapConfig, | ||
101 | + ObservationStore store) { | ||
102 | + CoapEndpoint.Builder builder = new CoapEndpoint.Builder(); | ||
103 | + DtlsConnectorConfig.Builder dtlsConfigBuilder = new DtlsConnectorConfig.Builder(dtlsConfig); | ||
104 | + | ||
105 | + // tricks to be able to change psk information on the fly | ||
106 | +// AdvancedPskStore pskStore = dtlsConfig.getAdvancedPskStore(); | ||
107 | +// if (pskStore != null) { | ||
108 | +// PskPublicInformation identity = pskStore.getIdentity(null, null); | ||
109 | +// SecretKey key = pskStore | ||
110 | +// .requestPskSecretResult(ConnectionId.EMPTY, null, identity, null, null, null).getSecret(); | ||
111 | +// singlePSKStore = new SinglePSKStore(identity, key); | ||
112 | +// dtlsConfigBuilder.setAdvancedPskStore(singlePSKStore); | ||
113 | +// } | ||
114 | + builder.setConnector(new DTLSConnector(dtlsConfigBuilder.build())); | ||
115 | + builder.setNetworkConfig(coapConfig); | ||
116 | + return builder.build(); | ||
152 | } | 117 | } |
153 | }; | 118 | }; |
154 | 119 | ||
120 | + | ||
155 | LeshanClientBuilder builder = new LeshanClientBuilder(endpoint); | 121 | LeshanClientBuilder builder = new LeshanClientBuilder(endpoint); |
156 | builder.setLocalAddress("0.0.0.0", 11000); | 122 | builder.setLocalAddress("0.0.0.0", 11000); |
157 | builder.setObjects(initializer.createAll()); | 123 | builder.setObjects(initializer.createAll()); |
@@ -246,6 +212,11 @@ public class LwM2MTestClient { | @@ -246,6 +212,11 @@ public class LwM2MTestClient { | ||
246 | public void onDeregistrationTimeout(ServerIdentity server, DeregisterRequest request) { | 212 | public void onDeregistrationTimeout(ServerIdentity server, DeregisterRequest request) { |
247 | log.info("ClientObserver ->onDeregistrationTimeout... DeregisterRequest [{}] [{}]", request.getRegistrationId(), request.getRegistrationId()); | 213 | log.info("ClientObserver ->onDeregistrationTimeout... DeregisterRequest [{}] [{}]", request.getRegistrationId(), request.getRegistrationId()); |
248 | } | 214 | } |
215 | + | ||
216 | + @Override | ||
217 | + public void onUnexpectedError(Throwable unexpectedError) { | ||
218 | + | ||
219 | + } | ||
249 | }; | 220 | }; |
250 | this.client.addObserver(observer); | 221 | this.client.addObserver(observer); |
251 | 222 |
@@ -97,7 +97,7 @@ public class SimpleLwM2MDevice extends BaseInstanceEnabler implements Destroyabl | @@ -97,7 +97,7 @@ public class SimpleLwM2MDevice extends BaseInstanceEnabler implements Destroyabl | ||
97 | } | 97 | } |
98 | 98 | ||
99 | @Override | 99 | @Override |
100 | - public WriteResponse write(ServerIdentity identity, int resourceid, LwM2mResource value) { | 100 | + public WriteResponse write(ServerIdentity identity, boolean replace, int resourceid, LwM2mResource value) { |
101 | log.info("Write on Device resource /{}/{}/{}", getModel().id, getId(), resourceid); | 101 | log.info("Write on Device resource /{}/{}/{}", getModel().id, getId(), resourceid); |
102 | 102 | ||
103 | switch (resourceid) { | 103 | switch (resourceid) { |
@@ -112,7 +112,7 @@ public class SimpleLwM2MDevice extends BaseInstanceEnabler implements Destroyabl | @@ -112,7 +112,7 @@ public class SimpleLwM2MDevice extends BaseInstanceEnabler implements Destroyabl | ||
112 | fireResourcesChange(resourceid); | 112 | fireResourcesChange(resourceid); |
113 | return WriteResponse.success(); | 113 | return WriteResponse.success(); |
114 | default: | 114 | default: |
115 | - return super.write(identity, resourceid, value); | 115 | + return super.write(identity, replace, resourceid, value); |
116 | } | 116 | } |
117 | } | 117 | } |
118 | 118 |
No preview for this file type
No preview for this file type
@@ -109,8 +109,8 @@ public class LwM2MTransportBootstrapService { | @@ -109,8 +109,8 @@ public class LwM2MTransportBootstrapService { | ||
109 | /** Create credentials */ | 109 | /** Create credentials */ |
110 | this.setServerWithCredentials(builder); | 110 | this.setServerWithCredentials(builder); |
111 | 111 | ||
112 | - /** Set securityStore with new ConfigStore */ | ||
113 | - builder.setConfigStore(lwM2MInMemoryBootstrapConfigStore); | 112 | +// /** Set securityStore with new ConfigStore */ |
113 | +// builder.setConfigStore(lwM2MInMemoryBootstrapConfigStore); | ||
114 | 114 | ||
115 | /** SecurityStore */ | 115 | /** SecurityStore */ |
116 | builder.setSecurityStore(lwM2MBootstrapSecurityStore); | 116 | builder.setSecurityStore(lwM2MBootstrapSecurityStore); |
@@ -69,7 +69,7 @@ public class LwM2MBootstrapConfig { | @@ -69,7 +69,7 @@ public class LwM2MBootstrapConfig { | ||
69 | server0.lifetime = servers.getLifetime(); | 69 | server0.lifetime = servers.getLifetime(); |
70 | server0.defaultMinPeriod = servers.getDefaultMinPeriod(); | 70 | server0.defaultMinPeriod = servers.getDefaultMinPeriod(); |
71 | server0.notifIfDisabled = servers.isNotifIfDisabled(); | 71 | server0.notifIfDisabled = servers.isNotifIfDisabled(); |
72 | - server0.binding = BindingMode.valueOf(servers.getBinding()); | 72 | + server0.binding = BindingMode.parse(servers.getBinding()); |
73 | configBs.servers.put(0, server0); | 73 | configBs.servers.put(0, server0); |
74 | /* Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Bootstrap instance = 0 */ | 74 | /* Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Bootstrap instance = 0 */ |
75 | this.bootstrapServer.setBootstrapServerIs(true); | 75 | this.bootstrapServer.setBootstrapServerIs(true); |
@@ -30,7 +30,7 @@ import org.eclipse.leshan.server.security.SecurityInfo; | @@ -30,7 +30,7 @@ import org.eclipse.leshan.server.security.SecurityInfo; | ||
30 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | 30 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
31 | import org.springframework.stereotype.Service; | 31 | import org.springframework.stereotype.Service; |
32 | import org.thingsboard.server.gen.transport.TransportProtos; | 32 | import org.thingsboard.server.gen.transport.TransportProtos; |
33 | -import org.thingsboard.server.transport.lwm2m.secure.EndpointSecurityInfo; | 33 | +import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; |
34 | import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; | 34 | import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; |
35 | import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener; | 35 | import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener; |
36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; | 36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; |
@@ -40,7 +40,7 @@ import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; | @@ -40,7 +40,7 @@ import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; | ||
40 | import java.io.IOException; | 40 | import java.io.IOException; |
41 | import java.security.GeneralSecurityException; | 41 | import java.security.GeneralSecurityException; |
42 | import java.util.Collections; | 42 | import java.util.Collections; |
43 | -import java.util.List; | 43 | +import java.util.Iterator; |
44 | import java.util.UUID; | 44 | import java.util.UUID; |
45 | 45 | ||
46 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.BOOTSTRAP_SERVER; | 46 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.BOOTSTRAP_SERVER; |
@@ -71,8 +71,8 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | @@ -71,8 +71,8 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | ||
71 | } | 71 | } |
72 | 72 | ||
73 | @Override | 73 | @Override |
74 | - public List<SecurityInfo> getAllByEndpoint(String endPoint) { | ||
75 | - EndpointSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(endPoint, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP); | 74 | + public Iterator<SecurityInfo> getAllByEndpoint(String endPoint) { |
75 | + TbLwM2MSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfoByCredentialsId(endPoint, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP); | ||
76 | if (store.getBootstrapCredentialConfig() != null && store.getSecurityMode() != null) { | 76 | if (store.getBootstrapCredentialConfig() != null && store.getSecurityMode() != null) { |
77 | /* add value to store from BootstrapJson */ | 77 | /* add value to store from BootstrapJson */ |
78 | this.setBootstrapConfigScurityInfo(store); | 78 | this.setBootstrapConfigScurityInfo(store); |
@@ -88,7 +88,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | @@ -88,7 +88,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | ||
88 | } catch (InvalidConfigurationException e) { | 88 | } catch (InvalidConfigurationException e) { |
89 | log.error("", e); | 89 | log.error("", e); |
90 | } | 90 | } |
91 | - return store.getSecurityInfo() == null ? null : Collections.singletonList(store.getSecurityInfo()); | 91 | + return store.getSecurityInfo() == null ? null : Collections.singletonList(store.getSecurityInfo()).iterator(); |
92 | } | 92 | } |
93 | } | 93 | } |
94 | return null; | 94 | return null; |
@@ -96,7 +96,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | @@ -96,7 +96,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | ||
96 | 96 | ||
97 | @Override | 97 | @Override |
98 | public SecurityInfo getByIdentity(String identity) { | 98 | public SecurityInfo getByIdentity(String identity) { |
99 | - EndpointSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(identity, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP); | 99 | + TbLwM2MSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfoByCredentialsId(identity, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP); |
100 | if (store.getBootstrapCredentialConfig() != null && store.getSecurityMode() != null) { | 100 | if (store.getBootstrapCredentialConfig() != null && store.getSecurityMode() != null) { |
101 | /* add value to store from BootstrapJson */ | 101 | /* add value to store from BootstrapJson */ |
102 | this.setBootstrapConfigScurityInfo(store); | 102 | this.setBootstrapConfigScurityInfo(store); |
@@ -113,7 +113,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | @@ -113,7 +113,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | ||
113 | return null; | 113 | return null; |
114 | } | 114 | } |
115 | 115 | ||
116 | - private void setBootstrapConfigScurityInfo(EndpointSecurityInfo store) { | 116 | + private void setBootstrapConfigScurityInfo(TbLwM2MSecurityInfo store) { |
117 | /* BootstrapConfig */ | 117 | /* BootstrapConfig */ |
118 | LwM2MBootstrapConfig lwM2MBootstrapConfig = this.getParametersBootstrap(store); | 118 | LwM2MBootstrapConfig lwM2MBootstrapConfig = this.getParametersBootstrap(store); |
119 | if (lwM2MBootstrapConfig != null) { | 119 | if (lwM2MBootstrapConfig != null) { |
@@ -150,7 +150,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | @@ -150,7 +150,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | ||
150 | } | 150 | } |
151 | } | 151 | } |
152 | 152 | ||
153 | - private LwM2MBootstrapConfig getParametersBootstrap(EndpointSecurityInfo store) { | 153 | + private LwM2MBootstrapConfig getParametersBootstrap(TbLwM2MSecurityInfo store) { |
154 | try { | 154 | try { |
155 | LwM2MBootstrapConfig lwM2MBootstrapConfig = store.getBootstrapCredentialConfig(); | 155 | LwM2MBootstrapConfig lwM2MBootstrapConfig = store.getBootstrapCredentialConfig(); |
156 | if (lwM2MBootstrapConfig != null) { | 156 | if (lwM2MBootstrapConfig != null) { |
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | package org.thingsboard.server.transport.lwm2m.bootstrap.secure; | 16 | package org.thingsboard.server.transport.lwm2m.bootstrap.secure; |
17 | 17 | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | +import org.eclipse.leshan.core.request.BootstrapRequest; | ||
19 | import org.eclipse.leshan.core.request.Identity; | 20 | import org.eclipse.leshan.core.request.Identity; |
20 | import org.eclipse.leshan.server.bootstrap.BootstrapSession; | 21 | import org.eclipse.leshan.server.bootstrap.BootstrapSession; |
21 | import org.eclipse.leshan.server.bootstrap.DefaultBootstrapSession; | 22 | import org.eclipse.leshan.server.bootstrap.DefaultBootstrapSession; |
@@ -25,7 +26,7 @@ import org.eclipse.leshan.server.security.SecurityChecker; | @@ -25,7 +26,7 @@ import org.eclipse.leshan.server.security.SecurityChecker; | ||
25 | import org.eclipse.leshan.server.security.SecurityInfo; | 26 | import org.eclipse.leshan.server.security.SecurityInfo; |
26 | 27 | ||
27 | import java.util.Collections; | 28 | import java.util.Collections; |
28 | -import java.util.List; | 29 | +import java.util.Iterator; |
29 | 30 | ||
30 | @Slf4j | 31 | @Slf4j |
31 | public class LwM2mDefaultBootstrapSessionManager extends DefaultBootstrapSessionManager { | 32 | public class LwM2mDefaultBootstrapSessionManager extends DefaultBootstrapSessionManager { |
@@ -50,16 +51,17 @@ public class LwM2mDefaultBootstrapSessionManager extends DefaultBootstrapSession | @@ -50,16 +51,17 @@ public class LwM2mDefaultBootstrapSessionManager extends DefaultBootstrapSession | ||
50 | } | 51 | } |
51 | 52 | ||
52 | @SuppressWarnings("deprecation") | 53 | @SuppressWarnings("deprecation") |
53 | - public BootstrapSession begin(String endpoint, Identity clientIdentity) { | 54 | + public BootstrapSession begin(BootstrapRequest request, Identity clientIdentity) { |
54 | boolean authorized; | 55 | boolean authorized; |
55 | if (bsSecurityStore != null) { | 56 | if (bsSecurityStore != null) { |
56 | - List<SecurityInfo> securityInfos = (clientIdentity.getPskIdentity() != null && !clientIdentity.getPskIdentity().isEmpty()) ? Collections.singletonList(bsSecurityStore.getByIdentity(clientIdentity.getPskIdentity())) : bsSecurityStore.getAllByEndpoint(endpoint); | 57 | + Iterator<SecurityInfo> securityInfos = (clientIdentity.getPskIdentity() != null && !clientIdentity.getPskIdentity().isEmpty()) ? |
58 | + Collections.singletonList(bsSecurityStore.getByIdentity(clientIdentity.getPskIdentity())).iterator() : bsSecurityStore.getAllByEndpoint(request.getEndpointName()); | ||
57 | log.info("Bootstrap session started securityInfos: [{}]", securityInfos); | 59 | log.info("Bootstrap session started securityInfos: [{}]", securityInfos); |
58 | - authorized = securityChecker.checkSecurityInfos(endpoint, clientIdentity, securityInfos); | 60 | + authorized = securityChecker.checkSecurityInfos(request.getEndpointName(), clientIdentity, securityInfos); |
59 | } else { | 61 | } else { |
60 | authorized = true; | 62 | authorized = true; |
61 | } | 63 | } |
62 | - DefaultBootstrapSession session = new DefaultBootstrapSession(endpoint, clientIdentity, authorized); | 64 | + DefaultBootstrapSession session = new DefaultBootstrapSession(request, clientIdentity, authorized); |
63 | log.info("Bootstrap session started : {}", session); | 65 | log.info("Bootstrap session started : {}", session); |
64 | return session; | 66 | return session; |
65 | } | 67 | } |
@@ -22,16 +22,16 @@ import org.eclipse.leshan.server.security.SecurityInfo; | @@ -22,16 +22,16 @@ import org.eclipse.leshan.server.security.SecurityInfo; | ||
22 | import org.springframework.stereotype.Component; | 22 | import org.springframework.stereotype.Component; |
23 | import org.thingsboard.common.util.JacksonUtil; | 23 | import org.thingsboard.common.util.JacksonUtil; |
24 | import org.thingsboard.server.common.data.StringUtils; | 24 | import org.thingsboard.server.common.data.StringUtils; |
25 | +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MClientCredentials; | ||
25 | import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; | 26 | import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; |
27 | +import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredentials; | ||
28 | +import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKClientCredentials; | ||
26 | import org.thingsboard.server.common.transport.TransportServiceCallback; | 29 | import org.thingsboard.server.common.transport.TransportServiceCallback; |
27 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | 30 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
28 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg; | 31 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg; |
29 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | 32 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
30 | import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; | 33 | import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; |
31 | -import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MClientCredentials; | ||
32 | import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials; | 34 | import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials; |
33 | -import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredentials; | ||
34 | -import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKClientCredentials; | ||
35 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; | 35 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; |
36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; | 36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; |
37 | 37 | ||
@@ -55,15 +55,15 @@ public class LwM2mCredentialsSecurityInfoValidator { | @@ -55,15 +55,15 @@ public class LwM2mCredentialsSecurityInfoValidator { | ||
55 | private final LwM2mTransportContext context; | 55 | private final LwM2mTransportContext context; |
56 | private final LwM2MTransportServerConfig config; | 56 | private final LwM2MTransportServerConfig config; |
57 | 57 | ||
58 | - public EndpointSecurityInfo getEndpointSecurityInfo(String endpoint, LwM2mTransportUtil.LwM2mTypeServer keyValue) { | 58 | + public TbLwM2MSecurityInfo getEndpointSecurityInfoByCredentialsId(String credentialsId, LwM2mTransportUtil.LwM2mTypeServer keyValue) { |
59 | CountDownLatch latch = new CountDownLatch(1); | 59 | CountDownLatch latch = new CountDownLatch(1); |
60 | - final EndpointSecurityInfo[] resultSecurityStore = new EndpointSecurityInfo[1]; | ||
61 | - context.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endpoint).build(), | 60 | + final TbLwM2MSecurityInfo[] resultSecurityStore = new TbLwM2MSecurityInfo[1]; |
61 | + context.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(credentialsId).build(), | ||
62 | new TransportServiceCallback<>() { | 62 | new TransportServiceCallback<>() { |
63 | @Override | 63 | @Override |
64 | public void onSuccess(ValidateDeviceCredentialsResponse msg) { | 64 | public void onSuccess(ValidateDeviceCredentialsResponse msg) { |
65 | String credentialsBody = msg.getCredentials(); | 65 | String credentialsBody = msg.getCredentials(); |
66 | - resultSecurityStore[0] = createSecurityInfo(endpoint, credentialsBody, keyValue); | 66 | + resultSecurityStore[0] = createSecurityInfo(credentialsId, credentialsBody, keyValue); |
67 | resultSecurityStore[0].setMsg(msg); | 67 | resultSecurityStore[0].setMsg(msg); |
68 | resultSecurityStore[0].setDeviceProfile(msg.getDeviceProfile()); | 68 | resultSecurityStore[0].setDeviceProfile(msg.getDeviceProfile()); |
69 | latch.countDown(); | 69 | latch.countDown(); |
@@ -71,8 +71,8 @@ public class LwM2mCredentialsSecurityInfoValidator { | @@ -71,8 +71,8 @@ public class LwM2mCredentialsSecurityInfoValidator { | ||
71 | 71 | ||
72 | @Override | 72 | @Override |
73 | public void onError(Throwable e) { | 73 | public void onError(Throwable e) { |
74 | - log.trace("[{}] [{}] Failed to process credentials ", endpoint, e); | ||
75 | - resultSecurityStore[0] = createSecurityInfo(endpoint, null, null); | 74 | + log.trace("[{}] [{}] Failed to process credentials ", credentialsId, e); |
75 | + resultSecurityStore[0] = createSecurityInfo(credentialsId, null, null); | ||
76 | latch.countDown(); | 76 | latch.countDown(); |
77 | } | 77 | } |
78 | }); | 78 | }); |
@@ -91,8 +91,8 @@ public class LwM2mCredentialsSecurityInfoValidator { | @@ -91,8 +91,8 @@ public class LwM2mCredentialsSecurityInfoValidator { | ||
91 | * @param keyValue - | 91 | * @param keyValue - |
92 | * @return SecurityInfo | 92 | * @return SecurityInfo |
93 | */ | 93 | */ |
94 | - private EndpointSecurityInfo createSecurityInfo(String endpoint, String jsonStr, LwM2mTransportUtil.LwM2mTypeServer keyValue) { | ||
95 | - EndpointSecurityInfo result = new EndpointSecurityInfo(); | 94 | + private TbLwM2MSecurityInfo createSecurityInfo(String endpoint, String jsonStr, LwM2mTransportUtil.LwM2mTypeServer keyValue) { |
95 | + TbLwM2MSecurityInfo result = new TbLwM2MSecurityInfo(); | ||
96 | LwM2MCredentials credentials = JacksonUtil.fromString(jsonStr, LwM2MCredentials.class); | 96 | LwM2MCredentials credentials = JacksonUtil.fromString(jsonStr, LwM2MCredentials.class); |
97 | if (credentials != null) { | 97 | if (credentials != null) { |
98 | if (keyValue.equals(LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP)) { | 98 | if (keyValue.equals(LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP)) { |
@@ -104,6 +104,7 @@ public class LwM2mCredentialsSecurityInfoValidator { | @@ -104,6 +104,7 @@ public class LwM2mCredentialsSecurityInfoValidator { | ||
104 | result.setEndpoint(endpoint); | 104 | result.setEndpoint(endpoint); |
105 | result.setSecurityMode(credentials.getBootstrap().getBootstrapServer().getSecurityMode()); | 105 | result.setSecurityMode(credentials.getBootstrap().getBootstrapServer().getSecurityMode()); |
106 | } else { | 106 | } else { |
107 | + result.setEndpoint(credentials.getClient().getEndpoint()); | ||
107 | switch (credentials.getClient().getSecurityConfigClientMode()) { | 108 | switch (credentials.getClient().getSecurityConfigClientMode()) { |
108 | case NO_SEC: | 109 | case NO_SEC: |
109 | createClientSecurityInfoNoSec(result); | 110 | createClientSecurityInfoNoSec(result); |
@@ -125,12 +126,12 @@ public class LwM2mCredentialsSecurityInfoValidator { | @@ -125,12 +126,12 @@ public class LwM2mCredentialsSecurityInfoValidator { | ||
125 | return result; | 126 | return result; |
126 | } | 127 | } |
127 | 128 | ||
128 | - private void createClientSecurityInfoNoSec(EndpointSecurityInfo result) { | 129 | + private void createClientSecurityInfoNoSec(TbLwM2MSecurityInfo result) { |
129 | result.setSecurityInfo(null); | 130 | result.setSecurityInfo(null); |
130 | result.setSecurityMode(NO_SEC); | 131 | result.setSecurityMode(NO_SEC); |
131 | } | 132 | } |
132 | 133 | ||
133 | - private void createClientSecurityInfoPSK(EndpointSecurityInfo result, String endpoint, LwM2MClientCredentials clientCredentialsConfig) { | 134 | + private void createClientSecurityInfoPSK(TbLwM2MSecurityInfo result, String endpoint, LwM2MClientCredentials clientCredentialsConfig) { |
134 | PSKClientCredentials pskConfig = (PSKClientCredentials) clientCredentialsConfig; | 135 | PSKClientCredentials pskConfig = (PSKClientCredentials) clientCredentialsConfig; |
135 | if (StringUtils.isNotEmpty(pskConfig.getIdentity())) { | 136 | if (StringUtils.isNotEmpty(pskConfig.getIdentity())) { |
136 | try { | 137 | try { |
@@ -149,7 +150,7 @@ public class LwM2mCredentialsSecurityInfoValidator { | @@ -149,7 +150,7 @@ public class LwM2mCredentialsSecurityInfoValidator { | ||
149 | } | 150 | } |
150 | } | 151 | } |
151 | 152 | ||
152 | - private void createClientSecurityInfoRPK(EndpointSecurityInfo result, String endpoint, LwM2MClientCredentials clientCredentialsConfig) { | 153 | + private void createClientSecurityInfoRPK(TbLwM2MSecurityInfo result, String endpoint, LwM2MClientCredentials clientCredentialsConfig) { |
153 | RPKClientCredentials rpkConfig = (RPKClientCredentials) clientCredentialsConfig; | 154 | RPKClientCredentials rpkConfig = (RPKClientCredentials) clientCredentialsConfig; |
154 | try { | 155 | try { |
155 | if (rpkConfig.getKey() != null) { | 156 | if (rpkConfig.getKey() != null) { |
@@ -164,7 +165,7 @@ public class LwM2mCredentialsSecurityInfoValidator { | @@ -164,7 +165,7 @@ public class LwM2mCredentialsSecurityInfoValidator { | ||
164 | } | 165 | } |
165 | } | 166 | } |
166 | 167 | ||
167 | - private void createClientSecurityInfoX509(EndpointSecurityInfo result, String endpoint, LwM2MClientCredentials clientCredentialsConfig) { | 168 | + private void createClientSecurityInfoX509(TbLwM2MSecurityInfo result, String endpoint, LwM2MClientCredentials clientCredentialsConfig) { |
168 | result.setSecurityInfo(SecurityInfo.newX509CertInfo(endpoint)); | 169 | result.setSecurityInfo(SecurityInfo.newX509CertInfo(endpoint)); |
169 | result.setSecurityMode(X509); | 170 | result.setSecurityMode(X509); |
170 | } | 171 | } |
@@ -27,6 +27,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | @@ -27,6 +27,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | ||
27 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; | 27 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
28 | import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; | 28 | import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; |
29 | import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2mSecurityStore; | 29 | import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2mSecurityStore; |
30 | +import org.thingsboard.server.transport.lwm2m.server.store.TbSecurityStore; | ||
30 | 31 | ||
31 | @Component | 32 | @Component |
32 | @RequiredArgsConstructor | 33 | @RequiredArgsConstructor |
@@ -34,7 +35,7 @@ import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2mSecurityStore; | @@ -34,7 +35,7 @@ import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2mSecurityStore; | ||
34 | public class TbLwM2MAuthorizer implements Authorizer { | 35 | public class TbLwM2MAuthorizer implements Authorizer { |
35 | 36 | ||
36 | private final TbLwM2MDtlsSessionStore sessionStorage; | 37 | private final TbLwM2MDtlsSessionStore sessionStorage; |
37 | - private final TbLwM2mSecurityStore securityStore; | 38 | + private final TbSecurityStore securityStore; |
38 | private final SecurityChecker securityChecker = new SecurityChecker(); | 39 | private final SecurityChecker securityChecker = new SecurityChecker(); |
39 | private final LwM2mClientContext clientContext; | 40 | private final LwM2mClientContext clientContext; |
40 | 41 |
@@ -29,22 +29,21 @@ import org.eclipse.californium.scandium.dtls.HandshakeResultHandler; | @@ -29,22 +29,21 @@ import org.eclipse.californium.scandium.dtls.HandshakeResultHandler; | ||
29 | import org.eclipse.californium.scandium.dtls.x509.NewAdvancedCertificateVerifier; | 29 | import org.eclipse.californium.scandium.dtls.x509.NewAdvancedCertificateVerifier; |
30 | import org.eclipse.californium.scandium.dtls.x509.StaticCertificateVerifier; | 30 | import org.eclipse.californium.scandium.dtls.x509.StaticCertificateVerifier; |
31 | import org.eclipse.californium.scandium.util.ServerNames; | 31 | import org.eclipse.californium.scandium.util.ServerNames; |
32 | +import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException; | ||
32 | import org.springframework.beans.factory.annotation.Value; | 33 | import org.springframework.beans.factory.annotation.Value; |
33 | import org.springframework.stereotype.Component; | 34 | import org.springframework.stereotype.Component; |
34 | -import org.springframework.util.StringUtils; | ||
35 | import org.thingsboard.common.util.JacksonUtil; | 35 | import org.thingsboard.common.util.JacksonUtil; |
36 | import org.thingsboard.server.common.data.DeviceProfile; | 36 | import org.thingsboard.server.common.data.DeviceProfile; |
37 | import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; | 37 | import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; |
38 | +import org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredentials; | ||
38 | import org.thingsboard.server.common.msg.EncryptionUtil; | 39 | import org.thingsboard.server.common.msg.EncryptionUtil; |
39 | -import org.thingsboard.server.common.transport.TransportService; | ||
40 | -import org.thingsboard.server.common.transport.TransportServiceCallback; | ||
41 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | 40 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
42 | import org.thingsboard.server.common.transport.util.SslUtil; | 41 | import org.thingsboard.server.common.transport.util.SslUtil; |
43 | -import org.thingsboard.server.gen.transport.TransportProtos; | ||
44 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | 42 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
45 | import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; | 43 | import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; |
46 | import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials; | 44 | import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials; |
47 | -import org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredentials; | 45 | +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; |
46 | +import org.thingsboard.server.transport.lwm2m.server.store.TbEditableSecurityStore; | ||
48 | import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; | 47 | import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; |
49 | 48 | ||
50 | import javax.annotation.PostConstruct; | 49 | import javax.annotation.PostConstruct; |
@@ -57,8 +56,6 @@ import java.security.cert.CertificateNotYetValidException; | @@ -57,8 +56,6 @@ import java.security.cert.CertificateNotYetValidException; | ||
57 | import java.security.cert.X509Certificate; | 56 | import java.security.cert.X509Certificate; |
58 | import java.util.Arrays; | 57 | import java.util.Arrays; |
59 | import java.util.List; | 58 | import java.util.List; |
60 | -import java.util.concurrent.CountDownLatch; | ||
61 | -import java.util.concurrent.TimeUnit; | ||
62 | 59 | ||
63 | @Slf4j | 60 | @Slf4j |
64 | @Component | 61 | @Component |
@@ -66,9 +63,10 @@ import java.util.concurrent.TimeUnit; | @@ -66,9 +63,10 @@ import java.util.concurrent.TimeUnit; | ||
66 | @RequiredArgsConstructor | 63 | @RequiredArgsConstructor |
67 | public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVerifier { | 64 | public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVerifier { |
68 | 65 | ||
69 | - private final TransportService transportService; | ||
70 | private final TbLwM2MDtlsSessionStore sessionStorage; | 66 | private final TbLwM2MDtlsSessionStore sessionStorage; |
71 | private final LwM2MTransportServerConfig config; | 67 | private final LwM2MTransportServerConfig config; |
68 | + private final LwM2mCredentialsSecurityInfoValidator securityInfoValidator; | ||
69 | + private final TbEditableSecurityStore securityStore; | ||
72 | 70 | ||
73 | @SuppressWarnings("deprecation") | 71 | @SuppressWarnings("deprecation") |
74 | private StaticCertificateVerifier staticCertificateVerifier; | 72 | private StaticCertificateVerifier staticCertificateVerifier; |
@@ -119,48 +117,33 @@ public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVer | @@ -119,48 +117,33 @@ public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVer | ||
119 | 117 | ||
120 | String strCert = SslUtil.getCertificateString(cert); | 118 | String strCert = SslUtil.getCertificateString(cert); |
121 | String sha3Hash = EncryptionUtil.getSha3Hash(strCert); | 119 | String sha3Hash = EncryptionUtil.getSha3Hash(strCert); |
122 | - final ValidateDeviceCredentialsResponse[] deviceCredentialsResponse = new ValidateDeviceCredentialsResponse[1]; | ||
123 | - CountDownLatch latch = new CountDownLatch(1); | ||
124 | - transportService.process(TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(sha3Hash).build(), | ||
125 | - new TransportServiceCallback<>() { | ||
126 | - @Override | ||
127 | - public void onSuccess(ValidateDeviceCredentialsResponse msg) { | ||
128 | - if (!StringUtils.isEmpty(msg.getCredentials())) { | ||
129 | - deviceCredentialsResponse[0] = msg; | ||
130 | - } | ||
131 | - latch.countDown(); | ||
132 | - } | ||
133 | - | ||
134 | - @Override | ||
135 | - public void onError(Throwable e) { | ||
136 | - log.error(e.getMessage(), e); | ||
137 | - latch.countDown(); | ||
138 | - } | ||
139 | - }); | ||
140 | - if (latch.await(10, TimeUnit.SECONDS)) { | ||
141 | - ValidateDeviceCredentialsResponse msg = deviceCredentialsResponse[0]; | ||
142 | - if (msg != null && org.thingsboard.server.common.data.StringUtils.isNotEmpty(msg.getCredentials())) { | ||
143 | - LwM2MCredentials credentials = JacksonUtil.fromString(msg.getCredentials(), LwM2MCredentials.class); | ||
144 | - if(!credentials.getClient().getSecurityConfigClientMode().equals(LwM2MSecurityMode.X509)){ | ||
145 | - continue; | ||
146 | - } | ||
147 | - X509ClientCredentials config = (X509ClientCredentials) credentials.getClient(); | ||
148 | - String certBody = config.getCert(); | ||
149 | - String endpoint = config.getEndpoint(); | ||
150 | - if (strCert.equals(certBody)) { | ||
151 | - x509CredentialsFound = true; | ||
152 | - DeviceProfile deviceProfile = msg.getDeviceProfile(); | ||
153 | - if (msg.hasDeviceInfo() && deviceProfile != null) { | ||
154 | - sessionStorage.put(endpoint, new TbX509DtlsSessionInfo(cert.getSubjectX500Principal().getName(), msg)); | ||
155 | - break; | 120 | + TbLwM2MSecurityInfo securityInfo = securityInfoValidator.getEndpointSecurityInfoByCredentialsId(sha3Hash, LwM2mTransportUtil.LwM2mTypeServer.CLIENT); |
121 | + ValidateDeviceCredentialsResponse msg = securityInfo != null ? securityInfo.getMsg() : null; | ||
122 | + if (msg != null && org.thingsboard.server.common.data.StringUtils.isNotEmpty(msg.getCredentials())) { | ||
123 | + LwM2MCredentials credentials = JacksonUtil.fromString(msg.getCredentials(), LwM2MCredentials.class); | ||
124 | + if (!credentials.getClient().getSecurityConfigClientMode().equals(LwM2MSecurityMode.X509)) { | ||
125 | + continue; | ||
126 | + } | ||
127 | + X509ClientCredentials config = (X509ClientCredentials) credentials.getClient(); | ||
128 | + String certBody = config.getCert(); | ||
129 | + String endpoint = config.getEndpoint(); | ||
130 | + if (strCert.equals(certBody)) { | ||
131 | + x509CredentialsFound = true; | ||
132 | + DeviceProfile deviceProfile = msg.getDeviceProfile(); | ||
133 | + if (msg.hasDeviceInfo() && deviceProfile != null) { | ||
134 | + sessionStorage.put(endpoint, new TbX509DtlsSessionInfo(cert.getSubjectX500Principal().getName(), msg)); | ||
135 | + try { | ||
136 | + securityStore.put(securityInfo); | ||
137 | + } catch (NonUniqueSecurityInfoException e) { | ||
138 | + log.trace("Failed to add security info: {}", securityInfo, e); | ||
156 | } | 139 | } |
157 | - } else { | ||
158 | - log.trace("[{}][{}] Certificate mismatch. Expected: {}, Actual: {}", endpoint, sha3Hash, strCert, certBody); | 140 | + break; |
159 | } | 141 | } |
142 | + } else { | ||
143 | + log.trace("[{}][{}] Certificate mismatch. Expected: {}, Actual: {}", endpoint, sha3Hash, strCert, certBody); | ||
160 | } | 144 | } |
161 | } | 145 | } |
162 | - } catch (InterruptedException | | ||
163 | - CertificateEncodingException | | 146 | + } catch (CertificateEncodingException | |
164 | CertificateExpiredException | | 147 | CertificateExpiredException | |
165 | CertificateNotYetValidException e) { | 148 | CertificateNotYetValidException e) { |
166 | log.error(e.getMessage(), e); | 149 | log.error(e.getMessage(), e); |
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MSecurityInfo.java
renamed from
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/EndpointSecurityInfo.java
@@ -24,7 +24,7 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes | @@ -24,7 +24,7 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes | ||
24 | import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapConfig; | 24 | import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapConfig; |
25 | 25 | ||
26 | @Data | 26 | @Data |
27 | -public class EndpointSecurityInfo { | 27 | +public class TbLwM2MSecurityInfo { |
28 | private ValidateDeviceCredentialsResponse msg; | 28 | private ValidateDeviceCredentialsResponse msg; |
29 | private SecurityInfo securityInfo; | 29 | private SecurityInfo securityInfo; |
30 | private SecurityMode securityMode; | 30 | private SecurityMode securityMode; |
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | * you may not use this file except in compliance with 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 | 6 | * You may obtain a copy of the License at |
7 | * | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * | 9 | * |
10 | * Unless required by applicable law or agreed to in writing, software | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
@@ -31,7 +31,6 @@ import org.eclipse.leshan.core.node.LwM2mObjectInstance; | @@ -31,7 +31,6 @@ import org.eclipse.leshan.core.node.LwM2mObjectInstance; | ||
31 | import org.eclipse.leshan.core.node.LwM2mPath; | 31 | import org.eclipse.leshan.core.node.LwM2mPath; |
32 | import org.eclipse.leshan.core.node.LwM2mResource; | 32 | import org.eclipse.leshan.core.node.LwM2mResource; |
33 | import org.eclipse.leshan.core.observation.Observation; | 33 | import org.eclipse.leshan.core.observation.Observation; |
34 | -import org.eclipse.leshan.core.request.ContentFormat; | ||
35 | import org.eclipse.leshan.core.request.WriteRequest; | 34 | import org.eclipse.leshan.core.request.WriteRequest; |
36 | import org.eclipse.leshan.core.response.ReadResponse; | 35 | import org.eclipse.leshan.core.response.ReadResponse; |
37 | import org.eclipse.leshan.server.registration.Registration; | 36 | import org.eclipse.leshan.server.registration.Registration; |
@@ -58,6 +57,8 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | @@ -58,6 +57,8 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | ||
58 | import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; | 57 | import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; |
59 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper; | 58 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper; |
60 | import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor; | 59 | import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor; |
60 | +import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClientState; | ||
61 | +import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClientStateException; | ||
61 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; | 62 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; |
62 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; | 63 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
63 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; | 64 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; |
@@ -91,7 +92,6 @@ import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWN | @@ -91,7 +92,6 @@ import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWN | ||
91 | import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; | 92 | import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; |
92 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; | 93 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; |
93 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto; | 94 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto; |
94 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.CLIENT_NOT_AUTHORIZED; | ||
95 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEVICE_ATTRIBUTES_REQUEST; | 95 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEVICE_ATTRIBUTES_REQUEST; |
96 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_ID; | 96 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_ID; |
97 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_RESULT_ID; | 97 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_RESULT_ID; |
@@ -99,6 +99,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L | @@ -99,6 +99,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L | ||
99 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO; | 99 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO; |
100 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_TELEMETRY; | 100 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_TELEMETRY; |
101 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE; | 101 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE; |
102 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_WARN; | ||
102 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LWM2M_STRATEGY_2; | 103 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LWM2M_STRATEGY_2; |
103 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER; | 104 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER; |
104 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; | 105 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; |
@@ -182,32 +183,38 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -182,32 +183,38 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
182 | */ | 183 | */ |
183 | public void onRegistered(Registration registration, Collection<Observation> previousObservations) { | 184 | public void onRegistered(Registration registration, Collection<Observation> previousObservations) { |
184 | registrationExecutor.submit(() -> { | 185 | registrationExecutor.submit(() -> { |
186 | + LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint()); | ||
185 | try { | 187 | try { |
186 | log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); | 188 | log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); |
187 | - LwM2mClient lwM2MClient = this.clientContext.registerOrUpdate(registration); | ||
188 | if (lwM2MClient != null) { | 189 | if (lwM2MClient != null) { |
189 | - SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); | ||
190 | - if (sessionInfo != null) { | ||
191 | - transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); | ||
192 | - TransportProtos.TransportToDeviceActorMsg msg = TransportProtos.TransportToDeviceActorMsg.newBuilder() | ||
193 | - .setSessionInfo(sessionInfo) | ||
194 | - .setSessionEvent(DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN)) | ||
195 | - .setSubscribeToAttributes(TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build()) | ||
196 | - .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder().build()) | ||
197 | - .build(); | ||
198 | - transportService.process(msg, null); | ||
199 | - this.getInfoFirmwareUpdate(lwM2MClient, null); | ||
200 | - this.getInfoSoftwareUpdate(lwM2MClient, null); | ||
201 | - this.initLwM2mFromClientValue(registration, lwM2MClient); | ||
202 | - this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration.getId()); | ||
203 | - } else { | ||
204 | - log.error("Client: [{}] onRegistered [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); | ||
205 | - } | 190 | + this.clientContext.register(lwM2MClient, registration); |
191 | + this.sendLogsToThingsboard(lwM2MClient, LOG_LW2M_INFO + ": Client registered with registration id: " + registration.getId()); | ||
192 | + SessionInfoProto sessionInfo = lwM2MClient.getSession(); | ||
193 | + transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); | ||
194 | + TransportProtos.TransportToDeviceActorMsg msg = TransportProtos.TransportToDeviceActorMsg.newBuilder() | ||
195 | + .setSessionInfo(sessionInfo) | ||
196 | + .setSessionEvent(DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN)) | ||
197 | + .setSubscribeToAttributes(TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build()) | ||
198 | + .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder().build()) | ||
199 | + .build(); | ||
200 | + transportService.process(msg, null); | ||
201 | + this.getInfoFirmwareUpdate(lwM2MClient, null); | ||
202 | + this.getInfoSoftwareUpdate(lwM2MClient, null); | ||
203 | + this.initClientTelemetry(lwM2MClient); | ||
206 | } else { | 204 | } else { |
207 | - log.error("Client: [{}] onRegistered [{}] name [{}] lwM2MClient ", registration.getId(), registration.getEndpoint(), null); | 205 | + log.error("Client: [{}] onRegistered [{}] name [{}] lwM2MClient ", registration.getId(), registration.getEndpoint(), null); |
206 | + } | ||
207 | + } catch (LwM2MClientStateException stateException) { | ||
208 | + if (LwM2MClientState.UNREGISTERED.equals(stateException.getState())) { | ||
209 | + log.info("[{}] retry registration due to race condition: [{}].", registration.getEndpoint(), stateException.getState()); | ||
210 | + // Race condition detected and the client was in progress of unregistration while new registration arrived. Let's try again. | ||
211 | + onRegistered(registration, previousObservations); | ||
212 | + } else { | ||
213 | + this.sendLogsToThingsboard(lwM2MClient, LOG_LW2M_WARN + ": Client registration failed due to invalid state: " + stateException.getState()); | ||
208 | } | 214 | } |
209 | } catch (Throwable t) { | 215 | } catch (Throwable t) { |
210 | log.error("[{}] endpoint [{}] error Unable registration.", registration.getEndpoint(), t); | 216 | log.error("[{}] endpoint [{}] error Unable registration.", registration.getEndpoint(), t); |
217 | + this.sendLogsToThingsboard(lwM2MClient, LOG_LW2M_WARN + ": Client registration failed due to: " + t.getMessage()); | ||
211 | } | 218 | } |
212 | }); | 219 | }); |
213 | } | 220 | } |
@@ -219,25 +226,26 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -219,25 +226,26 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
219 | */ | 226 | */ |
220 | public void updatedReg(Registration registration) { | 227 | public void updatedReg(Registration registration) { |
221 | updateRegistrationExecutor.submit(() -> { | 228 | updateRegistrationExecutor.submit(() -> { |
229 | + LwM2mClient lwM2MClient = clientContext.getClientByEndpoint(registration.getEndpoint()); | ||
222 | try { | 230 | try { |
223 | - LwM2mClient client = clientContext.getOrRegister(registration); | ||
224 | - if (client != null && client.getSession() != null) { | ||
225 | - SessionInfoProto sessionInfo = client.getSession(); | ||
226 | - this.reportActivityAndRegister(sessionInfo); | ||
227 | - if (registration.getBindingMode().useQueueMode()) { | ||
228 | - LwM2mQueuedRequest request; | ||
229 | - while ((request = client.getQueuedRequests().poll()) != null) { | ||
230 | - request.send(); | ||
231 | - } | 231 | + clientContext.updateRegistration(lwM2MClient, registration); |
232 | + TransportProtos.SessionInfoProto sessionInfo = lwM2MClient.getSession(); | ||
233 | + this.reportActivityAndRegister(sessionInfo); | ||
234 | + if (registration.usesQueueMode()) { | ||
235 | + LwM2mQueuedRequest request; | ||
236 | + while ((request = lwM2MClient.getQueuedRequests().poll()) != null) { | ||
237 | + request.send(); | ||
232 | } | 238 | } |
233 | - this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client update Registration", registration.getId()); | 239 | + } |
240 | + } catch (LwM2MClientStateException stateException) { | ||
241 | + if (LwM2MClientState.UNREGISTERED.equals(stateException.getState())) { | ||
242 | + log.info("[{}] update registration failed because client was already unregistered: [{}].", registration.getEndpoint(), stateException.getState()); | ||
234 | } else { | 243 | } else { |
235 | - log.error("Client: [{}] updatedReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); | ||
236 | - this.sendLogsToThingsboard(LOG_LW2M_ERROR + ": Client update Registration", registration.getId()); | 244 | + log.info("[{}] update registration: [{}] {}.", registration.getEndpoint(), stateException.getState(), stateException.getMessage()); |
237 | } | 245 | } |
238 | } catch (Throwable t) { | 246 | } catch (Throwable t) { |
239 | log.error("[{}] endpoint [{}] error Unable update registration.", registration.getEndpoint(), t); | 247 | log.error("[{}] endpoint [{}] error Unable update registration.", registration.getEndpoint(), t); |
240 | - this.sendLogsToThingsboard(LOG_LW2M_ERROR + String.format(": Client update Registration, %s", t.getMessage()), registration.getId()); | 248 | + this.sendLogsToThingsboard(lwM2MClient, LOG_LW2M_ERROR + String.format(": Client update Registration, %s", t.getMessage())); |
241 | } | 249 | } |
242 | }); | 250 | }); |
243 | } | 251 | } |
@@ -248,34 +256,32 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -248,34 +256,32 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
248 | */ | 256 | */ |
249 | public void unReg(Registration registration, Collection<Observation> observations) { | 257 | public void unReg(Registration registration, Collection<Observation> observations) { |
250 | unRegistrationExecutor.submit(() -> { | 258 | unRegistrationExecutor.submit(() -> { |
259 | + LwM2mClient client = clientContext.getClientByEndpoint(registration.getEndpoint()); | ||
251 | try { | 260 | try { |
252 | - this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId()); | ||
253 | - this.closeClientSession(registration); | 261 | + this.sendLogsToThingsboard(client, LOG_LW2M_INFO + ": Client unRegistration"); |
262 | + clientContext.unregister(client, registration); | ||
263 | + SessionInfoProto sessionInfo = client.getSession(); | ||
264 | + if (sessionInfo != null) { | ||
265 | + transportService.deregisterSession(sessionInfo); | ||
266 | + sessionStore.remove(registration.getEndpoint()); | ||
267 | + this.doCloseSession(sessionInfo); | ||
268 | + log.info("Client close session: [{}] unReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType()); | ||
269 | + } else { | ||
270 | + log.error("Client close session: [{}] unReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); | ||
271 | + } | ||
272 | + } catch (LwM2MClientStateException stateException) { | ||
273 | + log.info("[{}] delete registration: [{}] {}.", registration.getEndpoint(), stateException.getState(), stateException.getMessage()); | ||
254 | } catch (Throwable t) { | 274 | } catch (Throwable t) { |
255 | log.error("[{}] endpoint [{}] error Unable un registration.", registration.getEndpoint(), t); | 275 | log.error("[{}] endpoint [{}] error Unable un registration.", registration.getEndpoint(), t); |
256 | - this.sendLogsToThingsboard(LOG_LW2M_ERROR + String.format(": Client Unable un Registration, %s", t.getMessage()), registration.getId()); | 276 | + this.sendLogsToThingsboard(client, LOG_LW2M_ERROR + String.format(": Client Unable un Registration, %s", t.getMessage())); |
257 | } | 277 | } |
258 | }); | 278 | }); |
259 | } | 279 | } |
260 | 280 | ||
261 | - private void closeClientSession(Registration registration) { | ||
262 | - SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registration); | ||
263 | - if (sessionInfo != null) { | ||
264 | - transportService.deregisterSession(sessionInfo); | ||
265 | - sessionStore.remove(registration.getEndpoint()); | ||
266 | - this.doCloseSession(sessionInfo); | ||
267 | - clientContext.removeClientByRegistrationId(registration.getId()); | ||
268 | - log.info("Client close session: [{}] unReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType()); | ||
269 | - } else { | ||
270 | - log.error("Client close session: [{}] unReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); | ||
271 | - } | ||
272 | - } | ||
273 | - | ||
274 | @Override | 281 | @Override |
275 | public void onSleepingDev(Registration registration) { | 282 | public void onSleepingDev(Registration registration) { |
276 | log.info("[{}] [{}] Received endpoint Sleeping version event", registration.getId(), registration.getEndpoint()); | 283 | log.info("[{}] [{}] Received endpoint Sleeping version event", registration.getId(), registration.getEndpoint()); |
277 | - this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client is sleeping!", registration.getId()); | ||
278 | - | 284 | + this.sendLogsToThingsboard(clientContext.getClientByEndpoint(registration.getEndpoint()), LOG_LW2M_INFO + ": Client is sleeping!"); |
279 | //TODO: associate endpointId with device information. | 285 | //TODO: associate endpointId with device information. |
280 | } | 286 | } |
281 | 287 | ||
@@ -285,8 +291,11 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -285,8 +291,11 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
285 | @Override | 291 | @Override |
286 | public void setCancelObservationsAll(Registration registration) { | 292 | public void setCancelObservationsAll(Registration registration) { |
287 | if (registration != null) { | 293 | if (registration != null) { |
288 | - this.lwM2mTransportRequest.sendAllRequest(registration, null, OBSERVE_CANCEL_ALL, | ||
289 | - null, null, this.config.getTimeout(), null); | 294 | + LwM2mClient client = clientContext.getClientByEndpoint(registration.getEndpoint()); |
295 | + if (client != null && client.getRegistration() != null && client.getRegistration().getId().equals(registration.getId())) { | ||
296 | + this.lwM2mTransportRequest.sendAllRequest(client, null, OBSERVE_CANCEL_ALL, | ||
297 | + null, null, this.config.getTimeout(), null); | ||
298 | + } | ||
290 | } | 299 | } |
291 | } | 300 | } |
292 | 301 | ||
@@ -300,7 +309,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -300,7 +309,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
300 | @Override | 309 | @Override |
301 | public void onUpdateValueAfterReadResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest) { | 310 | public void onUpdateValueAfterReadResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest) { |
302 | if (response.getContent() != null) { | 311 | if (response.getContent() != null) { |
303 | - LwM2mClient lwM2MClient = clientContext.getOrRegister(registration); | 312 | + LwM2mClient lwM2MClient = clientContext.getClientByEndpoint(registration.getEndpoint()); |
304 | ObjectModel objectModelVersion = lwM2MClient.getObjectModel(path, this.config.getModelProvider()); | 313 | ObjectModel objectModelVersion = lwM2MClient.getObjectModel(path, this.config.getModelProvider()); |
305 | if (objectModelVersion != null) { | 314 | if (objectModelVersion != null) { |
306 | if (response.getContent() instanceof LwM2mObject) { | 315 | if (response.getContent() instanceof LwM2mObject) { |
@@ -332,7 +341,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -332,7 +341,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
332 | } | 341 | } |
333 | String msg = String.format("%s: type operation %s path - %s value - %s", LOG_LW2M_INFO, | 342 | String msg = String.format("%s: type operation %s path - %s value - %s", LOG_LW2M_INFO, |
334 | READ, pathIdVer, value); | 343 | READ, pathIdVer, value); |
335 | - this.sendLogsToThingsboard(msg, registration.getId()); | 344 | + this.sendLogsToThingsboard(lwM2MClient, msg); |
336 | rpcRequest.setValueMsg(String.format("%s", value)); | 345 | rpcRequest.setValueMsg(String.format("%s", value)); |
337 | this.sentRpcResponse(rpcRequest, response.getCode().getName(), (String) value, LOG_LW2M_VALUE); | 346 | this.sentRpcResponse(rpcRequest, response.getCode().getName(), (String) value, LOG_LW2M_VALUE); |
338 | } | 347 | } |
@@ -350,9 +359,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -350,9 +359,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
350 | */ | 359 | */ |
351 | @Override | 360 | @Override |
352 | public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) { | 361 | public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) { |
353 | - LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo); | 362 | + LwM2mClient lwM2MClient = clientContext.getClientBySessionInfo(sessionInfo); |
354 | if (msg.getSharedUpdatedCount() > 0 && lwM2MClient != null) { | 363 | if (msg.getSharedUpdatedCount() > 0 && lwM2MClient != null) { |
355 | - log.warn ("2) OnAttributeUpdate, SharedUpdatedList() [{}]", msg.getSharedUpdatedList()); | 364 | + log.warn("2) OnAttributeUpdate, SharedUpdatedList() [{}]", msg.getSharedUpdatedList()); |
356 | msg.getSharedUpdatedList().forEach(tsKvProto -> { | 365 | msg.getSharedUpdatedList().forEach(tsKvProto -> { |
357 | String pathName = tsKvProto.getKv().getKey(); | 366 | String pathName = tsKvProto.getKv().getKey(); |
358 | String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); | 367 | String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); |
@@ -377,13 +386,13 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -377,13 +386,13 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
377 | log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", pathIdVer, valueNew); | 386 | log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", pathIdVer, valueNew); |
378 | String logMsg = String.format("%s: attributeUpdate: Resource path - %s value - %s is not Writable and cannot be updated", | 387 | String logMsg = String.format("%s: attributeUpdate: Resource path - %s value - %s is not Writable and cannot be updated", |
379 | LOG_LW2M_ERROR, pathIdVer, valueNew); | 388 | LOG_LW2M_ERROR, pathIdVer, valueNew); |
380 | - this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration().getId()); | 389 | + this.sendLogsToThingsboard(lwM2MClient, logMsg); |
381 | } | 390 | } |
382 | } else if (!isFwSwWords(pathName)) { | 391 | } else if (!isFwSwWords(pathName)) { |
383 | log.error("Resource name name - [{}] value - [{}] is not present as attribute/telemetry in profile and cannot be updated", pathName, valueNew); | 392 | log.error("Resource name name - [{}] value - [{}] is not present as attribute/telemetry in profile and cannot be updated", pathName, valueNew); |
384 | String logMsg = String.format("%s: attributeUpdate: attribute name - %s value - %s is not present as attribute in profile and cannot be updated", | 393 | String logMsg = String.format("%s: attributeUpdate: attribute name - %s value - %s is not present as attribute in profile and cannot be updated", |
385 | LOG_LW2M_ERROR, pathName, valueNew); | 394 | LOG_LW2M_ERROR, pathName, valueNew); |
386 | - this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration().getId()); | 395 | + this.sendLogsToThingsboard(lwM2MClient, logMsg); |
387 | } | 396 | } |
388 | 397 | ||
389 | }); | 398 | }); |
@@ -396,9 +405,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -396,9 +405,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
396 | } | 405 | } |
397 | }); | 406 | }); |
398 | log.info("[{}] delete [{}] onAttributeUpdate", msg.getSharedDeletedList(), sessionInfo); | 407 | log.info("[{}] delete [{}] onAttributeUpdate", msg.getSharedDeletedList(), sessionInfo); |
399 | - } | ||
400 | - else if (lwM2MClient == null) { | ||
401 | - log.error ("OnAttributeUpdate, lwM2MClient is null"); | 408 | + } else if (lwM2MClient == null) { |
409 | + log.error("OnAttributeUpdate, lwM2MClient is null"); | ||
402 | } | 410 | } |
403 | } | 411 | } |
404 | 412 | ||
@@ -408,12 +416,11 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -408,12 +416,11 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
408 | */ | 416 | */ |
409 | @Override | 417 | @Override |
410 | public void onDeviceProfileUpdate(SessionInfoProto sessionInfo, DeviceProfile deviceProfile) { | 418 | public void onDeviceProfileUpdate(SessionInfoProto sessionInfo, DeviceProfile deviceProfile) { |
411 | - Set<LwM2mClient> clients = clientContext.getLwM2mClients() | ||
412 | - .stream().filter(e -> e.getProfileId().equals(deviceProfile.getUuidId())).collect(Collectors.toSet()); | 419 | + List<LwM2mClient> clients = clientContext.getLwM2mClients() |
420 | + .stream().filter(e -> e.getProfileId().equals(deviceProfile.getUuidId())).collect(Collectors.toList()); | ||
413 | clients.forEach(client -> client.onDeviceProfileUpdate(deviceProfile)); | 421 | clients.forEach(client -> client.onDeviceProfileUpdate(deviceProfile)); |
414 | - Set<String> registrationIds = clients.stream().map(LwM2mClient::getRegistration).map(Registration::getId).collect(Collectors.toSet()); | ||
415 | - if (registrationIds.size() > 0) { | ||
416 | - this.onDeviceProfileUpdate(registrationIds, deviceProfile); | 422 | + if (clients.size() > 0) { |
423 | + this.onDeviceProfileUpdate(clients, deviceProfile); | ||
417 | } | 424 | } |
418 | } | 425 | } |
419 | 426 | ||
@@ -446,7 +453,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -446,7 +453,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
446 | public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRpcRequestMsg, SessionInfoProto sessionInfo) { | 453 | public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRpcRequestMsg, SessionInfoProto sessionInfo) { |
447 | // #1 | 454 | // #1 |
448 | this.checkRpcRequestTimeout(); | 455 | this.checkRpcRequestTimeout(); |
449 | - log.warn ("4) toDeviceRpcRequestMsg: [{}], sessionUUID: [{}]", toDeviceRpcRequestMsg, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | 456 | + log.warn("4) toDeviceRpcRequestMsg: [{}], sessionUUID: [{}]", toDeviceRpcRequestMsg, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); |
450 | String bodyParams = StringUtils.trimToNull(toDeviceRpcRequestMsg.getParams()) != null ? toDeviceRpcRequestMsg.getParams() : "null"; | 457 | String bodyParams = StringUtils.trimToNull(toDeviceRpcRequestMsg.getParams()) != null ? toDeviceRpcRequestMsg.getParams() : "null"; |
451 | LwM2mTypeOper lwM2mTypeOper = setValidTypeOper(toDeviceRpcRequestMsg.getMethodName()); | 458 | LwM2mTypeOper lwM2mTypeOper = setValidTypeOper(toDeviceRpcRequestMsg.getMethodName()); |
452 | UUID requestUUID = new UUID(toDeviceRpcRequestMsg.getRequestIdMSB(), toDeviceRpcRequestMsg.getRequestIdLSB()); | 459 | UUID requestUUID = new UUID(toDeviceRpcRequestMsg.getRequestIdMSB(), toDeviceRpcRequestMsg.getRequestIdLSB()); |
@@ -454,13 +461,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -454,13 +461,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
454 | this.rpcSubscriptions.put(requestUUID, toDeviceRpcRequestMsg.getExpirationTime()); | 461 | this.rpcSubscriptions.put(requestUUID, toDeviceRpcRequestMsg.getExpirationTime()); |
455 | Lwm2mClientRpcRequest lwm2mClientRpcRequest = null; | 462 | Lwm2mClientRpcRequest lwm2mClientRpcRequest = null; |
456 | try { | 463 | try { |
457 | - Registration registration = clientContext.getClient(sessionInfo).getRegistration(); | 464 | + LwM2mClient client = clientContext.getClientBySessionInfo(sessionInfo); |
465 | + Registration registration = client.getRegistration(); | ||
458 | lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(lwM2mTypeOper, bodyParams, toDeviceRpcRequestMsg.getRequestId(), sessionInfo, registration, this); | 466 | lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(lwM2mTypeOper, bodyParams, toDeviceRpcRequestMsg.getRequestId(), sessionInfo, registration, this); |
459 | if (lwm2mClientRpcRequest.getErrorMsg() != null) { | 467 | if (lwm2mClientRpcRequest.getErrorMsg() != null) { |
460 | lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); | 468 | lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); |
461 | this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); | 469 | this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); |
462 | } else { | 470 | } else { |
463 | - lwM2mTransportRequest.sendAllRequest(registration, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), | 471 | + lwM2mTransportRequest.sendAllRequest(client, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), |
464 | null, | 472 | null, |
465 | lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(), | 473 | lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(), |
466 | this.config.getTimeout(), lwm2mClientRpcRequest); | 474 | this.config.getTimeout(), lwm2mClientRpcRequest); |
@@ -506,7 +514,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -506,7 +514,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
506 | 514 | ||
507 | @Override | 515 | @Override |
508 | public void onToDeviceRpcResponse(TransportProtos.ToDeviceRpcResponseMsg toDeviceResponse, SessionInfoProto sessionInfo) { | 516 | public void onToDeviceRpcResponse(TransportProtos.ToDeviceRpcResponseMsg toDeviceResponse, SessionInfoProto sessionInfo) { |
509 | - log.warn ("5) onToDeviceRpcResponse: [{}], sessionUUID: [{}]", toDeviceResponse, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | 517 | + log.warn("5) onToDeviceRpcResponse: [{}], sessionUUID: [{}]", toDeviceResponse, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); |
510 | transportService.process(sessionInfo, toDeviceResponse, null); | 518 | transportService.process(sessionInfo, toDeviceResponse, null); |
511 | } | 519 | } |
512 | 520 | ||
@@ -515,17 +523,6 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -515,17 +523,6 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
515 | } | 523 | } |
516 | 524 | ||
517 | /** | 525 | /** |
518 | - * Trigger Server path = "/1/0/8" | ||
519 | - * <p> | ||
520 | - * Trigger bootStrap path = "/1/0/9" - have to implemented on client | ||
521 | - */ | ||
522 | - @Override | ||
523 | - public void doTrigger(Registration registration, String path) { | ||
524 | - lwM2mTransportRequest.sendAllRequest(registration, path, EXECUTE, | ||
525 | - ContentFormat.TLV.getName(), null, this.config.getTimeout(), null); | ||
526 | - } | ||
527 | - | ||
528 | - /** | ||
529 | * Deregister session in transport | 526 | * Deregister session in transport |
530 | * | 527 | * |
531 | * @param sessionInfo - lwm2m client | 528 | * @param sessionInfo - lwm2m client |
@@ -558,7 +555,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -558,7 +555,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
558 | @Override | 555 | @Override |
559 | public void onAwakeDev(Registration registration) { | 556 | public void onAwakeDev(Registration registration) { |
560 | log.trace("[{}] [{}] Received endpoint Awake version event", registration.getId(), registration.getEndpoint()); | 557 | log.trace("[{}] [{}] Received endpoint Awake version event", registration.getId(), registration.getEndpoint()); |
561 | - this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client is awake!", registration.getId()); | 558 | + this.sendLogsToThingsboard(clientContext.getClientByEndpoint(registration.getEndpoint()), LOG_LW2M_INFO + ": Client is awake!"); |
562 | //TODO: associate endpointId with device information. | 559 | //TODO: associate endpointId with device information. |
563 | } | 560 | } |
564 | 561 | ||
@@ -567,13 +564,17 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -567,13 +564,17 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
567 | * @param registrationId - Id of Registration LwM2M Client | 564 | * @param registrationId - Id of Registration LwM2M Client |
568 | */ | 565 | */ |
569 | @Override | 566 | @Override |
570 | - public void sendLogsToThingsboard(String logMsg, String registrationId) { | ||
571 | - SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registrationId); | ||
572 | - if (logMsg != null && sessionInfo != null) { | 567 | + public void sendLogsToThingsboard(String registrationId, String logMsg) { |
568 | + sendLogsToThingsboard(clientContext.getClientByRegistrationId(registrationId), logMsg); | ||
569 | + } | ||
570 | + | ||
571 | + @Override | ||
572 | + public void sendLogsToThingsboard(LwM2mClient client, String logMsg) { | ||
573 | + if (logMsg != null && client != null && client.getSession() != null) { | ||
573 | if (logMsg.length() > 1024) { | 574 | if (logMsg.length() > 1024) { |
574 | logMsg = logMsg.substring(0, 1024); | 575 | logMsg = logMsg.substring(0, 1024); |
575 | } | 576 | } |
576 | - this.helper.sendParametersOnThingsboardTelemetry(this.helper.getKvStringtoThingsboard(LOG_LW2M_TELEMETRY, logMsg), sessionInfo); | 577 | + this.helper.sendParametersOnThingsboardTelemetry(this.helper.getKvStringtoThingsboard(LOG_LW2M_TELEMETRY, logMsg), client.getSession()); |
577 | } | 578 | } |
578 | } | 579 | } |
579 | 580 | ||
@@ -586,24 +587,23 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -586,24 +587,23 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
586 | * - Read Request to the client after registration to read all resource values for all objects | 587 | * - Read Request to the client after registration to read all resource values for all objects |
587 | * - then Observe Request to the client marked as observe from the profile configuration. | 588 | * - then Observe Request to the client marked as observe from the profile configuration. |
588 | * | 589 | * |
589 | - * @param registration - Registration LwM2M Client | ||
590 | - * @param lwM2MClient - object with All parameters off client | 590 | + * @param lwM2MClient - object with All parameters off client |
591 | */ | 591 | */ |
592 | - private void initLwM2mFromClientValue(Registration registration, LwM2mClient lwM2MClient) { | ||
593 | - LwM2mClientProfile lwM2MClientProfile = clientContext.getProfile(registration); | ||
594 | - Set<String> clientObjects = clientContext.getSupportedIdVerInClient(registration); | 592 | + private void initClientTelemetry(LwM2mClient lwM2MClient) { |
593 | + LwM2mClientProfile lwM2MClientProfile = clientContext.getProfile(lwM2MClient.getProfileId()); | ||
594 | + Set<String> clientObjects = clientContext.getSupportedIdVerInClient(lwM2MClient); | ||
595 | if (clientObjects != null && clientObjects.size() > 0) { | 595 | if (clientObjects != null && clientObjects.size() > 0) { |
596 | if (LWM2M_STRATEGY_2 == LwM2mTransportUtil.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { | 596 | if (LWM2M_STRATEGY_2 == LwM2mTransportUtil.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { |
597 | // #2 | 597 | // #2 |
598 | lwM2MClient.getPendingReadRequests().addAll(clientObjects); | 598 | lwM2MClient.getPendingReadRequests().addAll(clientObjects); |
599 | - clientObjects.forEach(path -> lwM2mTransportRequest.sendAllRequest(registration, path, READ, ContentFormat.TLV.getName(), | 599 | + clientObjects.forEach(path -> lwM2mTransportRequest.sendAllRequest(lwM2MClient, path, READ, |
600 | null, this.config.getTimeout(), null)); | 600 | null, this.config.getTimeout(), null)); |
601 | } | 601 | } |
602 | // #1 | 602 | // #1 |
603 | - this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, READ, clientObjects); | ||
604 | - this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, OBSERVE, clientObjects); | ||
605 | - this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, WRITE_ATTRIBUTES, clientObjects); | ||
606 | - this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, DISCOVER, clientObjects); | 603 | + this.initReadAttrTelemetryObserveToClient(lwM2MClient, READ, clientObjects); |
604 | + this.initReadAttrTelemetryObserveToClient(lwM2MClient, OBSERVE, clientObjects); | ||
605 | + this.initReadAttrTelemetryObserveToClient(lwM2MClient, WRITE_ATTRIBUTES, clientObjects); | ||
606 | + this.initReadAttrTelemetryObserveToClient(lwM2MClient, DISCOVER, clientObjects); | ||
607 | } | 607 | } |
608 | } | 608 | } |
609 | 609 | ||
@@ -645,7 +645,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -645,7 +645,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
645 | * @param path - resource | 645 | * @param path - resource |
646 | */ | 646 | */ |
647 | private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) { | 647 | private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) { |
648 | - LwM2mClient lwM2MClient = clientContext.getOrRegister(registration); | 648 | + LwM2mClient lwM2MClient = clientContext.getClientByEndpoint(registration.getEndpoint()); |
649 | if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.config.getModelProvider())) { | 649 | if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.config.getModelProvider())) { |
650 | /** version != null | 650 | /** version != null |
651 | * set setClient_fw_info... = value | 651 | * set setClient_fw_info... = value |
@@ -740,15 +740,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -740,15 +740,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
740 | } | 740 | } |
741 | } | 741 | } |
742 | 742 | ||
743 | - /** | ||
744 | - * Start observe/read: Attr/Telemetry | ||
745 | - * #1 - Analyze: path in resource profile == client resource | ||
746 | - * | ||
747 | - * @param registration - | ||
748 | - */ | ||
749 | - private void initReadAttrTelemetryObserveToClient(Registration registration, LwM2mClient lwM2MClient, | ||
750 | - LwM2mTypeOper typeOper, Set<String> clientObjects) { | ||
751 | - LwM2mClientProfile lwM2MClientProfile = clientContext.getProfile(registration); | 743 | + private void initReadAttrTelemetryObserveToClient(LwM2mClient lwM2MClient, LwM2mTypeOper typeOper, Set<String> clientObjects) { |
744 | + LwM2mClientProfile lwM2MClientProfile = clientContext.getProfile(lwM2MClient.getProfileId()); | ||
752 | Set<String> result = null; | 745 | Set<String> result = null; |
753 | ConcurrentHashMap<String, Object> params = null; | 746 | ConcurrentHashMap<String, Object> params = null; |
754 | if (READ.equals(typeOper)) { | 747 | if (READ.equals(typeOper)) { |
@@ -768,28 +761,42 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -768,28 +761,42 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
768 | params = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile()); | 761 | params = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile()); |
769 | result = params.keySet(); | 762 | result = params.keySet(); |
770 | } | 763 | } |
771 | - if (result != null && !result.isEmpty()) { | ||
772 | - // #1 | ||
773 | - Set<String> pathSend = result.stream().filter(target -> { | ||
774 | - return target.split(LWM2M_SEPARATOR_PATH).length < 3 ? | ||
775 | - clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1]) : | ||
776 | - clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1] + "/" + target.split(LWM2M_SEPARATOR_PATH)[2]); | ||
777 | - } | 764 | + sendRequestsToClient(lwM2MClient, typeOper, clientObjects, result, params); |
765 | + } | ||
766 | + | ||
767 | + private void sendRequestsToClient(LwM2mClient lwM2MClient, LwM2mTypeOper operationType, Set<String> supportedObjectIds, Set<String> desiredObjectIds, ConcurrentHashMap<String, Object> params) { | ||
768 | + if (desiredObjectIds != null && !desiredObjectIds.isEmpty()) { | ||
769 | + Set<String> targetObjectIds = desiredObjectIds.stream().filter(target -> isSupportedTargetId(supportedObjectIds, target) | ||
778 | ).collect(Collectors.toUnmodifiableSet()); | 770 | ).collect(Collectors.toUnmodifiableSet()); |
779 | - if (!pathSend.isEmpty()) { | ||
780 | - lwM2MClient.getPendingReadRequests().addAll(pathSend); | ||
781 | - ConcurrentHashMap<String, Object> finalParams = params; | ||
782 | - pathSend.forEach(target -> { | ||
783 | - lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, ContentFormat.TLV.getName(), | ||
784 | - finalParams != null ? finalParams.get(target) : null, this.config.getTimeout(), null); | 771 | + if (!targetObjectIds.isEmpty()) { |
772 | + //TODO: remove this side effect? | ||
773 | + lwM2MClient.getPendingReadRequests().addAll(targetObjectIds); | ||
774 | + targetObjectIds.forEach(target -> { | ||
775 | + Object additionalParams = params != null ? params.get(target) : null; | ||
776 | + lwM2mTransportRequest.sendAllRequest(lwM2MClient, target, operationType, additionalParams, this.config.getTimeout(), null); | ||
785 | }); | 777 | }); |
786 | - if (OBSERVE.equals(typeOper)) { | 778 | + if (OBSERVE.equals(operationType)) { |
787 | lwM2MClient.initReadValue(this, null); | 779 | lwM2MClient.initReadValue(this, null); |
788 | } | 780 | } |
789 | } | 781 | } |
790 | } | 782 | } |
791 | } | 783 | } |
792 | 784 | ||
785 | + private boolean isSupportedTargetId(Set<String> supportedIds, String targetId) { | ||
786 | + String[] targetIdParts = targetId.split(LWM2M_SEPARATOR_PATH); | ||
787 | + if (targetIdParts.length <= 1) { | ||
788 | + return false; | ||
789 | + } | ||
790 | + String targetIdSearch = targetIdParts[0]; | ||
791 | + for (int i = 1; i < targetIdParts.length; i++) { | ||
792 | + targetIdSearch += "/" + targetIdParts[i]; | ||
793 | + if (supportedIds.contains(targetIdSearch)) { | ||
794 | + return true; | ||
795 | + } | ||
796 | + } | ||
797 | + return false; | ||
798 | + } | ||
799 | + | ||
793 | private ConcurrentHashMap<String, Object> getPathForWriteAttributes(JsonObject objectJson) { | 800 | private ConcurrentHashMap<String, Object> getPathForWriteAttributes(JsonObject objectJson) { |
794 | ConcurrentHashMap<String, Object> pathAttributes = new Gson().fromJson(objectJson.toString(), | 801 | ConcurrentHashMap<String, Object> pathAttributes = new Gson().fromJson(objectJson.toString(), |
795 | new TypeToken<ConcurrentHashMap<String, Object>>() { | 802 | new TypeToken<ConcurrentHashMap<String, Object>>() { |
@@ -798,7 +805,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -798,7 +805,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
798 | } | 805 | } |
799 | 806 | ||
800 | private void onDeviceUpdate(LwM2mClient lwM2MClient, Device device, Optional<DeviceProfile> deviceProfileOpt) { | 807 | private void onDeviceUpdate(LwM2mClient lwM2MClient, Device device, Optional<DeviceProfile> deviceProfileOpt) { |
801 | - deviceProfileOpt.ifPresent(deviceProfile -> this.onDeviceProfileUpdate(Collections.singleton(lwM2MClient.getRegistration().getId()), deviceProfile)); | 808 | + deviceProfileOpt.ifPresent(deviceProfile -> this.onDeviceProfileUpdate(Collections.singletonList(lwM2MClient), deviceProfile)); |
802 | lwM2MClient.onDeviceUpdate(device, deviceProfileOpt); | 809 | lwM2MClient.onDeviceUpdate(device, deviceProfileOpt); |
803 | } | 810 | } |
804 | 811 | ||
@@ -843,7 +850,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -843,7 +850,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
843 | } | 850 | } |
844 | 851 | ||
845 | private TransportProtos.KeyValueProto getKvToThingsboard(String pathIdVer, Registration registration) { | 852 | private TransportProtos.KeyValueProto getKvToThingsboard(String pathIdVer, Registration registration) { |
846 | - LwM2mClient lwM2MClient = this.clientContext.getClientByRegistrationId(registration.getId()); | 853 | + LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint()); |
847 | JsonObject names = clientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile(); | 854 | JsonObject names = clientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile(); |
848 | if (names != null && names.has(pathIdVer)) { | 855 | if (names != null && names.has(pathIdVer)) { |
849 | String resourceName = names.get(pathIdVer).getAsString(); | 856 | String resourceName = names.get(pathIdVer).getAsString(); |
@@ -858,7 +865,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -858,7 +865,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
858 | valueKvProto = new JsonObject(); | 865 | valueKvProto = new JsonObject(); |
859 | Object finalvalueKvProto = valueKvProto; | 866 | Object finalvalueKvProto = valueKvProto; |
860 | Gson gson = new GsonBuilder().create(); | 867 | Gson gson = new GsonBuilder().create(); |
861 | - resourceValue.getValues().forEach((k, v) -> { | 868 | + resourceValue.getInstances().forEach((k, v) -> { |
862 | Object val = this.converter.convertValue(v, currentType, expectedType, | 869 | Object val = this.converter.convertValue(v, currentType, expectedType, |
863 | new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); | 870 | new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); |
864 | JsonElement element = gson.toJsonTree(val, val.getClass()); | 871 | JsonElement element = gson.toJsonTree(val, val.getClass()); |
@@ -892,9 +899,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -892,9 +899,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
892 | ResourceModel.Type expectedType = this.helper.getResourceModelTypeEqualsKvProtoValueType(currentType, pathIdVer); | 899 | ResourceModel.Type expectedType = this.helper.getResourceModelTypeEqualsKvProtoValueType(currentType, pathIdVer); |
893 | return this.converter.convertValue(resourceValue.getValue(), currentType, expectedType, | 900 | return this.converter.convertValue(resourceValue.getValue(), currentType, expectedType, |
894 | new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); | 901 | new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); |
895 | - } | ||
896 | - | ||
897 | - else { | 902 | + } else { |
898 | return null; | 903 | return null; |
899 | } | 904 | } |
900 | } | 905 | } |
@@ -955,10 +960,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -955,10 +960,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
955 | * #6.1 - update WriteAttribute | 960 | * #6.1 - update WriteAttribute |
956 | * #6.2 - del WriteAttribute | 961 | * #6.2 - del WriteAttribute |
957 | * | 962 | * |
958 | - * @param registrationIds - | ||
959 | - * @param deviceProfile - | 963 | + * @param clients - |
964 | + * @param deviceProfile - | ||
960 | */ | 965 | */ |
961 | - private void onDeviceProfileUpdate(Set<String> registrationIds, DeviceProfile deviceProfile) { | 966 | + private void onDeviceProfileUpdate(List<LwM2mClient> clients, DeviceProfile deviceProfile) { |
962 | LwM2mClientProfile lwM2MClientProfileOld = clientContext.getProfiles().get(deviceProfile.getUuidId()).clone(); | 967 | LwM2mClientProfile lwM2MClientProfileOld = clientContext.getProfiles().get(deviceProfile.getUuidId()).clone(); |
963 | if (clientContext.profileUpdate(deviceProfile) != null) { | 968 | if (clientContext.profileUpdate(deviceProfile) != null) { |
964 | // #1 | 969 | // #1 |
@@ -1009,15 +1014,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1009,15 +1014,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1009 | 1014 | ||
1010 | // #3.4, #6 | 1015 | // #3.4, #6 |
1011 | if (!attributeLwm2mOld.equals(attributeLwm2mNew)) { | 1016 | if (!attributeLwm2mOld.equals(attributeLwm2mNew)) { |
1012 | - this.getAnalyzerAttributeLwm2m(registrationIds, attributeLwm2mOld, attributeLwm2mNew); | 1017 | + this.getAnalyzerAttributeLwm2m(clients, attributeLwm2mOld, attributeLwm2mNew); |
1013 | } | 1018 | } |
1014 | 1019 | ||
1015 | // #4.1 add | 1020 | // #4.1 add |
1016 | if (sendAttrToThingsboard.getPathPostParametersAdd().size() > 0) { | 1021 | if (sendAttrToThingsboard.getPathPostParametersAdd().size() > 0) { |
1017 | // update value in Resources | 1022 | // update value in Resources |
1018 | - registrationIds.forEach(registrationId -> { | ||
1019 | - Registration registration = clientContext.getRegistration(registrationId); | ||
1020 | - this.readObserveFromProfile(registration, sendAttrToThingsboard.getPathPostParametersAdd(), READ); | 1023 | + clients.forEach(client -> { |
1024 | + this.readObserveFromProfile(client, sendAttrToThingsboard.getPathPostParametersAdd(), READ); | ||
1021 | }); | 1025 | }); |
1022 | } | 1026 | } |
1023 | // #4.2 del | 1027 | // #4.2 del |
@@ -1041,15 +1045,15 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1041,15 +1045,15 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1041 | // does not include oldObserve | 1045 | // does not include oldObserve |
1042 | ResultsAnalyzerParameters postObserveAnalyzer = this.getAnalyzerParameters(sendObserveToClientOld.getPathPostParametersAdd(), sendObserveToClientNew.getPathPostParametersAdd()); | 1046 | ResultsAnalyzerParameters postObserveAnalyzer = this.getAnalyzerParameters(sendObserveToClientOld.getPathPostParametersAdd(), sendObserveToClientNew.getPathPostParametersAdd()); |
1043 | // send Request observe to Client | 1047 | // send Request observe to Client |
1044 | - registrationIds.forEach(registrationId -> { | ||
1045 | - Registration registration = clientContext.getRegistration(registrationId); | 1048 | + clients.forEach(client -> { |
1049 | + Registration registration = client.getRegistration(); | ||
1046 | if (postObserveAnalyzer.getPathPostParametersAdd().size() > 0) { | 1050 | if (postObserveAnalyzer.getPathPostParametersAdd().size() > 0) { |
1047 | - this.readObserveFromProfile(registration, postObserveAnalyzer.getPathPostParametersAdd(), OBSERVE); | 1051 | + this.readObserveFromProfile(client, postObserveAnalyzer.getPathPostParametersAdd(), OBSERVE); |
1048 | } | 1052 | } |
1049 | // 5.3 del | 1053 | // 5.3 del |
1050 | // send Request cancel observe to Client | 1054 | // send Request cancel observe to Client |
1051 | if (postObserveAnalyzer.getPathPostParametersDel().size() > 0) { | 1055 | if (postObserveAnalyzer.getPathPostParametersDel().size() > 0) { |
1052 | - this.cancelObserveFromProfile(registration, postObserveAnalyzer.getPathPostParametersDel()); | 1056 | + this.cancelObserveFromProfile(client, postObserveAnalyzer.getPathPostParametersDel()); |
1053 | } | 1057 | } |
1054 | }); | 1058 | }); |
1055 | } | 1059 | } |
@@ -1086,19 +1090,18 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1086,19 +1090,18 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1086 | * Update Resource value after change RezAttrTelemetry in config Profile | 1090 | * Update Resource value after change RezAttrTelemetry in config Profile |
1087 | * send response Read to Client and add path to pathResAttrTelemetry in LwM2MClient.getAttrTelemetryObserveValue() | 1091 | * send response Read to Client and add path to pathResAttrTelemetry in LwM2MClient.getAttrTelemetryObserveValue() |
1088 | * | 1092 | * |
1089 | - * @param registration - Registration LwM2M Client | ||
1090 | - * @param targets - path Resources == [ "/2/0/0", "/2/0/1"] | 1093 | + * @param targets - path Resources == [ "/2/0/0", "/2/0/1"] |
1091 | */ | 1094 | */ |
1092 | - private void readObserveFromProfile(Registration registration, Set<String> targets, LwM2mTypeOper typeOper) { | 1095 | + private void readObserveFromProfile(LwM2mClient client, Set<String> targets, LwM2mTypeOper typeOper) { |
1093 | targets.forEach(target -> { | 1096 | targets.forEach(target -> { |
1094 | LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(target)); | 1097 | LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(target)); |
1095 | if (pathIds.isResource()) { | 1098 | if (pathIds.isResource()) { |
1096 | if (READ.equals(typeOper)) { | 1099 | if (READ.equals(typeOper)) { |
1097 | - lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, | ||
1098 | - ContentFormat.TLV.getName(), null, this.config.getTimeout(), null); | 1100 | + lwM2mTransportRequest.sendAllRequest(client, target, typeOper, |
1101 | + null, this.config.getTimeout(), null); | ||
1099 | } else if (OBSERVE.equals(typeOper)) { | 1102 | } else if (OBSERVE.equals(typeOper)) { |
1100 | - lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, | ||
1101 | - null, null, this.config.getTimeout(), null); | 1103 | + lwM2mTransportRequest.sendAllRequest(client, target, typeOper, |
1104 | + null, this.config.getTimeout(), null); | ||
1102 | } | 1105 | } |
1103 | } | 1106 | } |
1104 | }); | 1107 | }); |
@@ -1124,7 +1127,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1124,7 +1127,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1124 | * @param attributeLwm2mNew - | 1127 | * @param attributeLwm2mNew - |
1125 | * @return | 1128 | * @return |
1126 | */ | 1129 | */ |
1127 | - private void getAnalyzerAttributeLwm2m(Set<String> registrationIds, JsonObject attributeLwm2mOld, JsonObject attributeLwm2mNew) { | 1130 | + private void getAnalyzerAttributeLwm2m(List<LwM2mClient> clients, JsonObject attributeLwm2mOld, JsonObject attributeLwm2mNew) { |
1128 | ResultsAnalyzerParameters analyzerParameters = new ResultsAnalyzerParameters(); | 1131 | ResultsAnalyzerParameters analyzerParameters = new ResultsAnalyzerParameters(); |
1129 | ConcurrentHashMap<String, Object> lwm2mAttributesOld = new Gson().fromJson(attributeLwm2mOld.toString(), | 1132 | ConcurrentHashMap<String, Object> lwm2mAttributesOld = new Gson().fromJson(attributeLwm2mOld.toString(), |
1130 | new TypeToken<ConcurrentHashMap<String, Object>>() { | 1133 | new TypeToken<ConcurrentHashMap<String, Object>>() { |
@@ -1146,23 +1149,22 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1146,23 +1149,22 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1146 | // #6 | 1149 | // #6 |
1147 | // #6.2 | 1150 | // #6.2 |
1148 | if (analyzerParameters.getPathPostParametersAdd().size() > 0) { | 1151 | if (analyzerParameters.getPathPostParametersAdd().size() > 0) { |
1149 | - registrationIds.forEach(registrationId -> { | ||
1150 | - Registration registration = this.clientContext.getRegistration(registrationId); | ||
1151 | - Set<String> clientObjects = clientContext.getSupportedIdVerInClient(registration); | 1152 | + clients.forEach(client -> { |
1153 | + Set<String> clientObjects = clientContext.getSupportedIdVerInClient(client); | ||
1152 | Set<String> pathSend = analyzerParameters.getPathPostParametersAdd().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) | 1154 | Set<String> pathSend = analyzerParameters.getPathPostParametersAdd().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) |
1153 | .collect(Collectors.toUnmodifiableSet()); | 1155 | .collect(Collectors.toUnmodifiableSet()); |
1154 | if (!pathSend.isEmpty()) { | 1156 | if (!pathSend.isEmpty()) { |
1155 | ConcurrentHashMap<String, Object> finalParams = lwm2mAttributesNew; | 1157 | ConcurrentHashMap<String, Object> finalParams = lwm2mAttributesNew; |
1156 | - pathSend.forEach(target -> lwM2mTransportRequest.sendAllRequest(registration, target, WRITE_ATTRIBUTES, ContentFormat.TLV.getName(), | 1158 | + pathSend.forEach(target -> lwM2mTransportRequest.sendAllRequest(client, target, WRITE_ATTRIBUTES, |
1157 | finalParams.get(target), this.config.getTimeout(), null)); | 1159 | finalParams.get(target), this.config.getTimeout(), null)); |
1158 | } | 1160 | } |
1159 | }); | 1161 | }); |
1160 | } | 1162 | } |
1161 | // #6.2 | 1163 | // #6.2 |
1162 | if (analyzerParameters.getPathPostParametersDel().size() > 0) { | 1164 | if (analyzerParameters.getPathPostParametersDel().size() > 0) { |
1163 | - registrationIds.forEach(registrationId -> { | ||
1164 | - Registration registration = this.clientContext.getRegistration(registrationId); | ||
1165 | - Set<String> clientObjects = clientContext.getSupportedIdVerInClient(registration); | 1165 | + clients.forEach(client -> { |
1166 | + Registration registration = client.getRegistration(); | ||
1167 | + Set<String> clientObjects = clientContext.getSupportedIdVerInClient(client); | ||
1166 | Set<String> pathSend = analyzerParameters.getPathPostParametersDel().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) | 1168 | Set<String> pathSend = analyzerParameters.getPathPostParametersDel().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) |
1167 | .collect(Collectors.toUnmodifiableSet()); | 1169 | .collect(Collectors.toUnmodifiableSet()); |
1168 | if (!pathSend.isEmpty()) { | 1170 | if (!pathSend.isEmpty()) { |
@@ -1170,8 +1172,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1170,8 +1172,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1170 | Map<String, Object> params = (Map<String, Object>) lwm2mAttributesOld.get(target); | 1172 | Map<String, Object> params = (Map<String, Object>) lwm2mAttributesOld.get(target); |
1171 | params.clear(); | 1173 | params.clear(); |
1172 | params.put(OBJECT_VERSION, ""); | 1174 | params.put(OBJECT_VERSION, ""); |
1173 | - lwM2mTransportRequest.sendAllRequest(registration, target, WRITE_ATTRIBUTES, ContentFormat.TLV.getName(), | ||
1174 | - params, this.config.getTimeout(), null); | 1175 | + lwM2mTransportRequest.sendAllRequest(client, target, WRITE_ATTRIBUTES, params, this.config.getTimeout(), null); |
1175 | }); | 1176 | }); |
1176 | } | 1177 | } |
1177 | }); | 1178 | }); |
@@ -1179,12 +1180,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1179,12 +1180,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1179 | 1180 | ||
1180 | } | 1181 | } |
1181 | 1182 | ||
1182 | - private void cancelObserveFromProfile(Registration registration, Set<String> paramAnallyzer) { | ||
1183 | - LwM2mClient lwM2MClient = clientContext.getOrRegister(registration); | 1183 | + private void cancelObserveFromProfile(LwM2mClient lwM2mClient, Set<String> paramAnallyzer) { |
1184 | paramAnallyzer.forEach(pathIdVer -> { | 1184 | paramAnallyzer.forEach(pathIdVer -> { |
1185 | - if (this.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer) != null) { | ||
1186 | - lwM2mTransportRequest.sendAllRequest(registration, pathIdVer, OBSERVE_CANCEL, null, | ||
1187 | - null, this.config.getTimeout(), null); | 1185 | + if (this.getResourceValueFromLwM2MClient(lwM2mClient, pathIdVer) != null) { |
1186 | + lwM2mTransportRequest.sendAllRequest(lwM2mClient, pathIdVer, OBSERVE_CANCEL, null, this.config.getTimeout(), null); | ||
1188 | } | 1187 | } |
1189 | } | 1188 | } |
1190 | ); | 1189 | ); |
@@ -1192,14 +1191,12 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1192,14 +1191,12 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1192 | 1191 | ||
1193 | private void updateResourcesValueToClient(LwM2mClient lwM2MClient, Object valueOld, Object valueNew, String path) { | 1192 | private void updateResourcesValueToClient(LwM2mClient lwM2MClient, Object valueOld, Object valueNew, String path) { |
1194 | if (valueNew != null && (valueOld == null || !valueNew.toString().equals(valueOld.toString()))) { | 1193 | if (valueNew != null && (valueOld == null || !valueNew.toString().equals(valueOld.toString()))) { |
1195 | - lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), path, WRITE_REPLACE, | ||
1196 | - ContentFormat.TLV.getName(), valueNew, | ||
1197 | - this.config.getTimeout(), null); | 1194 | + lwM2mTransportRequest.sendAllRequest(lwM2MClient, path, WRITE_REPLACE, valueNew, this.config.getTimeout(), null); |
1198 | } else { | 1195 | } else { |
1199 | log.error("Failed update resource [{}] [{}]", path, valueNew); | 1196 | log.error("Failed update resource [{}] [{}]", path, valueNew); |
1200 | String logMsg = String.format("%s: Failed update resource path - %s value - %s. Value is not changed or bad", | 1197 | String logMsg = String.format("%s: Failed update resource path - %s value - %s. Value is not changed or bad", |
1201 | LOG_LW2M_ERROR, path, valueNew); | 1198 | LOG_LW2M_ERROR, path, valueNew); |
1202 | - this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration().getId()); | 1199 | + this.sendLogsToThingsboard(lwM2MClient, logMsg); |
1203 | log.info("Failed update resource [{}] [{}]", path, valueNew); | 1200 | log.info("Failed update resource [{}] [{}]", path, valueNew); |
1204 | } | 1201 | } |
1205 | } | 1202 | } |
@@ -1221,7 +1218,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1221,7 +1218,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1221 | */ | 1218 | */ |
1222 | public String getPresentPathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) { | 1219 | public String getPresentPathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) { |
1223 | LwM2mClientProfile profile = clientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); | 1220 | LwM2mClientProfile profile = clientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); |
1224 | - LwM2mClient lwM2mClient = clientContext.getClient(sessionInfo); | 1221 | + LwM2mClient lwM2mClient = clientContext.getClientBySessionInfo(sessionInfo); |
1225 | return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() | 1222 | return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() |
1226 | .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModel(lwM2mClient, e.getKey(), false)).findFirst().map(Map.Entry::getKey) | 1223 | .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModel(lwM2mClient, e.getKey(), false)).findFirst().map(Map.Entry::getKey) |
1227 | .orElse(null); | 1224 | .orElse(null); |
@@ -1256,7 +1253,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1256,7 +1253,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1256 | * @param sessionInfo | 1253 | * @param sessionInfo |
1257 | */ | 1254 | */ |
1258 | public void updateAttributeFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) { | 1255 | public void updateAttributeFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) { |
1259 | - LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo); | 1256 | + LwM2mClient lwM2MClient = clientContext.getClientBySessionInfo(sessionInfo); |
1260 | if (lwM2MClient != null) { | 1257 | if (lwM2MClient != null) { |
1261 | log.warn("1) UpdateAttributeFromThingsboard, tsKvProtos [{}]", tsKvProtos); | 1258 | log.warn("1) UpdateAttributeFromThingsboard, tsKvProtos [{}]", tsKvProtos); |
1262 | tsKvProtos.forEach(tsKvProto -> { | 1259 | tsKvProtos.forEach(tsKvProto -> { |
@@ -1275,8 +1272,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1275,8 +1272,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1275 | this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), | 1272 | this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), |
1276 | getValueFromKvProto(tsKvProto.getKv()), pathIdVer); | 1273 | getValueFromKvProto(tsKvProto.getKv()), pathIdVer); |
1277 | }); | 1274 | }); |
1278 | - } | ||
1279 | - else { | 1275 | + } else { |
1280 | log.error("UpdateAttributeFromThingsboard, lwM2MClient is null"); | 1276 | log.error("UpdateAttributeFromThingsboard, lwM2MClient is null"); |
1281 | } | 1277 | } |
1282 | } | 1278 | } |
@@ -1285,14 +1281,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1285,14 +1281,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1285 | * @param lwM2MClient - | 1281 | * @param lwM2MClient - |
1286 | * @return SessionInfoProto - | 1282 | * @return SessionInfoProto - |
1287 | */ | 1283 | */ |
1288 | - private SessionInfoProto getSessionInfoOrCloseSession(LwM2mClient lwM2MClient) { | ||
1289 | - if (lwM2MClient != null) { | ||
1290 | - SessionInfoProto sessionInfoProto = lwM2MClient.getSession(); | ||
1291 | - if (sessionInfoProto == null) { | ||
1292 | - log.info("[{}] [{}]", lwM2MClient.getEndpoint(), CLIENT_NOT_AUTHORIZED); | ||
1293 | - this.closeClientSession(lwM2MClient.getRegistration()); | ||
1294 | - } | ||
1295 | - return sessionInfoProto; | 1284 | + private SessionInfoProto getSessionInfo(LwM2mClient lwM2MClient) { |
1285 | + if (lwM2MClient != null && lwM2MClient.getSession() != null) { | ||
1286 | + return lwM2MClient.getSession(); | ||
1296 | } | 1287 | } |
1297 | return null; | 1288 | return null; |
1298 | } | 1289 | } |
@@ -1302,15 +1293,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1302,15 +1293,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1302 | * @return - sessionInfo after access connect client | 1293 | * @return - sessionInfo after access connect client |
1303 | */ | 1294 | */ |
1304 | public SessionInfoProto getSessionInfoOrCloseSession(Registration registration) { | 1295 | public SessionInfoProto getSessionInfoOrCloseSession(Registration registration) { |
1305 | - return getSessionInfoOrCloseSession(clientContext.getOrRegister(registration)); | ||
1306 | - } | ||
1307 | - | ||
1308 | - /** | ||
1309 | - * @param registrationId - | ||
1310 | - * @return - | ||
1311 | - */ | ||
1312 | - private SessionInfoProto getSessionInfoOrCloseSession(String registrationId) { | ||
1313 | - return getSessionInfoOrCloseSession(clientContext.getClientByRegistrationId(registrationId)); | 1296 | + return getSessionInfo(clientContext.getClientByEndpoint(registration.getEndpoint())); |
1314 | } | 1297 | } |
1315 | 1298 | ||
1316 | /** | 1299 | /** |
@@ -1340,7 +1323,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1340,7 +1323,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1340 | * @param lwM2MClient - LwM2M Client | 1323 | * @param lwM2MClient - LwM2M Client |
1341 | */ | 1324 | */ |
1342 | public void putDelayedUpdateResourcesThingsboard(LwM2mClient lwM2MClient) { | 1325 | public void putDelayedUpdateResourcesThingsboard(LwM2mClient lwM2MClient) { |
1343 | - SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); | 1326 | + SessionInfoProto sessionInfo = this.getSessionInfo(lwM2MClient); |
1344 | if (sessionInfo != null) { | 1327 | if (sessionInfo != null) { |
1345 | //#1.1 | 1328 | //#1.1 |
1346 | ConcurrentMap<String, String> keyNamesMap = this.getNamesFromProfileForSharedAttributes(lwM2MClient); | 1329 | ConcurrentMap<String, String> keyNamesMap = this.getNamesFromProfileForSharedAttributes(lwM2MClient); |
@@ -1359,7 +1342,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1359,7 +1342,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1359 | 1342 | ||
1360 | public void getInfoFirmwareUpdate(LwM2mClient lwM2MClient, Lwm2mClientRpcRequest rpcRequest) { | 1343 | public void getInfoFirmwareUpdate(LwM2mClient lwM2MClient, Lwm2mClientRpcRequest rpcRequest) { |
1361 | if (lwM2MClient.getRegistration().getSupportedVersion(FW_ID) != null) { | 1344 | if (lwM2MClient.getRegistration().getSupportedVersion(FW_ID) != null) { |
1362 | - SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); | 1345 | + SessionInfoProto sessionInfo = this.getSessionInfo(lwM2MClient); |
1363 | if (sessionInfo != null) { | 1346 | if (sessionInfo != null) { |
1364 | DefaultLwM2MTransportMsgHandler handler = this; | 1347 | DefaultLwM2MTransportMsgHandler handler = this; |
1365 | this.transportService.process(sessionInfo, createOtaPackageRequestMsg(sessionInfo, OtaPackageType.FIRMWARE.name()), | 1348 | this.transportService.process(sessionInfo, createOtaPackageRequestMsg(sessionInfo, OtaPackageType.FIRMWARE.name()), |
@@ -1368,16 +1351,15 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1368,16 +1351,15 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1368 | public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { | 1351 | public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { |
1369 | if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) | 1352 | if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) |
1370 | && response.getType().equals(OtaPackageType.FIRMWARE.name())) { | 1353 | && response.getType().equals(OtaPackageType.FIRMWARE.name())) { |
1371 | - log.warn ("7) firmware start with ver: [{}]", response.getVersion()); | 1354 | + log.warn("7) firmware start with ver: [{}]", response.getVersion()); |
1372 | lwM2MClient.getFwUpdate().setRpcRequest(rpcRequest); | 1355 | lwM2MClient.getFwUpdate().setRpcRequest(rpcRequest); |
1373 | lwM2MClient.getFwUpdate().setCurrentVersion(response.getVersion()); | 1356 | lwM2MClient.getFwUpdate().setCurrentVersion(response.getVersion()); |
1374 | lwM2MClient.getFwUpdate().setCurrentTitle(response.getTitle()); | 1357 | lwM2MClient.getFwUpdate().setCurrentTitle(response.getTitle()); |
1375 | lwM2MClient.getFwUpdate().setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId()); | 1358 | lwM2MClient.getFwUpdate().setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId()); |
1376 | if (rpcRequest == null) { | 1359 | if (rpcRequest == null) { |
1377 | lwM2MClient.getFwUpdate().sendReadObserveInfo(lwM2mTransportRequest); | 1360 | lwM2MClient.getFwUpdate().sendReadObserveInfo(lwM2mTransportRequest); |
1378 | - } | ||
1379 | - else { | ||
1380 | - lwM2MClient.getFwUpdate().writeFwSwWare(handler, lwM2mTransportRequest); | 1361 | + } else { |
1362 | + lwM2MClient.getFwUpdate().writeFwSwWare(handler, lwM2mTransportRequest); | ||
1381 | } | 1363 | } |
1382 | } else { | 1364 | } else { |
1383 | log.trace("OtaPackage [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); | 1365 | log.trace("OtaPackage [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); |
@@ -1395,7 +1377,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1395,7 +1377,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1395 | 1377 | ||
1396 | public void getInfoSoftwareUpdate(LwM2mClient lwM2MClient, Lwm2mClientRpcRequest rpcRequest) { | 1378 | public void getInfoSoftwareUpdate(LwM2mClient lwM2MClient, Lwm2mClientRpcRequest rpcRequest) { |
1397 | if (lwM2MClient.getRegistration().getSupportedVersion(SW_ID) != null) { | 1379 | if (lwM2MClient.getRegistration().getSupportedVersion(SW_ID) != null) { |
1398 | - SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); | 1380 | + SessionInfoProto sessionInfo = this.getSessionInfo(lwM2MClient); |
1399 | if (sessionInfo != null) { | 1381 | if (sessionInfo != null) { |
1400 | DefaultLwM2MTransportMsgHandler handler = this; | 1382 | DefaultLwM2MTransportMsgHandler handler = this; |
1401 | transportService.process(sessionInfo, createOtaPackageRequestMsg(sessionInfo, OtaPackageType.SOFTWARE.name()), | 1383 | transportService.process(sessionInfo, createOtaPackageRequestMsg(sessionInfo, OtaPackageType.SOFTWARE.name()), |
@@ -1411,9 +1393,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1411,9 +1393,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1411 | lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest); | 1393 | lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest); |
1412 | if (rpcRequest == null) { | 1394 | if (rpcRequest == null) { |
1413 | lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest); | 1395 | lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest); |
1414 | - } | ||
1415 | - else { | ||
1416 | - lwM2MClient.getSwUpdate().writeFwSwWare(handler, lwM2mTransportRequest); | 1396 | + } else { |
1397 | + lwM2MClient.getSwUpdate().writeFwSwWare(handler, lwM2mTransportRequest); | ||
1417 | } | 1398 | } |
1418 | } else { | 1399 | } else { |
1419 | log.trace("Software [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); | 1400 | log.trace("Software [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); |
@@ -36,6 +36,8 @@ import org.thingsboard.server.transport.lwm2m.secure.LWM2MGenerationPSkRPkECC; | @@ -36,6 +36,8 @@ import org.thingsboard.server.transport.lwm2m.secure.LWM2MGenerationPSkRPkECC; | ||
36 | import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MAuthorizer; | 36 | import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MAuthorizer; |
37 | import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MDtlsCertificateVerifier; | 37 | import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MDtlsCertificateVerifier; |
38 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; | 38 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
39 | +import org.thingsboard.server.transport.lwm2m.server.store.TbEditableSecurityStore; | ||
40 | +import org.thingsboard.server.transport.lwm2m.server.store.TbSecurityStore; | ||
39 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; | 41 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; |
40 | 42 | ||
41 | import javax.annotation.PostConstruct; | 43 | import javax.annotation.PostConstruct; |
@@ -83,7 +85,7 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService { | @@ -83,7 +85,7 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService { | ||
83 | private final LwM2mTransportServerHelper helper; | 85 | private final LwM2mTransportServerHelper helper; |
84 | private final LwM2mTransportMsgHandler handler; | 86 | private final LwM2mTransportMsgHandler handler; |
85 | private final CaliforniumRegistrationStore registrationStore; | 87 | private final CaliforniumRegistrationStore registrationStore; |
86 | - private final EditableSecurityStore securityStore; | 88 | + private final TbSecurityStore securityStore; |
87 | private final LwM2mClientContext lwM2mClientContext; | 89 | private final LwM2mClientContext lwM2mClientContext; |
88 | private final TbLwM2MDtlsCertificateVerifier certificateVerifier; | 90 | private final TbLwM2MDtlsCertificateVerifier certificateVerifier; |
89 | private final TbLwM2MAuthorizer authorizer; | 91 | private final TbLwM2MAuthorizer authorizer; |
@@ -87,7 +87,7 @@ public class LwM2mServerListener { | @@ -87,7 +87,7 @@ public class LwM2mServerListener { | ||
87 | @Override | 87 | @Override |
88 | public void cancelled(Observation observation) { | 88 | public void cancelled(Observation observation) { |
89 | String msg = String.format("%s: Canceled Observation %s.", LOG_LW2M_INFO, observation.getPath()); | 89 | String msg = String.format("%s: Canceled Observation %s.", LOG_LW2M_INFO, observation.getPath()); |
90 | - service.sendLogsToThingsboard(msg, observation.getRegistrationId()); | 90 | + service.sendLogsToThingsboard(observation.getRegistrationId(), msg); |
91 | log.warn(msg); | 91 | log.warn(msg); |
92 | } | 92 | } |
93 | 93 | ||
@@ -109,7 +109,7 @@ public class LwM2mServerListener { | @@ -109,7 +109,7 @@ public class LwM2mServerListener { | ||
109 | String msg = String.format("%s: Successful start newObservation %s.", LOG_LW2M_INFO, | 109 | String msg = String.format("%s: Successful start newObservation %s.", LOG_LW2M_INFO, |
110 | observation.getPath()); | 110 | observation.getPath()); |
111 | log.warn(msg); | 111 | log.warn(msg); |
112 | - service.sendLogsToThingsboard(msg, registration.getId()); | 112 | + service.sendLogsToThingsboard(registration.getId(), msg); |
113 | } | 113 | } |
114 | }; | 114 | }; |
115 | } | 115 | } |
@@ -22,6 +22,7 @@ import org.thingsboard.server.common.data.Device; | @@ -22,6 +22,7 @@ import org.thingsboard.server.common.data.Device; | ||
22 | import org.thingsboard.server.common.data.DeviceProfile; | 22 | import org.thingsboard.server.common.data.DeviceProfile; |
23 | import org.thingsboard.server.gen.transport.TransportProtos; | 23 | import org.thingsboard.server.gen.transport.TransportProtos; |
24 | import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; | 24 | import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; |
25 | +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; | ||
25 | import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; | 26 | import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; |
26 | 27 | ||
27 | import java.util.Collection; | 28 | import java.util.Collection; |
@@ -57,13 +58,13 @@ public interface LwM2mTransportMsgHandler { | @@ -57,13 +58,13 @@ public interface LwM2mTransportMsgHandler { | ||
57 | 58 | ||
58 | void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg toServerResponse); | 59 | void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg toServerResponse); |
59 | 60 | ||
60 | - void doTrigger(Registration registration, String path); | ||
61 | - | ||
62 | void doDisconnect(TransportProtos.SessionInfoProto sessionInfo); | 61 | void doDisconnect(TransportProtos.SessionInfoProto sessionInfo); |
63 | 62 | ||
64 | void onAwakeDev(Registration registration); | 63 | void onAwakeDev(Registration registration); |
65 | 64 | ||
66 | - void sendLogsToThingsboard(String msg, String registrationId); | 65 | + void sendLogsToThingsboard(LwM2mClient client, String msg); |
66 | + | ||
67 | + void sendLogsToThingsboard(String registrationId, String msg); | ||
67 | 68 | ||
68 | LwM2MTransportServerConfig getConfig(); | 69 | LwM2MTransportServerConfig getConfig(); |
69 | } | 70 | } |
@@ -32,10 +32,10 @@ import org.eclipse.leshan.core.observation.Observation; | @@ -32,10 +32,10 @@ import org.eclipse.leshan.core.observation.Observation; | ||
32 | import org.eclipse.leshan.core.request.ContentFormat; | 32 | import org.eclipse.leshan.core.request.ContentFormat; |
33 | import org.eclipse.leshan.core.request.DeleteRequest; | 33 | import org.eclipse.leshan.core.request.DeleteRequest; |
34 | import org.eclipse.leshan.core.request.DiscoverRequest; | 34 | import org.eclipse.leshan.core.request.DiscoverRequest; |
35 | -import org.eclipse.leshan.core.request.DownlinkRequest; | ||
36 | import org.eclipse.leshan.core.request.ExecuteRequest; | 35 | import org.eclipse.leshan.core.request.ExecuteRequest; |
37 | import org.eclipse.leshan.core.request.ObserveRequest; | 36 | import org.eclipse.leshan.core.request.ObserveRequest; |
38 | import org.eclipse.leshan.core.request.ReadRequest; | 37 | import org.eclipse.leshan.core.request.ReadRequest; |
38 | +import org.eclipse.leshan.core.request.SimpleDownlinkRequest; | ||
39 | import org.eclipse.leshan.core.request.WriteAttributesRequest; | 39 | import org.eclipse.leshan.core.request.WriteAttributesRequest; |
40 | import org.eclipse.leshan.core.request.WriteRequest; | 40 | import org.eclipse.leshan.core.request.WriteRequest; |
41 | import org.eclipse.leshan.core.request.exception.ClientSleepingException; | 41 | import org.eclipse.leshan.core.request.exception.ClientSleepingException; |
@@ -116,32 +116,30 @@ public class LwM2mTransportRequest { | @@ -116,32 +116,30 @@ public class LwM2mTransportRequest { | ||
116 | new NamedThreadFactory(String.format("LwM2M %s channel response after request", RESPONSE_REQUEST_CHANNEL))); | 116 | new NamedThreadFactory(String.format("LwM2M %s channel response after request", RESPONSE_REQUEST_CHANNEL))); |
117 | } | 117 | } |
118 | 118 | ||
119 | - /** | ||
120 | - * Device management and service enablement, including Read, Write, Execute, Discover, Create, Delete and Write-Attributes | ||
121 | - * | ||
122 | - * @param registration - | ||
123 | - * @param targetIdVer - | ||
124 | - * @param typeOper - | ||
125 | - * @param contentFormatName - | ||
126 | - */ | 119 | + public void sendAllRequest(LwM2mClient lwM2MClient, String targetIdVer, LwM2mTypeOper typeOper, Object params, long timeoutInMs, Lwm2mClientRpcRequest lwm2mClientRpcRequest) { |
120 | + sendAllRequest(lwM2MClient, targetIdVer, typeOper, lwM2MClient.getDefaultContentFormat(), params, timeoutInMs, lwm2mClientRpcRequest); | ||
121 | + } | ||
122 | + | ||
127 | 123 | ||
128 | - public void sendAllRequest(Registration registration, String targetIdVer, LwM2mTypeOper typeOper, | ||
129 | - String contentFormatName, Object params, long timeoutInMs, Lwm2mClientRpcRequest lwm2mClientRpcRequest) { | 124 | + public void sendAllRequest(LwM2mClient lwM2MClient, String targetIdVer, LwM2mTypeOper typeOper, |
125 | + ContentFormat contentFormat, Object params, long timeoutInMs, Lwm2mClientRpcRequest lwm2mClientRpcRequest) { | ||
126 | + Registration registration = lwM2MClient.getRegistration(); | ||
130 | try { | 127 | try { |
131 | String target = convertPathFromIdVerToObjectId(targetIdVer); | 128 | String target = convertPathFromIdVerToObjectId(targetIdVer); |
132 | - ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT; | ||
133 | - LwM2mClient lwM2MClient = this.lwM2mClientContext.getOrRegister(registration); | 129 | + if(contentFormat == null){ |
130 | + contentFormat = ContentFormat.DEFAULT; | ||
131 | + } | ||
134 | LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null; | 132 | LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null; |
135 | if (!OBSERVE_CANCEL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && lwM2MClient != null) { | 133 | if (!OBSERVE_CANCEL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && lwM2MClient != null) { |
136 | if (lwM2MClient.isValidObjectVersion(targetIdVer)) { | 134 | if (lwM2MClient.isValidObjectVersion(targetIdVer)) { |
137 | timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT; | 135 | timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT; |
138 | - DownlinkRequest request = createRequest(registration, lwM2MClient, typeOper, contentFormat, target, | 136 | + SimpleDownlinkRequest request = createRequest(registration, lwM2MClient, typeOper, contentFormat, target, |
139 | targetIdVer, resultIds, params, lwm2mClientRpcRequest); | 137 | targetIdVer, resultIds, params, lwm2mClientRpcRequest); |
140 | if (request != null) { | 138 | if (request != null) { |
141 | try { | 139 | try { |
142 | this.sendRequest(registration, lwM2MClient, request, timeoutInMs, lwm2mClientRpcRequest); | 140 | this.sendRequest(registration, lwM2MClient, request, timeoutInMs, lwm2mClientRpcRequest); |
143 | } catch (ClientSleepingException e) { | 141 | } catch (ClientSleepingException e) { |
144 | - DownlinkRequest finalRequest = request; | 142 | + SimpleDownlinkRequest finalRequest = request; |
145 | long finalTimeoutInMs = timeoutInMs; | 143 | long finalTimeoutInMs = timeoutInMs; |
146 | Lwm2mClientRpcRequest finalRpcRequest = lwm2mClientRpcRequest; | 144 | Lwm2mClientRpcRequest finalRpcRequest = lwm2mClientRpcRequest; |
147 | lwM2MClient.getQueuedRequests().add(() -> sendRequest(registration, lwM2MClient, finalRequest, finalTimeoutInMs, finalRpcRequest)); | 145 | lwM2MClient.getQueuedRequests().add(() -> sendRequest(registration, lwM2MClient, finalRequest, finalTimeoutInMs, finalRpcRequest)); |
@@ -185,7 +183,7 @@ public class LwM2mTransportRequest { | @@ -185,7 +183,7 @@ public class LwM2mTransportRequest { | ||
185 | } | 183 | } |
186 | String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO, | 184 | String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO, |
187 | typeOper.name(), paths); | 185 | typeOper.name(), paths); |
188 | - this.handler.sendLogsToThingsboard(msg, registration.getId()); | 186 | + this.handler.sendLogsToThingsboard(lwM2MClient, msg); |
189 | if (lwm2mClientRpcRequest != null) { | 187 | if (lwm2mClientRpcRequest != null) { |
190 | String valueMsg = String.format("Paths - %s", paths); | 188 | String valueMsg = String.format("Paths - %s", paths); |
191 | this.handler.sentRpcResponse(lwm2mClientRpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE); | 189 | this.handler.sentRpcResponse(lwm2mClientRpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE); |
@@ -204,7 +202,7 @@ public class LwM2mTransportRequest { | @@ -204,7 +202,7 @@ public class LwM2mTransportRequest { | ||
204 | observeCancelMsg = String.format("%s: type operation %s paths: All count: %d", LOG_LW2M_INFO, | 202 | observeCancelMsg = String.format("%s: type operation %s paths: All count: %d", LOG_LW2M_INFO, |
205 | OBSERVE_CANCEL.name(), observeCancelCnt); | 203 | OBSERVE_CANCEL.name(), observeCancelCnt); |
206 | } | 204 | } |
207 | - this.afterObserveCancel(registration, observeCancelCnt, observeCancelMsg, lwm2mClientRpcRequest); | 205 | + this.afterObserveCancel(lwM2MClient, observeCancelCnt, observeCancelMsg, lwm2mClientRpcRequest); |
208 | break; | 206 | break; |
209 | // lwm2mClientRpcRequest != null | 207 | // lwm2mClientRpcRequest != null |
210 | case FW_UPDATE: | 208 | case FW_UPDATE: |
@@ -215,7 +213,7 @@ public class LwM2mTransportRequest { | @@ -215,7 +213,7 @@ public class LwM2mTransportRequest { | ||
215 | } catch (Exception e) { | 213 | } catch (Exception e) { |
216 | String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR, | 214 | String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR, |
217 | typeOper.name(), e.getMessage()); | 215 | typeOper.name(), e.getMessage()); |
218 | - handler.sendLogsToThingsboard(msg, registration.getId()); | 216 | + handler.sendLogsToThingsboard(lwM2MClient, msg); |
219 | if (lwm2mClientRpcRequest != null) { | 217 | if (lwm2mClientRpcRequest != null) { |
220 | String errorMsg = String.format("Path %s type operation %s %s", targetIdVer, typeOper.name(), e.getMessage()); | 218 | String errorMsg = String.format("Path %s type operation %s %s", targetIdVer, typeOper.name(), e.getMessage()); |
221 | handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); | 219 | handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); |
@@ -223,10 +221,10 @@ public class LwM2mTransportRequest { | @@ -223,10 +221,10 @@ public class LwM2mTransportRequest { | ||
223 | } | 221 | } |
224 | } | 222 | } |
225 | 223 | ||
226 | - private DownlinkRequest createRequest(Registration registration, LwM2mClient lwM2MClient, LwM2mTypeOper typeOper, | 224 | + private SimpleDownlinkRequest createRequest(Registration registration, LwM2mClient lwM2MClient, LwM2mTypeOper typeOper, |
227 | ContentFormat contentFormat, String target, String targetIdVer, | 225 | ContentFormat contentFormat, String target, String targetIdVer, |
228 | LwM2mPath resultIds, Object params, Lwm2mClientRpcRequest rpcRequest) { | 226 | LwM2mPath resultIds, Object params, Lwm2mClientRpcRequest rpcRequest) { |
229 | - DownlinkRequest request = null; | 227 | + SimpleDownlinkRequest request = null; |
230 | switch (typeOper) { | 228 | switch (typeOper) { |
231 | case READ: | 229 | case READ: |
232 | request = new ReadRequest(contentFormat, target); | 230 | request = new ReadRequest(contentFormat, target); |
@@ -273,7 +271,7 @@ public class LwM2mTransportRequest { | @@ -273,7 +271,7 @@ public class LwM2mTransportRequest { | ||
273 | contentFormat = getContentFormatByResourceModelType(resourceModelWrite, contentFormat); | 271 | contentFormat = getContentFormatByResourceModelType(resourceModelWrite, contentFormat); |
274 | request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(), | 272 | request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(), |
275 | resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModelWrite.type, | 273 | resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModelWrite.type, |
276 | - registration, rpcRequest); | 274 | + lwM2MClient, rpcRequest); |
277 | } | 275 | } |
278 | break; | 276 | break; |
279 | case WRITE_UPDATE: | 277 | case WRITE_UPDATE: |
@@ -329,7 +327,7 @@ public class LwM2mTransportRequest { | @@ -329,7 +327,7 @@ public class LwM2mTransportRequest { | ||
329 | */ | 327 | */ |
330 | 328 | ||
331 | @SuppressWarnings({"error sendRequest"}) | 329 | @SuppressWarnings({"error sendRequest"}) |
332 | - private void sendRequest(Registration registration, LwM2mClient lwM2MClient, DownlinkRequest request, | 330 | + private void sendRequest(Registration registration, LwM2mClient lwM2MClient, SimpleDownlinkRequest request, |
333 | long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) { | 331 | long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) { |
334 | context.getServer().send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { | 332 | context.getServer().send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { |
335 | 333 | ||
@@ -337,11 +335,11 @@ public class LwM2mTransportRequest { | @@ -337,11 +335,11 @@ public class LwM2mTransportRequest { | ||
337 | lwM2MClient.initReadValue(this.handler, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); | 335 | lwM2MClient.initReadValue(this.handler, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); |
338 | } | 336 | } |
339 | if (CoAP.ResponseCode.isSuccess(((Response) response.getCoapResponse()).getCode())) { | 337 | if (CoAP.ResponseCode.isSuccess(((Response) response.getCoapResponse()).getCode())) { |
340 | - this.handleResponse(registration, request.getPath().toString(), response, request, rpcRequest); | 338 | + this.handleResponse(lwM2MClient, request.getPath().toString(), response, request, rpcRequest); |
341 | } else { | 339 | } else { |
342 | String msg = String.format("%s: SendRequest %s: CoapCode - %s Lwm2m code - %d name - %s Resource path - %s", LOG_LW2M_ERROR, request.getClass().getName().toString(), | 340 | String msg = String.format("%s: SendRequest %s: CoapCode - %s Lwm2m code - %d name - %s Resource path - %s", LOG_LW2M_ERROR, request.getClass().getName().toString(), |
343 | ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString()); | 341 | ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString()); |
344 | - handler.sendLogsToThingsboard(msg, registration.getId()); | 342 | + handler.sendLogsToThingsboard(lwM2MClient, msg); |
345 | log.error("[{}] [{}], [{}] - [{}] [{}] error SendRequest", request.getClass().getName().toString(), registration.getEndpoint(), | 343 | log.error("[{}] [{}], [{}] - [{}] [{}] error SendRequest", request.getClass().getName().toString(), registration.getEndpoint(), |
346 | ((Response) response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString()); | 344 | ((Response) response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString()); |
347 | if (!lwM2MClient.isInit()) { | 345 | if (!lwM2MClient.isInit()) { |
@@ -388,7 +386,7 @@ public class LwM2mTransportRequest { | @@ -388,7 +386,7 @@ public class LwM2mTransportRequest { | ||
388 | } | 386 | } |
389 | String msg = String.format("%s: SendRequest %s: Resource path - %s msg error - %s", | 387 | String msg = String.format("%s: SendRequest %s: Resource path - %s msg error - %s", |
390 | LOG_LW2M_ERROR, request.getClass().getName().toString(), request.getPath().toString(), e.getMessage()); | 388 | LOG_LW2M_ERROR, request.getClass().getName().toString(), request.getPath().toString(), e.getMessage()); |
391 | - handler.sendLogsToThingsboard(msg, registration.getId()); | 389 | + handler.sendLogsToThingsboard(lwM2MClient, msg); |
392 | log.error("[{}] [{}] - [{}] error SendRequest", request.getClass().getName().toString(), request.getPath().toString(), e.toString()); | 390 | log.error("[{}] [{}] - [{}] error SendRequest", request.getClass().getName().toString(), request.getPath().toString(), e.toString()); |
393 | if (rpcRequest != null) { | 391 | if (rpcRequest != null) { |
394 | handler.sentRpcResponse(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR); | 392 | handler.sentRpcResponse(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR); |
@@ -398,7 +396,7 @@ public class LwM2mTransportRequest { | @@ -398,7 +396,7 @@ public class LwM2mTransportRequest { | ||
398 | 396 | ||
399 | private WriteRequest getWriteRequestSingleResource(ContentFormat contentFormat, Integer objectId, Integer instanceId, | 397 | private WriteRequest getWriteRequestSingleResource(ContentFormat contentFormat, Integer objectId, Integer instanceId, |
400 | Integer resourceId, Object value, ResourceModel.Type type, | 398 | Integer resourceId, Object value, ResourceModel.Type type, |
401 | - Registration registration, Lwm2mClientRpcRequest rpcRequest) { | 399 | + LwM2mClient client, Lwm2mClientRpcRequest rpcRequest) { |
402 | try { | 400 | try { |
403 | if (type != null) { | 401 | if (type != null) { |
404 | switch (type) { | 402 | switch (type) { |
@@ -433,7 +431,7 @@ public class LwM2mTransportRequest { | @@ -433,7 +431,7 @@ public class LwM2mTransportRequest { | ||
433 | String patn = "/" + objectId + "/" + instanceId + "/" + resourceId; | 431 | String patn = "/" + objectId + "/" + instanceId + "/" + resourceId; |
434 | String msg = String.format(LOG_LW2M_ERROR + ": NumberFormatException: Resource path - %s type - %s value - %s msg error - %s SendRequest to Client", | 432 | String msg = String.format(LOG_LW2M_ERROR + ": NumberFormatException: Resource path - %s type - %s value - %s msg error - %s SendRequest to Client", |
435 | patn, type, value, e.toString()); | 433 | patn, type, value, e.toString()); |
436 | - handler.sendLogsToThingsboard(msg, registration.getId()); | 434 | + handler.sendLogsToThingsboard(client, msg); |
437 | log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString()); | 435 | log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString()); |
438 | if (rpcRequest != null) { | 436 | if (rpcRequest != null) { |
439 | String errorMsg = String.format("NumberFormatException: Resource path - %s type - %s value - %s", patn, type, value); | 437 | String errorMsg = String.format("NumberFormatException: Resource path - %s type - %s value - %s", patn, type, value); |
@@ -443,13 +441,13 @@ public class LwM2mTransportRequest { | @@ -443,13 +441,13 @@ public class LwM2mTransportRequest { | ||
443 | } | 441 | } |
444 | } | 442 | } |
445 | 443 | ||
446 | - private void handleResponse(Registration registration, final String path, LwM2mResponse response, | ||
447 | - DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { | 444 | + private void handleResponse(LwM2mClient lwM2mClient, final String path, LwM2mResponse response, |
445 | + SimpleDownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { | ||
448 | responseRequestExecutor.submit(() -> { | 446 | responseRequestExecutor.submit(() -> { |
449 | try { | 447 | try { |
450 | - this.sendResponse(registration, path, response, request, rpcRequest); | 448 | + this.sendResponse(lwM2mClient, path, response, request, rpcRequest); |
451 | } catch (Exception e) { | 449 | } catch (Exception e) { |
452 | - log.error("[{}] endpoint [{}] path [{}] Exception Unable to after send response.", registration.getEndpoint(), path, e); | 450 | + log.error("[{}] endpoint [{}] path [{}] Exception Unable to after send response.", lwM2mClient.getRegistration().getEndpoint(), path, e); |
453 | } | 451 | } |
454 | }); | 452 | }); |
455 | } | 453 | } |
@@ -461,8 +459,9 @@ public class LwM2mTransportRequest { | @@ -461,8 +459,9 @@ public class LwM2mTransportRequest { | ||
461 | * @param path - | 459 | * @param path - |
462 | * @param response - | 460 | * @param response - |
463 | */ | 461 | */ |
464 | - private void sendResponse(Registration registration, String path, LwM2mResponse response, | ||
465 | - DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { | 462 | + private void sendResponse(LwM2mClient lwM2mClient, String path, LwM2mResponse response, |
463 | + SimpleDownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { | ||
464 | + Registration registration = lwM2mClient.getRegistration(); | ||
466 | String pathIdVer = convertPathFromObjectIdToIdVer(path, registration); | 465 | String pathIdVer = convertPathFromObjectIdToIdVer(path, registration); |
467 | String msgLog = ""; | 466 | String msgLog = ""; |
468 | if (response instanceof ReadResponse) { | 467 | if (response instanceof ReadResponse) { |
@@ -477,7 +476,7 @@ public class LwM2mTransportRequest { | @@ -477,7 +476,7 @@ public class LwM2mTransportRequest { | ||
477 | String discoverValue = Link.serialize(((DiscoverResponse) response).getObjectLinks()); | 476 | String discoverValue = Link.serialize(((DiscoverResponse) response).getObjectLinks()); |
478 | msgLog = String.format("%s: type operation: %s path: %s value: %s", | 477 | msgLog = String.format("%s: type operation: %s path: %s value: %s", |
479 | LOG_LW2M_INFO, DISCOVER.name(), request.getPath().toString(), discoverValue); | 478 | LOG_LW2M_INFO, DISCOVER.name(), request.getPath().toString(), discoverValue); |
480 | - handler.sendLogsToThingsboard(msgLog, registration.getId()); | 479 | + handler.sendLogsToThingsboard(lwM2mClient, msgLog); |
481 | log.warn("DiscoverResponse: [{}]", (DiscoverResponse) response); | 480 | log.warn("DiscoverResponse: [{}]", (DiscoverResponse) response); |
482 | if (rpcRequest != null) { | 481 | if (rpcRequest != null) { |
483 | handler.sentRpcResponse(rpcRequest, response.getCode().getName(), discoverValue, LOG_LW2M_VALUE); | 482 | handler.sentRpcResponse(rpcRequest, response.getCode().getName(), discoverValue, LOG_LW2M_VALUE); |
@@ -486,7 +485,7 @@ public class LwM2mTransportRequest { | @@ -486,7 +485,7 @@ public class LwM2mTransportRequest { | ||
486 | msgLog = String.format("%s: type operation: %s path: %s", | 485 | msgLog = String.format("%s: type operation: %s path: %s", |
487 | LOG_LW2M_INFO, EXECUTE.name(), request.getPath().toString()); | 486 | LOG_LW2M_INFO, EXECUTE.name(), request.getPath().toString()); |
488 | log.warn("9) [{}] ", msgLog); | 487 | log.warn("9) [{}] ", msgLog); |
489 | - handler.sendLogsToThingsboard(msgLog, registration.getId()); | 488 | + handler.sendLogsToThingsboard(lwM2mClient, msgLog); |
490 | if (rpcRequest != null) { | 489 | if (rpcRequest != null) { |
491 | msgLog = String.format("Start %s path: %S. Preparation finished: %s", EXECUTE.name(), path, rpcRequest.getInfoMsg()); | 490 | msgLog = String.format("Start %s path: %S. Preparation finished: %s", EXECUTE.name(), path, rpcRequest.getInfoMsg()); |
492 | rpcRequest.setInfoMsg(msgLog); | 491 | rpcRequest.setInfoMsg(msgLog); |
@@ -496,7 +495,7 @@ public class LwM2mTransportRequest { | @@ -496,7 +495,7 @@ public class LwM2mTransportRequest { | ||
496 | } else if (response instanceof WriteAttributesResponse) { | 495 | } else if (response instanceof WriteAttributesResponse) { |
497 | msgLog = String.format("%s: type operation: %s path: %s value: %s", | 496 | msgLog = String.format("%s: type operation: %s path: %s value: %s", |
498 | LOG_LW2M_INFO, WRITE_ATTRIBUTES.name(), request.getPath().toString(), ((WriteAttributesRequest) request).getAttributes().toString()); | 497 | LOG_LW2M_INFO, WRITE_ATTRIBUTES.name(), request.getPath().toString(), ((WriteAttributesRequest) request).getAttributes().toString()); |
499 | - handler.sendLogsToThingsboard(msgLog, registration.getId()); | 498 | + handler.sendLogsToThingsboard(lwM2mClient, msgLog); |
500 | log.warn("12) [{}] Path [{}] WriteAttributesResponse", pathIdVer, response); | 499 | log.warn("12) [{}] Path [{}] WriteAttributesResponse", pathIdVer, response); |
501 | if (rpcRequest != null) { | 500 | if (rpcRequest != null) { |
502 | handler.sentRpcResponse(rpcRequest, response.getCode().getName(), response.toString(), LOG_LW2M_VALUE); | 501 | handler.sentRpcResponse(rpcRequest, response.getCode().getName(), response.toString(), LOG_LW2M_VALUE); |
@@ -504,13 +503,14 @@ public class LwM2mTransportRequest { | @@ -504,13 +503,14 @@ public class LwM2mTransportRequest { | ||
504 | } else if (response instanceof WriteResponse) { | 503 | } else if (response instanceof WriteResponse) { |
505 | msgLog = String.format("Type operation: Write path: %s", pathIdVer); | 504 | msgLog = String.format("Type operation: Write path: %s", pathIdVer); |
506 | log.warn("10) [{}] response: [{}]", msgLog, response); | 505 | log.warn("10) [{}] response: [{}]", msgLog, response); |
507 | - this.infoWriteResponse(registration, response, request, rpcRequest); | 506 | + this.infoWriteResponse(lwM2mClient, response, request, rpcRequest); |
508 | handler.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request); | 507 | handler.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request); |
509 | } | 508 | } |
510 | } | 509 | } |
511 | 510 | ||
512 | - private void infoWriteResponse(Registration registration, LwM2mResponse response, DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { | 511 | + private void infoWriteResponse(LwM2mClient lwM2mClient, LwM2mResponse response, SimpleDownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { |
513 | try { | 512 | try { |
513 | + Registration registration = lwM2mClient.getRegistration(); | ||
514 | LwM2mNode node = ((WriteRequest) request).getNode(); | 514 | LwM2mNode node = ((WriteRequest) request).getNode(); |
515 | String msg = null; | 515 | String msg = null; |
516 | Object value; | 516 | Object value; |
@@ -545,7 +545,7 @@ public class LwM2mTransportRequest { | @@ -545,7 +545,7 @@ public class LwM2mTransportRequest { | ||
545 | } | 545 | } |
546 | } | 546 | } |
547 | if (msg != null) { | 547 | if (msg != null) { |
548 | - handler.sendLogsToThingsboard(msg, registration.getId()); | 548 | + handler.sendLogsToThingsboard(lwM2mClient, msg); |
549 | if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { | 549 | if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { |
550 | this.afterWriteSuccessFwSwUpdate(registration, request); | 550 | this.afterWriteSuccessFwSwUpdate(registration, request); |
551 | if (rpcRequest != null) { | 551 | if (rpcRequest != null) { |
@@ -566,7 +566,7 @@ public class LwM2mTransportRequest { | @@ -566,7 +566,7 @@ public class LwM2mTransportRequest { | ||
566 | * fw_state/sw_state = DOWNLOADED | 566 | * fw_state/sw_state = DOWNLOADED |
567 | * send operation Execute | 567 | * send operation Execute |
568 | */ | 568 | */ |
569 | - private void afterWriteSuccessFwSwUpdate(Registration registration, DownlinkRequest request) { | 569 | + private void afterWriteSuccessFwSwUpdate(Registration registration, SimpleDownlinkRequest request) { |
570 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); | 570 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); |
571 | if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) { | 571 | if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) { |
572 | lwM2MClient.getFwUpdate().setStateUpdate(DOWNLOADED.name()); | 572 | lwM2MClient.getFwUpdate().setStateUpdate(DOWNLOADED.name()); |
@@ -581,7 +581,7 @@ public class LwM2mTransportRequest { | @@ -581,7 +581,7 @@ public class LwM2mTransportRequest { | ||
581 | /** | 581 | /** |
582 | * After finish operation FwSwUpdate Write (error): fw_state = FAILED | 582 | * After finish operation FwSwUpdate Write (error): fw_state = FAILED |
583 | */ | 583 | */ |
584 | - private void afterWriteFwSWUpdateError(Registration registration, DownlinkRequest request, String msgError) { | 584 | + private void afterWriteFwSWUpdateError(Registration registration, SimpleDownlinkRequest request, String msgError) { |
585 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); | 585 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); |
586 | if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) { | 586 | if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) { |
587 | lwM2MClient.getFwUpdate().setStateUpdate(FAILED.name()); | 587 | lwM2MClient.getFwUpdate().setStateUpdate(FAILED.name()); |
@@ -593,7 +593,7 @@ public class LwM2mTransportRequest { | @@ -593,7 +593,7 @@ public class LwM2mTransportRequest { | ||
593 | } | 593 | } |
594 | } | 594 | } |
595 | 595 | ||
596 | - private void afterExecuteFwSwUpdateError(Registration registration, DownlinkRequest request, String msgError) { | 596 | + private void afterExecuteFwSwUpdateError(Registration registration, SimpleDownlinkRequest request, String msgError) { |
597 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); | 597 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); |
598 | if (request.getPath().toString().equals(FW_UPDATE_ID) && lwM2MClient.getFwUpdate() != null) { | 598 | if (request.getPath().toString().equals(FW_UPDATE_ID) && lwM2MClient.getFwUpdate() != null) { |
599 | lwM2MClient.getFwUpdate().sendLogs(this.handler, EXECUTE.name(), LOG_LW2M_ERROR, msgError); | 599 | lwM2MClient.getFwUpdate().sendLogs(this.handler, EXECUTE.name(), LOG_LW2M_ERROR, msgError); |
@@ -603,8 +603,8 @@ public class LwM2mTransportRequest { | @@ -603,8 +603,8 @@ public class LwM2mTransportRequest { | ||
603 | } | 603 | } |
604 | } | 604 | } |
605 | 605 | ||
606 | - private void afterObserveCancel(Registration registration, int observeCancelCnt, String observeCancelMsg, Lwm2mClientRpcRequest rpcRequest) { | ||
607 | - handler.sendLogsToThingsboard(observeCancelMsg, registration.getId()); | 606 | + private void afterObserveCancel(LwM2mClient lwM2mClient, int observeCancelCnt, String observeCancelMsg, Lwm2mClientRpcRequest rpcRequest) { |
607 | + handler.sendLogsToThingsboard(lwM2mClient, observeCancelMsg); | ||
608 | log.warn("[{}]", observeCancelMsg); | 608 | log.warn("[{}]", observeCancelMsg); |
609 | if (rpcRequest != null) { | 609 | if (rpcRequest != null) { |
610 | rpcRequest.setInfoMsg(String.format("Count: %d", observeCancelCnt)); | 610 | rpcRequest.setInfoMsg(String.format("Count: %d", observeCancelCnt)); |
@@ -137,7 +137,7 @@ public class LwM2mTransportServerHelper { | @@ -137,7 +137,7 @@ public class LwM2mTransportServerHelper { | ||
137 | public ObjectModel parseFromXmlToObjectModel(byte[] xmlByte, String streamName, DefaultDDFFileValidator ddfValidator) { | 137 | public ObjectModel parseFromXmlToObjectModel(byte[] xmlByte, String streamName, DefaultDDFFileValidator ddfValidator) { |
138 | try { | 138 | try { |
139 | DDFFileParser ddfFileParser = new DDFFileParser(ddfValidator); | 139 | DDFFileParser ddfFileParser = new DDFFileParser(ddfValidator); |
140 | - return ddfFileParser.parseEx(new ByteArrayInputStream(xmlByte), streamName).get(0); | 140 | + return ddfFileParser.parse(new ByteArrayInputStream(xmlByte), streamName).get(0); |
141 | } catch (IOException | InvalidDDFFileException e) { | 141 | } catch (IOException | InvalidDDFFileException e) { |
142 | log.error("Could not parse the XML file [{}]", streamName, e); | 142 | log.error("Could not parse the XML file [{}]", streamName, e); |
143 | return null; | 143 | return null; |
@@ -36,7 +36,7 @@ import org.eclipse.leshan.core.node.LwM2mObjectInstance; | @@ -36,7 +36,7 @@ import org.eclipse.leshan.core.node.LwM2mObjectInstance; | ||
36 | import org.eclipse.leshan.core.node.LwM2mPath; | 36 | import org.eclipse.leshan.core.node.LwM2mPath; |
37 | import org.eclipse.leshan.core.node.LwM2mSingleResource; | 37 | import org.eclipse.leshan.core.node.LwM2mSingleResource; |
38 | import org.eclipse.leshan.core.node.codec.CodecException; | 38 | import org.eclipse.leshan.core.node.codec.CodecException; |
39 | -import org.eclipse.leshan.core.request.DownlinkRequest; | 39 | +import org.eclipse.leshan.core.request.SimpleDownlinkRequest; |
40 | import org.eclipse.leshan.core.request.WriteAttributesRequest; | 40 | import org.eclipse.leshan.core.request.WriteAttributesRequest; |
41 | import org.eclipse.leshan.core.util.Hex; | 41 | import org.eclipse.leshan.core.util.Hex; |
42 | import org.eclipse.leshan.server.registration.Registration; | 42 | import org.eclipse.leshan.server.registration.Registration; |
@@ -839,7 +839,7 @@ public class LwM2mTransportUtil { | @@ -839,7 +839,7 @@ public class LwM2mTransportUtil { | ||
839 | * Attribute pmax = new Attribute(MAXIMUM_PERIOD, "60"); | 839 | * Attribute pmax = new Attribute(MAXIMUM_PERIOD, "60"); |
840 | * Attribute [] attrs = {gt, st}; | 840 | * Attribute [] attrs = {gt, st}; |
841 | */ | 841 | */ |
842 | - public static DownlinkRequest createWriteAttributeRequest(String target, Object params, DefaultLwM2MTransportMsgHandler serviceImpl) { | 842 | + public static SimpleDownlinkRequest createWriteAttributeRequest(String target, Object params, DefaultLwM2MTransportMsgHandler serviceImpl) { |
843 | AttributeSet attrSet = new AttributeSet(createWriteAttributes(params, serviceImpl, target)); | 843 | AttributeSet attrSet = new AttributeSet(createWriteAttributes(params, serviceImpl, target)); |
844 | return attrSet.getAttributes().size() > 0 ? new WriteAttributesRequest(target, attrSet) : null; | 844 | return attrSet.getAttributes().size() > 0 ? new WriteAttributesRequest(target, attrSet) : null; |
845 | } | 845 | } |
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 | +public enum LwM2MClientState { | ||
19 | + | ||
20 | + CREATED, REGISTERED, UNREGISTERED | ||
21 | + | ||
22 | +} |
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.Getter; | ||
19 | + | ||
20 | +public class LwM2MClientStateException extends Exception { | ||
21 | + | ||
22 | + private static final long serialVersionUID = 3307690997951364046L; | ||
23 | + | ||
24 | + @Getter | ||
25 | + private final LwM2MClientState state; | ||
26 | + | ||
27 | + public LwM2MClientStateException(LwM2MClientState state, String message) { | ||
28 | + super(message); | ||
29 | + this.state = state; | ||
30 | + } | ||
31 | +} |
@@ -26,6 +26,7 @@ import org.eclipse.leshan.core.node.LwM2mObjectInstance; | @@ -26,6 +26,7 @@ import org.eclipse.leshan.core.node.LwM2mObjectInstance; | ||
26 | import org.eclipse.leshan.core.node.LwM2mPath; | 26 | import org.eclipse.leshan.core.node.LwM2mPath; |
27 | import org.eclipse.leshan.core.node.LwM2mResource; | 27 | import org.eclipse.leshan.core.node.LwM2mResource; |
28 | import org.eclipse.leshan.core.node.LwM2mSingleResource; | 28 | import org.eclipse.leshan.core.node.LwM2mSingleResource; |
29 | +import org.eclipse.leshan.core.request.ContentFormat; | ||
29 | import org.eclipse.leshan.server.model.LwM2mModelProvider; | 30 | import org.eclipse.leshan.server.model.LwM2mModelProvider; |
30 | import org.eclipse.leshan.server.registration.Registration; | 31 | import org.eclipse.leshan.server.registration.Registration; |
31 | import org.eclipse.leshan.server.security.SecurityInfo; | 32 | import org.eclipse.leshan.server.security.SecurityInfo; |
@@ -49,6 +50,8 @@ import java.util.UUID; | @@ -49,6 +50,8 @@ import java.util.UUID; | ||
49 | import java.util.concurrent.ConcurrentHashMap; | 50 | import java.util.concurrent.ConcurrentHashMap; |
50 | import java.util.concurrent.ConcurrentLinkedQueue; | 51 | import java.util.concurrent.ConcurrentLinkedQueue; |
51 | import java.util.concurrent.CopyOnWriteArrayList; | 52 | import java.util.concurrent.CopyOnWriteArrayList; |
53 | +import java.util.concurrent.locks.Lock; | ||
54 | +import java.util.concurrent.locks.ReentrantLock; | ||
52 | import java.util.stream.Collectors; | 55 | import java.util.stream.Collectors; |
53 | 56 | ||
54 | import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE; | 57 | import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE; |
@@ -62,12 +65,28 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.g | @@ -62,12 +65,28 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.g | ||
62 | 65 | ||
63 | @Slf4j | 66 | @Slf4j |
64 | public class LwM2mClient implements Cloneable { | 67 | public class LwM2mClient implements Cloneable { |
68 | + | ||
69 | + private final String nodeId; | ||
70 | + @Getter | ||
71 | + private final String endpoint; | ||
72 | + private final Lock lock; | ||
73 | + @Getter | ||
74 | + @Setter | ||
75 | + private LwM2MClientState state; | ||
76 | + @Getter | ||
77 | + private final Map<String, ResourceValue> resources; | ||
78 | + @Getter | ||
79 | + private final Map<String, TsKvProto> delayedRequests; | ||
80 | + @Getter | ||
81 | + private final List<String> pendingReadRequests; | ||
82 | + @Getter | ||
83 | + private final Queue<LwM2mQueuedRequest> queuedRequests; | ||
84 | + | ||
65 | @Getter | 85 | @Getter |
66 | private String deviceName; | 86 | private String deviceName; |
67 | @Getter | 87 | @Getter |
68 | private String deviceProfileName; | 88 | private String deviceProfileName; |
69 | - @Getter | ||
70 | - private String endpoint; | 89 | + |
71 | @Getter | 90 | @Getter |
72 | private String identity; | 91 | private String identity; |
73 | @Getter | 92 | @Getter |
@@ -93,33 +112,29 @@ public class LwM2mClient implements Cloneable { | @@ -93,33 +112,29 @@ public class LwM2mClient implements Cloneable { | ||
93 | private ValidateDeviceCredentialsResponse credentials; | 112 | private ValidateDeviceCredentialsResponse credentials; |
94 | 113 | ||
95 | @Getter | 114 | @Getter |
96 | - private final Map<String, ResourceValue> resources; | ||
97 | - @Getter | ||
98 | - private final Map<String, TsKvProto> delayedRequests; | ||
99 | - @Getter | ||
100 | - @Setter | ||
101 | - private final List<String> pendingReadRequests; | ||
102 | - @Getter | ||
103 | - private final Queue<LwM2mQueuedRequest> queuedRequests; | ||
104 | - @Getter | ||
105 | private boolean init; | 115 | private boolean init; |
106 | 116 | ||
107 | public Object clone() throws CloneNotSupportedException { | 117 | public Object clone() throws CloneNotSupportedException { |
108 | return super.clone(); | 118 | return super.clone(); |
109 | } | 119 | } |
110 | 120 | ||
111 | - public LwM2mClient(String nodeId, String endpoint, String identity, SecurityInfo securityInfo, ValidateDeviceCredentialsResponse credentials, UUID profileId, UUID sessionId) { | 121 | + public LwM2mClient(String nodeId, String endpoint) { |
122 | + this.nodeId = nodeId; | ||
112 | this.endpoint = endpoint; | 123 | this.endpoint = endpoint; |
113 | - this.identity = identity; | ||
114 | - this.securityInfo = securityInfo; | ||
115 | - this.credentials = credentials; | 124 | + this.lock = new ReentrantLock(); |
116 | this.delayedRequests = new ConcurrentHashMap<>(); | 125 | this.delayedRequests = new ConcurrentHashMap<>(); |
117 | this.pendingReadRequests = new CopyOnWriteArrayList<>(); | 126 | this.pendingReadRequests = new CopyOnWriteArrayList<>(); |
118 | this.resources = new ConcurrentHashMap<>(); | 127 | this.resources = new ConcurrentHashMap<>(); |
119 | - this.profileId = profileId; | ||
120 | - this.init = false; | ||
121 | this.queuedRequests = new ConcurrentLinkedQueue<>(); | 128 | this.queuedRequests = new ConcurrentLinkedQueue<>(); |
129 | + this.state = LwM2MClientState.CREATED; | ||
130 | + } | ||
122 | 131 | ||
132 | + public void init(String identity, SecurityInfo securityInfo, ValidateDeviceCredentialsResponse credentials, UUID profileId, UUID sessionId) { | ||
133 | + this.identity = identity; | ||
134 | + this.securityInfo = securityInfo; | ||
135 | + this.credentials = credentials; | ||
136 | + this.profileId = profileId; | ||
137 | + this.init = false; | ||
123 | this.fwUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.FIRMWARE); | 138 | this.fwUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.FIRMWARE); |
124 | this.swUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.SOFTWARE); | 139 | this.swUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.SOFTWARE); |
125 | if (this.credentials != null && this.credentials.hasDeviceInfo()) { | 140 | if (this.credentials != null && this.credentials.hasDeviceInfo()) { |
@@ -131,6 +146,14 @@ public class LwM2mClient implements Cloneable { | @@ -131,6 +146,14 @@ public class LwM2mClient implements Cloneable { | ||
131 | } | 146 | } |
132 | } | 147 | } |
133 | 148 | ||
149 | + public void lock() { | ||
150 | + lock.lock(); | ||
151 | + } | ||
152 | + | ||
153 | + public void unlock() { | ||
154 | + lock.unlock(); | ||
155 | + } | ||
156 | + | ||
134 | public void onDeviceUpdate(Device device, Optional<DeviceProfile> deviceProfileOpt) { | 157 | public void onDeviceUpdate(Device device, Optional<DeviceProfile> deviceProfileOpt) { |
135 | SessionInfoProto.Builder builder = SessionInfoProto.newBuilder().mergeFrom(session); | 158 | SessionInfoProto.Builder builder = SessionInfoProto.newBuilder().mergeFrom(session); |
136 | this.deviceId = device.getUuidId(); | 159 | this.deviceId = device.getUuidId(); |
@@ -193,9 +216,7 @@ public class LwM2mClient implements Cloneable { | @@ -193,9 +216,7 @@ public class LwM2mClient implements Cloneable { | ||
193 | public Object getResourceValue(String pathRezIdVer, String pathRezId) { | 216 | public Object getResourceValue(String pathRezIdVer, String pathRezId) { |
194 | String pathRez = pathRezIdVer == null ? convertPathFromObjectIdToIdVer(pathRezId, this.registration) : pathRezIdVer; | 217 | String pathRez = pathRezIdVer == null ? convertPathFromObjectIdToIdVer(pathRezId, this.registration) : pathRezIdVer; |
195 | if (this.resources.get(pathRez) != null) { | 218 | if (this.resources.get(pathRez) != null) { |
196 | - return this.resources.get(pathRez).getLwM2mResource().isMultiInstances() ? | ||
197 | - this.resources.get(pathRez).getLwM2mResource().getValues() : | ||
198 | - this.resources.get(pathRez).getLwM2mResource().getValue(); | 219 | + return this.resources.get(pathRez).getLwM2mResource().getValue(); |
199 | } | 220 | } |
200 | return null; | 221 | return null; |
201 | } | 222 | } |
@@ -366,5 +387,14 @@ public class LwM2mClient implements Cloneable { | @@ -366,5 +387,14 @@ public class LwM2mClient implements Cloneable { | ||
366 | } | 387 | } |
367 | } | 388 | } |
368 | 389 | ||
390 | + public ContentFormat getDefaultContentFormat() { | ||
391 | + if (registration == null) { | ||
392 | + return ContentFormat.DEFAULT; | ||
393 | + } else if (registration.getLwM2mVersion().equals("1.0")) { | ||
394 | + return ContentFormat.TLV; | ||
395 | + } else { | ||
396 | + return ContentFormat.TEXT; | ||
397 | + } | ||
398 | + } | ||
369 | } | 399 | } |
370 | 400 |
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | package org.thingsboard.server.transport.lwm2m.server.client; | 16 | package org.thingsboard.server.transport.lwm2m.server.client; |
17 | 17 | ||
18 | import org.eclipse.leshan.server.registration.Registration; | 18 | import org.eclipse.leshan.server.registration.Registration; |
19 | +import org.eclipse.leshan.server.security.SecurityInfo; | ||
19 | import org.thingsboard.server.common.data.DeviceProfile; | 20 | import org.thingsboard.server.common.data.DeviceProfile; |
20 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | 21 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
21 | import org.thingsboard.server.gen.transport.TransportProtos; | 22 | import org.thingsboard.server.gen.transport.TransportProtos; |
@@ -27,21 +28,17 @@ import java.util.UUID; | @@ -27,21 +28,17 @@ import java.util.UUID; | ||
27 | 28 | ||
28 | public interface LwM2mClientContext { | 29 | public interface LwM2mClientContext { |
29 | 30 | ||
30 | - void removeClientByRegistrationId(String registrationId); | ||
31 | - | ||
32 | - LwM2mClient getClientByEndpoint(String endpoint); | ||
33 | - | ||
34 | LwM2mClient getClientByRegistrationId(String registrationId); | 31 | LwM2mClient getClientByRegistrationId(String registrationId); |
35 | 32 | ||
36 | - LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo); | 33 | + LwM2mClient getClientByEndpoint(String endpoint); |
37 | 34 | ||
38 | - LwM2mClient getOrRegister(Registration registration); | 35 | + LwM2mClient getClientBySessionInfo(TransportProtos.SessionInfoProto sessionInfo); |
39 | 36 | ||
40 | - LwM2mClient registerOrUpdate(Registration registration); | 37 | + void register(LwM2mClient lwM2MClient, Registration registration) throws LwM2MClientStateException; |
41 | 38 | ||
42 | - LwM2mClient fetchClientByEndpoint(String endpoint); | 39 | + void updateRegistration(LwM2mClient client, Registration registration) throws LwM2MClientStateException; |
43 | 40 | ||
44 | - Registration getRegistration(String registrationId); | 41 | + void unregister(LwM2mClient client, Registration registration) throws LwM2MClientStateException; |
45 | 42 | ||
46 | Collection<LwM2mClient> getLwM2mClients(); | 43 | Collection<LwM2mClient> getLwM2mClients(); |
47 | 44 | ||
@@ -55,9 +52,11 @@ public interface LwM2mClientContext { | @@ -55,9 +52,11 @@ public interface LwM2mClientContext { | ||
55 | 52 | ||
56 | LwM2mClientProfile profileUpdate(DeviceProfile deviceProfile); | 53 | LwM2mClientProfile profileUpdate(DeviceProfile deviceProfile); |
57 | 54 | ||
58 | - Set<String> getSupportedIdVerInClient(Registration registration); | 55 | + Set<String> getSupportedIdVerInClient(LwM2mClient registration); |
59 | 56 | ||
60 | LwM2mClient getClientByDeviceId(UUID deviceId); | 57 | LwM2mClient getClientByDeviceId(UUID deviceId); |
61 | 58 | ||
62 | void registerClient(Registration registration, ValidateDeviceCredentialsResponse credentials); | 59 | void registerClient(Registration registration, ValidateDeviceCredentialsResponse credentials); |
60 | + | ||
61 | + | ||
63 | } | 62 | } |
@@ -19,16 +19,15 @@ import lombok.RequiredArgsConstructor; | @@ -19,16 +19,15 @@ import lombok.RequiredArgsConstructor; | ||
19 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
20 | import org.eclipse.leshan.core.node.LwM2mPath; | 20 | import org.eclipse.leshan.core.node.LwM2mPath; |
21 | import org.eclipse.leshan.server.registration.Registration; | 21 | import org.eclipse.leshan.server.registration.Registration; |
22 | -import org.eclipse.leshan.server.security.EditableSecurityStore; | ||
23 | import org.springframework.stereotype.Service; | 22 | import org.springframework.stereotype.Service; |
24 | import org.thingsboard.server.common.data.DeviceProfile; | 23 | import org.thingsboard.server.common.data.DeviceProfile; |
25 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | 24 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
26 | import org.thingsboard.server.gen.transport.TransportProtos; | 25 | import org.thingsboard.server.gen.transport.TransportProtos; |
27 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | 26 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
28 | -import org.thingsboard.server.transport.lwm2m.secure.EndpointSecurityInfo; | ||
29 | -import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; | 27 | +import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; |
30 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; | 28 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; |
31 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; | 29 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; |
30 | +import org.thingsboard.server.transport.lwm2m.server.store.TbEditableSecurityStore; | ||
32 | 31 | ||
33 | import java.util.Arrays; | 32 | import java.util.Arrays; |
34 | import java.util.Collection; | 33 | import java.util.Collection; |
@@ -48,46 +47,107 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.c | @@ -48,46 +47,107 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.c | ||
48 | public class LwM2mClientContextImpl implements LwM2mClientContext { | 47 | public class LwM2mClientContextImpl implements LwM2mClientContext { |
49 | 48 | ||
50 | private final LwM2mTransportContext context; | 49 | private final LwM2mTransportContext context; |
50 | + private final TbEditableSecurityStore securityStore; | ||
51 | private final Map<String, LwM2mClient> lwM2mClientsByEndpoint = new ConcurrentHashMap<>(); | 51 | private final Map<String, LwM2mClient> lwM2mClientsByEndpoint = new ConcurrentHashMap<>(); |
52 | private final Map<String, LwM2mClient> lwM2mClientsByRegistrationId = new ConcurrentHashMap<>(); | 52 | private final Map<String, LwM2mClient> lwM2mClientsByRegistrationId = new ConcurrentHashMap<>(); |
53 | private Map<UUID, LwM2mClientProfile> profiles = new ConcurrentHashMap<>(); | 53 | private Map<UUID, LwM2mClientProfile> profiles = new ConcurrentHashMap<>(); |
54 | 54 | ||
55 | - private final LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator; | ||
56 | - | ||
57 | - private final EditableSecurityStore securityStore; | ||
58 | - | ||
59 | @Override | 55 | @Override |
60 | public LwM2mClient getClientByEndpoint(String endpoint) { | 56 | public LwM2mClient getClientByEndpoint(String endpoint) { |
61 | - return lwM2mClientsByEndpoint.get(endpoint); | 57 | + return lwM2mClientsByEndpoint.computeIfAbsent(endpoint, ep -> new LwM2mClient(context.getNodeId(), ep)); |
62 | } | 58 | } |
63 | 59 | ||
64 | @Override | 60 | @Override |
65 | - public LwM2mClient getClientByRegistrationId(String registrationId) { | ||
66 | - return lwM2mClientsByRegistrationId.get(registrationId); | 61 | + public void register(LwM2mClient lwM2MClient, Registration registration) throws LwM2MClientStateException { |
62 | + lwM2MClient.lock(); | ||
63 | + try { | ||
64 | + if (LwM2MClientState.UNREGISTERED.equals(lwM2MClient.getState())) { | ||
65 | + throw new LwM2MClientStateException(lwM2MClient.getState(), "Client is in invalid state."); | ||
66 | + } | ||
67 | + TbLwM2MSecurityInfo securityInfo = securityStore.getTbLwM2MSecurityInfoByEndpoint(lwM2MClient.getEndpoint()); | ||
68 | + if (securityInfo.getSecurityMode() != null) { | ||
69 | + if (securityInfo.getDeviceProfile() != null) { | ||
70 | + UUID profileUuid = profileUpdate(securityInfo.getDeviceProfile()) != null ? securityInfo.getDeviceProfile().getUuidId() : null; | ||
71 | + if (securityInfo.getSecurityInfo() != null) { | ||
72 | + lwM2MClient.init(securityInfo.getSecurityInfo().getIdentity(), securityInfo.getSecurityInfo(), securityInfo.getMsg(), profileUuid, UUID.randomUUID()); | ||
73 | + } else if (NO_SEC.equals(securityInfo.getSecurityMode())) { | ||
74 | + lwM2MClient.init(null, null, securityInfo.getMsg(), profileUuid, UUID.randomUUID()); | ||
75 | + } else { | ||
76 | + throw new RuntimeException(String.format("Registration failed: device %s not found.", lwM2MClient.getEndpoint())); | ||
77 | + } | ||
78 | + } else { | ||
79 | + throw new RuntimeException(String.format("Registration failed: device %s not found.", lwM2MClient.getEndpoint())); | ||
80 | + } | ||
81 | + } else { | ||
82 | + throw new RuntimeException(String.format("Registration failed: FORBIDDEN, endpointId: %s", lwM2MClient.getEndpoint())); | ||
83 | + } | ||
84 | + lwM2MClient.setRegistration(registration); | ||
85 | + this.lwM2mClientsByRegistrationId.put(registration.getId(), lwM2MClient); | ||
86 | + lwM2MClient.setState(LwM2MClientState.REGISTERED); | ||
87 | + } finally { | ||
88 | + lwM2MClient.unlock(); | ||
89 | + } | ||
67 | } | 90 | } |
68 | 91 | ||
69 | @Override | 92 | @Override |
70 | - public LwM2mClient getOrRegister(Registration registration) { | ||
71 | - if (registration == null) { | ||
72 | - return null; | 93 | + public void updateRegistration(LwM2mClient lwM2MClient, Registration registration) throws LwM2MClientStateException { |
94 | + lwM2MClient.lock(); | ||
95 | + try { | ||
96 | + if (!LwM2MClientState.REGISTERED.equals(lwM2MClient.getState())) { | ||
97 | + throw new LwM2MClientStateException(lwM2MClient.getState(), "Client is in invalid state."); | ||
98 | + } | ||
99 | + Registration currentRegistration = lwM2MClient.getRegistration(); | ||
100 | + if (currentRegistration.getId().equals(registration.getId())) { | ||
101 | + lwM2MClient.setRegistration(registration); | ||
102 | + } else { | ||
103 | + throw new LwM2MClientStateException(lwM2MClient.getState(), "Client has different registration."); | ||
104 | + } | ||
105 | + } finally { | ||
106 | + lwM2MClient.unlock(); | ||
73 | } | 107 | } |
74 | - LwM2mClient client = lwM2mClientsByRegistrationId.get(registration.getId()); | ||
75 | - if (client == null) { | ||
76 | - client = lwM2mClientsByEndpoint.get(registration.getEndpoint()); | ||
77 | - if (client == null) { | ||
78 | - client = registerOrUpdate(registration); | 108 | + } |
109 | + | ||
110 | + @Override | ||
111 | + public void unregister(LwM2mClient lwM2MClient, Registration registration) throws LwM2MClientStateException { | ||
112 | + lwM2MClient.lock(); | ||
113 | + try { | ||
114 | + if (!LwM2MClientState.REGISTERED.equals(lwM2MClient.getState())) { | ||
115 | + throw new LwM2MClientStateException(lwM2MClient.getState(), "Client is in invalid state."); | ||
79 | } | 116 | } |
117 | + lwM2mClientsByRegistrationId.remove(registration.getId()); | ||
118 | + Registration currentRegistration = lwM2MClient.getRegistration(); | ||
119 | + if (currentRegistration.getId().equals(registration.getId())) { | ||
120 | + lwM2MClient.setState(LwM2MClientState.UNREGISTERED); | ||
121 | + lwM2mClientsByEndpoint.remove(lwM2MClient.getEndpoint()); | ||
122 | + this.securityStore.remove(lwM2MClient.getEndpoint()); | ||
123 | + this.lwM2mClientsByRegistrationId.remove(registration.getId()); | ||
124 | + UUID profileId = lwM2MClient.getProfileId(); | ||
125 | + if (profileId != null) { | ||
126 | + Optional<LwM2mClient> otherClients = lwM2mClientsByRegistrationId.values().stream().filter(e -> e.getProfileId().equals(profileId)).findFirst(); | ||
127 | + if (otherClients.isEmpty()) { | ||
128 | + profiles.remove(profileId); | ||
129 | + } | ||
130 | + } | ||
131 | + } else { | ||
132 | + throw new LwM2MClientStateException(lwM2MClient.getState(), "Client has different registration."); | ||
133 | + } | ||
134 | + } finally { | ||
135 | + lwM2MClient.unlock(); | ||
80 | } | 136 | } |
81 | - return client; | ||
82 | } | 137 | } |
83 | 138 | ||
84 | @Override | 139 | @Override |
85 | - public LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo) { | ||
86 | - LwM2mClient lwM2mClient = lwM2mClientsByEndpoint.values().stream().filter(c -> | 140 | + public LwM2mClient getClientByRegistrationId(String registrationId) { |
141 | + return lwM2mClientsByRegistrationId.get(registrationId); | ||
142 | + } | ||
143 | + | ||
144 | + @Override | ||
145 | + public LwM2mClient getClientBySessionInfo(TransportProtos.SessionInfoProto sessionInfo) { | ||
146 | + LwM2mClient lwM2mClient = lwM2mClientsByEndpoint.values().stream().filter(c -> | ||
87 | (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) | 147 | (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) |
88 | .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))) | 148 | .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))) |
89 | 149 | ||
90 | - ).findAny().get(); | 150 | + ).findAny().orElse(null); |
91 | if (lwM2mClient == null) { | 151 | if (lwM2mClient == null) { |
92 | log.warn("Device TimeOut? lwM2mClient is null."); | 152 | log.warn("Device TimeOut? lwM2mClient is null."); |
93 | log.warn("SessionInfo input [{}], lwM2mClientsByEndpoint size: [{}]", sessionInfo, lwM2mClientsByEndpoint.values().size()); | 153 | log.warn("SessionInfo input [{}], lwM2mClientsByEndpoint size: [{}]", sessionInfo, lwM2mClientsByEndpoint.values().size()); |
@@ -96,60 +156,14 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | @@ -96,60 +156,14 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | ||
96 | return lwM2mClient; | 156 | return lwM2mClient; |
97 | } | 157 | } |
98 | 158 | ||
99 | - @Override | ||
100 | - public LwM2mClient registerOrUpdate(Registration registration) { | ||
101 | - LwM2mClient lwM2MClient = lwM2mClientsByEndpoint.get(registration.getEndpoint()); | ||
102 | - if (lwM2MClient == null) { | ||
103 | - lwM2MClient = this.fetchClientByEndpoint(registration.getEndpoint()); | ||
104 | - } | ||
105 | - lwM2MClient.setRegistration(registration); | ||
106 | -// TODO: this remove is probably redundant. We should remove it. | ||
107 | -// this.lwM2mClientsByEndpoint.remove(registration.getEndpoint()); | ||
108 | - this.lwM2mClientsByRegistrationId.put(registration.getId(), lwM2MClient); | ||
109 | - return lwM2MClient; | ||
110 | - } | ||
111 | - | ||
112 | public Registration getRegistration(String registrationId) { | 159 | public Registration getRegistration(String registrationId) { |
113 | return this.lwM2mClientsByRegistrationId.get(registrationId).getRegistration(); | 160 | return this.lwM2mClientsByRegistrationId.get(registrationId).getRegistration(); |
114 | } | 161 | } |
115 | 162 | ||
116 | @Override | 163 | @Override |
117 | - public LwM2mClient fetchClientByEndpoint(String endpoint) { | ||
118 | - EndpointSecurityInfo securityInfo = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(endpoint, LwM2mTransportUtil.LwM2mTypeServer.CLIENT); | ||
119 | - if (securityInfo.getSecurityMode() != null) { | ||
120 | - if (securityInfo.getDeviceProfile() != null) { | ||
121 | - UUID profileUuid = profileUpdate(securityInfo.getDeviceProfile())!= null ? | ||
122 | - securityInfo.getDeviceProfile().getUuidId() : null; | ||
123 | - // TODO: for tests bug. | ||
124 | - if (profileUuid== null) { | ||
125 | - log.trace("input parameters toClientProfile if the result is null: [{}]", securityInfo.getDeviceProfile()); | ||
126 | - } | ||
127 | - LwM2mClient client; | ||
128 | - if (securityInfo.getSecurityInfo() != null) { | ||
129 | - client = new LwM2mClient(context.getNodeId(), securityInfo.getSecurityInfo().getEndpoint(), | ||
130 | - securityInfo.getSecurityInfo().getIdentity(), securityInfo.getSecurityInfo(), | ||
131 | - securityInfo.getMsg(), profileUuid, UUID.randomUUID()); | ||
132 | - } else if (NO_SEC.equals(securityInfo.getSecurityMode())) { | ||
133 | - client = new LwM2mClient(context.getNodeId(), endpoint, | ||
134 | - null, null, | ||
135 | - securityInfo.getMsg(), profileUuid, UUID.randomUUID()); | ||
136 | - } else { | ||
137 | - throw new RuntimeException(String.format("Registration failed: device %s not found.", endpoint)); | ||
138 | - } | ||
139 | - lwM2mClientsByEndpoint.put(client.getEndpoint(), client); | ||
140 | - return client; | ||
141 | - } else { | ||
142 | - throw new RuntimeException(String.format("Registration failed: device %s not found.", endpoint)); | ||
143 | - } | ||
144 | - } else { | ||
145 | - throw new RuntimeException(String.format("Registration failed: FORBIDDEN, endpointId: %s", endpoint)); | ||
146 | - } | ||
147 | - } | ||
148 | - | ||
149 | - @Override | ||
150 | public void registerClient(Registration registration, ValidateDeviceCredentialsResponse credentials) { | 164 | public void registerClient(Registration registration, ValidateDeviceCredentialsResponse credentials) { |
151 | - LwM2mClient client = new LwM2mClient(context.getNodeId(), registration.getEndpoint(), null, null, credentials, credentials.getDeviceProfile().getUuidId(), UUID.randomUUID()); | ||
152 | - lwM2mClientsByEndpoint.put(registration.getEndpoint(), client); | 165 | + LwM2mClient client = getClientByEndpoint(registration.getEndpoint()); |
166 | + client.init(null, null, credentials, credentials.getDeviceProfile().getUuidId(), UUID.randomUUID()); | ||
153 | lwM2mClientsByRegistrationId.put(registration.getId(), client); | 167 | lwM2mClientsByRegistrationId.put(registration.getId(), client); |
154 | profileUpdate(credentials.getDeviceProfile()); | 168 | profileUpdate(credentials.getDeviceProfile()); |
155 | } | 169 | } |
@@ -171,7 +185,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | @@ -171,7 +185,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | ||
171 | 185 | ||
172 | @Override | 186 | @Override |
173 | public LwM2mClientProfile getProfile(Registration registration) { | 187 | public LwM2mClientProfile getProfile(Registration registration) { |
174 | - return this.getProfiles().get(getOrRegister(registration).getProfileId()); | 188 | + return this.getProfiles().get(getClientByEndpoint(registration.getEndpoint()).getProfileId()); |
175 | } | 189 | } |
176 | 190 | ||
177 | @Override | 191 | @Override |
@@ -186,25 +200,18 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | @@ -186,25 +200,18 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | ||
186 | if (lwM2MClientProfile != null) { | 200 | if (lwM2MClientProfile != null) { |
187 | profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile); | 201 | profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile); |
188 | return lwM2MClientProfile; | 202 | return lwM2MClientProfile; |
189 | - } | ||
190 | - else { | 203 | + } else { |
191 | return null; | 204 | return null; |
192 | } | 205 | } |
193 | } | 206 | } |
194 | 207 | ||
195 | - /** | ||
196 | - * if isVer - ok or default ver=DEFAULT_LWM2M_VERSION | ||
197 | - * | ||
198 | - * @param registration - | ||
199 | - * @return - all objectIdVer in client | ||
200 | - */ | ||
201 | @Override | 208 | @Override |
202 | - public Set<String> getSupportedIdVerInClient(Registration registration) { | 209 | + public Set<String> getSupportedIdVerInClient(LwM2mClient client) { |
203 | Set<String> clientObjects = ConcurrentHashMap.newKeySet(); | 210 | Set<String> clientObjects = ConcurrentHashMap.newKeySet(); |
204 | - Arrays.stream(registration.getObjectLinks()).forEach(url -> { | ||
205 | - LwM2mPath pathIds = new LwM2mPath(url.getUrl()); | 211 | + Arrays.stream(client.getRegistration().getObjectLinks()).forEach(link -> { |
212 | + LwM2mPath pathIds = new LwM2mPath(link.getUrl()); | ||
206 | if (!pathIds.isRoot()) { | 213 | if (!pathIds.isRoot()) { |
207 | - clientObjects.add(convertPathFromObjectIdToIdVer(url.getUrl(), registration)); | 214 | + clientObjects.add(convertPathFromObjectIdToIdVer(link.getUrl(), client.getRegistration())); |
208 | } | 215 | } |
209 | }); | 216 | }); |
210 | return (clientObjects.size() > 0) ? clientObjects : null; | 217 | return (clientObjects.size() > 0) ? clientObjects : null; |
@@ -215,20 +222,4 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | @@ -215,20 +222,4 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | ||
215 | return lwM2mClientsByRegistrationId.values().stream().filter(e -> deviceId.equals(e.getDeviceId())).findFirst().orElse(null); | 222 | return lwM2mClientsByRegistrationId.values().stream().filter(e -> deviceId.equals(e.getDeviceId())).findFirst().orElse(null); |
216 | } | 223 | } |
217 | 224 | ||
218 | - @Override | ||
219 | - public void removeClientByRegistrationId(String registrationId) { | ||
220 | - LwM2mClient lwM2MClient = this.lwM2mClientsByRegistrationId.get(registrationId); | ||
221 | - if (lwM2MClient != null) { | ||
222 | - this.securityStore.remove(lwM2MClient.getEndpoint(), false); | ||
223 | - this.lwM2mClientsByEndpoint.remove(lwM2MClient.getEndpoint()); | ||
224 | - this.lwM2mClientsByRegistrationId.remove(registrationId); | ||
225 | - UUID profileId = lwM2MClient.getProfileId(); | ||
226 | - if (profileId != null) { | ||
227 | - Optional<LwM2mClient> otherClients = lwM2mClientsByRegistrationId.values().stream().filter(e -> e.getProfileId().equals(profileId)).findFirst(); | ||
228 | - if (otherClients.isEmpty()) { | ||
229 | - profiles.remove(profileId); | ||
230 | - } | ||
231 | - } | ||
232 | - } | ||
233 | - } | ||
234 | } | 225 | } |
@@ -167,9 +167,9 @@ public class LwM2mFwSwUpdate { | @@ -167,9 +167,9 @@ public class LwM2mFwSwUpdate { | ||
167 | String targetIdVer = convertPathFromObjectIdToIdVer(this.pathPackageId, this.lwM2MClient.getRegistration()); | 167 | String targetIdVer = convertPathFromObjectIdToIdVer(this.pathPackageId, this.lwM2MClient.getRegistration()); |
168 | String fwMsg = String.format("%s: Start type operation %s paths: %s", LOG_LW2M_INFO, | 168 | String fwMsg = String.format("%s: Start type operation %s paths: %s", LOG_LW2M_INFO, |
169 | LwM2mTransportUtil.LwM2mTypeOper.FW_UPDATE.name(), FW_PACKAGE_ID); | 169 | LwM2mTransportUtil.LwM2mTypeOper.FW_UPDATE.name(), FW_PACKAGE_ID); |
170 | - handler.sendLogsToThingsboard(fwMsg, lwM2MClient.getRegistration().getId()); | 170 | + handler.sendLogsToThingsboard(lwM2MClient, fwMsg); |
171 | log.warn("8) Start firmware Update. Send save to: [{}] ver: [{}] path: [{}]", this.lwM2MClient.getDeviceName(), this.currentVersion, targetIdVer); | 171 | log.warn("8) Start firmware Update. Send save to: [{}] ver: [{}] path: [{}]", this.lwM2MClient.getDeviceName(), this.currentVersion, targetIdVer); |
172 | - request.sendAllRequest(this.lwM2MClient.getRegistration(), targetIdVer, WRITE_REPLACE, ContentFormat.OPAQUE.getName(), | 172 | + request.sendAllRequest(this.lwM2MClient, targetIdVer, WRITE_REPLACE, ContentFormat.OPAQUE, |
173 | firmwareChunk, handler.config.getTimeout(), this.rpcRequest); | 173 | firmwareChunk, handler.config.getTimeout(), this.rpcRequest); |
174 | } | 174 | } |
175 | else { | 175 | else { |
@@ -190,7 +190,7 @@ public class LwM2mFwSwUpdate { | @@ -190,7 +190,7 @@ public class LwM2mFwSwUpdate { | ||
190 | if (LOG_LW2M_ERROR.equals(typeInfo)) { | 190 | if (LOG_LW2M_ERROR.equals(typeInfo)) { |
191 | msg = String.format("%s Error: %s", msg, msgError); | 191 | msg = String.format("%s Error: %s", msg, msgError); |
192 | } | 192 | } |
193 | - handler.sendLogsToThingsboard(msg, lwM2MClient.getRegistration().getId()); | 193 | + handler.sendLogsToThingsboard(lwM2MClient, msg); |
194 | } | 194 | } |
195 | 195 | ||
196 | 196 | ||
@@ -202,8 +202,7 @@ public class LwM2mFwSwUpdate { | @@ -202,8 +202,7 @@ public class LwM2mFwSwUpdate { | ||
202 | public void executeFwSwWare(DefaultLwM2MTransportMsgHandler handler, LwM2mTransportRequest request) { | 202 | public void executeFwSwWare(DefaultLwM2MTransportMsgHandler handler, LwM2mTransportRequest request) { |
203 | this.setStateUpdate(UPDATING.name()); | 203 | this.setStateUpdate(UPDATING.name()); |
204 | this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_INFO, null); | 204 | this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_INFO, null); |
205 | - request.sendAllRequest(this.lwM2MClient.getRegistration(), this.pathInstallId, EXECUTE, ContentFormat.TLV.getName(), | ||
206 | - null, 0, this.rpcRequest); | 205 | + request.sendAllRequest(this.lwM2MClient, this.pathInstallId, EXECUTE, null, 0, this.rpcRequest); |
207 | } | 206 | } |
208 | 207 | ||
209 | /** | 208 | /** |
@@ -334,10 +333,10 @@ public class LwM2mFwSwUpdate { | @@ -334,10 +333,10 @@ public class LwM2mFwSwUpdate { | ||
334 | } | 333 | } |
335 | 334 | ||
336 | private void observeStateUpdate(DefaultLwM2MTransportMsgHandler handler, LwM2mTransportRequest request) { | 335 | private void observeStateUpdate(DefaultLwM2MTransportMsgHandler handler, LwM2mTransportRequest request) { |
337 | - request.sendAllRequest(lwM2MClient.getRegistration(), | 336 | + request.sendAllRequest(lwM2MClient, |
338 | convertPathFromObjectIdToIdVer(this.pathStateId, this.lwM2MClient.getRegistration()), OBSERVE, | 337 | convertPathFromObjectIdToIdVer(this.pathStateId, this.lwM2MClient.getRegistration()), OBSERVE, |
339 | null, null, 0, null); | 338 | null, null, 0, null); |
340 | - request.sendAllRequest(lwM2MClient.getRegistration(), | 339 | + request.sendAllRequest(lwM2MClient, |
341 | convertPathFromObjectIdToIdVer(this.pathResultId, this.lwM2MClient.getRegistration()), OBSERVE, | 340 | convertPathFromObjectIdToIdVer(this.pathResultId, this.lwM2MClient.getRegistration()), OBSERVE, |
342 | null, null, 0, null); | 341 | null, null, 0, null); |
343 | } | 342 | } |
@@ -364,8 +363,7 @@ public class LwM2mFwSwUpdate { | @@ -364,8 +363,7 @@ public class LwM2mFwSwUpdate { | ||
364 | this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer( | 363 | this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer( |
365 | this.pathResultId, this.lwM2MClient.getRegistration())); | 364 | this.pathResultId, this.lwM2MClient.getRegistration())); |
366 | this.pendingInfoRequestsStart.forEach(pathIdVer -> { | 365 | this.pendingInfoRequestsStart.forEach(pathIdVer -> { |
367 | - request.sendAllRequest(this.lwM2MClient.getRegistration(), pathIdVer, OBSERVE, ContentFormat.TLV.getName(), | ||
368 | - null, 0, this.rpcRequest); | 366 | + request.sendAllRequest(this.lwM2MClient, pathIdVer, OBSERVE, null, 0, this.rpcRequest); |
369 | }); | 367 | }); |
370 | 368 | ||
371 | } | 369 | } |
@@ -273,7 +273,7 @@ public class Lwm2mClientRpcRequest { | @@ -273,7 +273,7 @@ public class Lwm2mClientRpcRequest { | ||
273 | } | 273 | } |
274 | 274 | ||
275 | private String getRezIdByResourceNameAndObjectInstanceId(String resourceName, DefaultLwM2MTransportMsgHandler handler) { | 275 | private String getRezIdByResourceNameAndObjectInstanceId(String resourceName, DefaultLwM2MTransportMsgHandler handler) { |
276 | - LwM2mClient lwM2mClient = handler.clientContext.getClient(this.sessionInfo); | 276 | + LwM2mClient lwM2mClient = handler.clientContext.getClientBySessionInfo(this.sessionInfo); |
277 | return lwM2mClient != null ? | 277 | return lwM2mClient != null ? |
278 | lwM2mClient.getRezIdByResourceNameAndObjectInstanceId(resourceName, this.targetIdVer, handler.config.getModelProvider()) : | 278 | lwM2mClient.getRezIdByResourceNameAndObjectInstanceId(resourceName, this.targetIdVer, handler.config.getModelProvider()) : |
279 | null; | 279 | null; |
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.security.NonUniqueSecurityInfoException; | ||
19 | +import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; | ||
20 | + | ||
21 | +public interface TbEditableSecurityStore extends TbSecurityStore { | ||
22 | + | ||
23 | + void put(TbLwM2MSecurityInfo tbSecurityInfo) throws NonUniqueSecurityInfoException; | ||
24 | + | ||
25 | + void remove(String endpoint); | ||
26 | + | ||
27 | +} |
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.security.NonUniqueSecurityInfoException; | ||
19 | +import org.eclipse.leshan.server.security.SecurityInfo; | ||
20 | +import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; | ||
21 | + | ||
22 | +import java.util.HashMap; | ||
23 | +import java.util.Map; | ||
24 | +import java.util.concurrent.locks.Lock; | ||
25 | +import java.util.concurrent.locks.ReadWriteLock; | ||
26 | +import java.util.concurrent.locks.ReentrantReadWriteLock; | ||
27 | + | ||
28 | +public class TbInMemorySecurityStore implements TbEditableSecurityStore { | ||
29 | + // lock for the two maps | ||
30 | + protected final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); | ||
31 | + protected final Lock readLock = readWriteLock.readLock(); | ||
32 | + protected final Lock writeLock = readWriteLock.writeLock(); | ||
33 | + | ||
34 | + // by client end-point | ||
35 | + protected Map<String, TbLwM2MSecurityInfo> securityByEp = new HashMap<>(); | ||
36 | + | ||
37 | + // by PSK identity | ||
38 | + protected Map<String, TbLwM2MSecurityInfo> securityByIdentity = new HashMap<>(); | ||
39 | + | ||
40 | + public TbInMemorySecurityStore() { | ||
41 | + } | ||
42 | + | ||
43 | + /** | ||
44 | + * {@inheritDoc} | ||
45 | + */ | ||
46 | + @Override | ||
47 | + public SecurityInfo getByEndpoint(String endpoint) { | ||
48 | + readLock.lock(); | ||
49 | + try { | ||
50 | + TbLwM2MSecurityInfo securityInfo = securityByEp.get(endpoint); | ||
51 | + if (securityInfo != null) { | ||
52 | + return securityInfo.getSecurityInfo(); | ||
53 | + } else { | ||
54 | + return null; | ||
55 | + } | ||
56 | + } finally { | ||
57 | + readLock.unlock(); | ||
58 | + } | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * {@inheritDoc} | ||
63 | + */ | ||
64 | + @Override | ||
65 | + public SecurityInfo getByIdentity(String identity) { | ||
66 | + readLock.lock(); | ||
67 | + try { | ||
68 | + TbLwM2MSecurityInfo securityInfo = securityByIdentity.get(identity); | ||
69 | + if (securityInfo != null) { | ||
70 | + return securityInfo.getSecurityInfo(); | ||
71 | + } else { | ||
72 | + return null; | ||
73 | + } | ||
74 | + } finally { | ||
75 | + readLock.unlock(); | ||
76 | + } | ||
77 | + } | ||
78 | + | ||
79 | + @Override | ||
80 | + public void put(TbLwM2MSecurityInfo tbSecurityInfo) throws NonUniqueSecurityInfoException { | ||
81 | + writeLock.lock(); | ||
82 | + try { | ||
83 | + String identity = null; | ||
84 | + if (tbSecurityInfo.getSecurityInfo() != null) { | ||
85 | + identity = tbSecurityInfo.getSecurityInfo().getIdentity(); | ||
86 | + if (identity != null) { | ||
87 | + TbLwM2MSecurityInfo infoByIdentity = securityByIdentity.get(identity); | ||
88 | + if (infoByIdentity != null && !tbSecurityInfo.getSecurityInfo().getEndpoint().equals(infoByIdentity.getEndpoint())) { | ||
89 | + throw new NonUniqueSecurityInfoException("PSK Identity " + identity + " is already used"); | ||
90 | + } | ||
91 | + securityByIdentity.put(tbSecurityInfo.getSecurityInfo().getIdentity(), tbSecurityInfo); | ||
92 | + } | ||
93 | + } | ||
94 | + | ||
95 | + TbLwM2MSecurityInfo previous = securityByEp.put(tbSecurityInfo.getEndpoint(), tbSecurityInfo); | ||
96 | + if (previous != null && previous.getSecurityInfo() != null) { | ||
97 | + String previousIdentity = previous.getSecurityInfo().getIdentity(); | ||
98 | + if (previousIdentity != null && !previousIdentity.equals(identity)) { | ||
99 | + securityByIdentity.remove(previousIdentity); | ||
100 | + } | ||
101 | + } | ||
102 | + } finally { | ||
103 | + writeLock.unlock(); | ||
104 | + } | ||
105 | + } | ||
106 | + | ||
107 | + @Override | ||
108 | + public void remove(String endpoint) { | ||
109 | + writeLock.lock(); | ||
110 | + try { | ||
111 | + TbLwM2MSecurityInfo securityInfo = securityByEp.remove(endpoint); | ||
112 | + if (securityInfo != null && securityInfo.getSecurityInfo() != null && securityInfo.getSecurityInfo().getIdentity() != null) { | ||
113 | + securityByIdentity.remove(securityInfo.getSecurityInfo().getIdentity()); | ||
114 | + } | ||
115 | + } finally { | ||
116 | + writeLock.unlock(); | ||
117 | + } | ||
118 | + } | ||
119 | + | ||
120 | + @Override | ||
121 | + public TbLwM2MSecurityInfo getTbLwM2MSecurityInfoByEndpoint(String endpoint) { | ||
122 | + readLock.lock(); | ||
123 | + try { | ||
124 | + return securityByEp.get(endpoint); | ||
125 | + } finally { | ||
126 | + readLock.unlock(); | ||
127 | + } | ||
128 | + } | ||
129 | + | ||
130 | +} |
@@ -22,11 +22,13 @@ import org.eclipse.leshan.core.Destroyable; | @@ -22,11 +22,13 @@ import org.eclipse.leshan.core.Destroyable; | ||
22 | import org.eclipse.leshan.core.Startable; | 22 | import org.eclipse.leshan.core.Startable; |
23 | import org.eclipse.leshan.core.Stoppable; | 23 | import org.eclipse.leshan.core.Stoppable; |
24 | import org.eclipse.leshan.core.observation.Observation; | 24 | import org.eclipse.leshan.core.observation.Observation; |
25 | +import org.eclipse.leshan.core.request.Identity; | ||
25 | import org.eclipse.leshan.core.util.NamedThreadFactory; | 26 | import org.eclipse.leshan.core.util.NamedThreadFactory; |
26 | import org.eclipse.leshan.core.util.Validate; | 27 | import org.eclipse.leshan.core.util.Validate; |
27 | import org.eclipse.leshan.server.californium.observation.ObserveUtil; | 28 | import org.eclipse.leshan.server.californium.observation.ObserveUtil; |
28 | import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore; | 29 | import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore; |
29 | import org.eclipse.leshan.server.redis.RedisRegistrationStore; | 30 | import org.eclipse.leshan.server.redis.RedisRegistrationStore; |
31 | +import org.eclipse.leshan.server.redis.serialization.IdentitySerDes; | ||
30 | import org.eclipse.leshan.server.redis.serialization.ObservationSerDes; | 32 | import org.eclipse.leshan.server.redis.serialization.ObservationSerDes; |
31 | import org.eclipse.leshan.server.redis.serialization.RegistrationSerDes; | 33 | import org.eclipse.leshan.server.redis.serialization.RegistrationSerDes; |
32 | import org.eclipse.leshan.server.registration.Deregistration; | 34 | import org.eclipse.leshan.server.registration.Deregistration; |
@@ -73,6 +75,7 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | @@ -73,6 +75,7 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | ||
73 | private static final String REG_EP = "REG:EP:"; // (Endpoint => Registration) | 75 | 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) | 76 | 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) | 77 | private static final String REG_EP_ADDR_IDX = "EP:ADDR:"; // secondary index key (Socket Address => Endpoint) |
78 | + private static final String REG_EP_IDENTITY = "EP:IDENTITY:"; // secondary index key (Identity => Endpoint) | ||
76 | private static final String LOCK_EP = "LOCK:EP:"; | 79 | private static final String LOCK_EP = "LOCK:EP:"; |
77 | private static final byte[] OBS_TKN = "OBS:TKN:".getBytes(UTF_8); | 80 | 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) | 81 | private static final String OBS_TKNS_REGID_IDX = "TKNS:REGID:"; // secondary index (token list by registration) |
@@ -155,6 +158,8 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | @@ -155,6 +158,8 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | ||
155 | connection.set(regid_idx, registration.getEndpoint().getBytes(UTF_8)); | 158 | connection.set(regid_idx, registration.getEndpoint().getBytes(UTF_8)); |
156 | byte[] addr_idx = toRegAddrKey(registration.getSocketAddress()); | 159 | byte[] addr_idx = toRegAddrKey(registration.getSocketAddress()); |
157 | connection.set(addr_idx, registration.getEndpoint().getBytes(UTF_8)); | 160 | connection.set(addr_idx, registration.getEndpoint().getBytes(UTF_8)); |
161 | + byte[] identity_idx = toRegIdentityKey(registration.getIdentity()); | ||
162 | + connection.set(identity_idx, registration.getEndpoint().getBytes(UTF_8)); | ||
158 | 163 | ||
159 | // Add or update expiration | 164 | // Add or update expiration |
160 | addOrUpdateExpiration(connection, registration); | 165 | addOrUpdateExpiration(connection, registration); |
@@ -167,6 +172,9 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | @@ -167,6 +172,9 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | ||
167 | if (!oldRegistration.getSocketAddress().equals(registration.getSocketAddress())) { | 172 | if (!oldRegistration.getSocketAddress().equals(registration.getSocketAddress())) { |
168 | removeAddrIndex(connection, oldRegistration); | 173 | removeAddrIndex(connection, oldRegistration); |
169 | } | 174 | } |
175 | + if (!oldRegistration.getIdentity().equals(registration.getIdentity())) { | ||
176 | + removeIdentityIndex(connection, oldRegistration); | ||
177 | + } | ||
170 | // remove old observation | 178 | // remove old observation |
171 | Collection<Observation> obsRemoved = unsafeRemoveAllObservations(connection, oldRegistration.getId()); | 179 | Collection<Observation> obsRemoved = unsafeRemoveAllObservations(connection, oldRegistration.getId()); |
172 | 180 | ||
@@ -222,6 +230,9 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | @@ -222,6 +230,9 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | ||
222 | if (!r.getSocketAddress().equals(updatedRegistration.getSocketAddress())) { | 230 | if (!r.getSocketAddress().equals(updatedRegistration.getSocketAddress())) { |
223 | removeAddrIndex(connection, r); | 231 | removeAddrIndex(connection, r); |
224 | } | 232 | } |
233 | + if (!r.getIdentity().equals(updatedRegistration.getIdentity())) { | ||
234 | + removeIdentityIndex(connection, r); | ||
235 | + } | ||
225 | 236 | ||
226 | return new UpdatedRegistration(r, updatedRegistration); | 237 | return new UpdatedRegistration(r, updatedRegistration); |
227 | 238 | ||
@@ -269,6 +280,22 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | @@ -269,6 +280,22 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | ||
269 | } | 280 | } |
270 | 281 | ||
271 | @Override | 282 | @Override |
283 | + public Registration getRegistrationByIdentity(Identity identity) { | ||
284 | + Validate.notNull(identity); | ||
285 | + try (var connection = connectionFactory.getConnection()) { | ||
286 | + byte[] ep = connection.get(toRegIdentityKey(identity)); | ||
287 | + if (ep == null) { | ||
288 | + return null; | ||
289 | + } | ||
290 | + byte[] data = connection.get(toEndpointKey(ep)); | ||
291 | + if (data == null) { | ||
292 | + return null; | ||
293 | + } | ||
294 | + return deserializeReg(data); | ||
295 | + } | ||
296 | + } | ||
297 | + | ||
298 | + @Override | ||
272 | public Iterator<Registration> getAllRegistrations() { | 299 | public Iterator<Registration> getAllRegistrations() { |
273 | try (var connection = connectionFactory.getConnection()) { | 300 | try (var connection = connectionFactory.getConnection()) { |
274 | Collection<Registration> list = new LinkedList<>(); | 301 | Collection<Registration> list = new LinkedList<>(); |
@@ -325,6 +352,7 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | @@ -325,6 +352,7 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | ||
325 | connection.del(toEndpointKey(r.getEndpoint())); | 352 | connection.del(toEndpointKey(r.getEndpoint())); |
326 | Collection<Observation> obsRemoved = unsafeRemoveAllObservations(connection, r.getId()); | 353 | Collection<Observation> obsRemoved = unsafeRemoveAllObservations(connection, r.getId()); |
327 | removeAddrIndex(connection, r); | 354 | removeAddrIndex(connection, r); |
355 | + removeIdentityIndex(connection, r); | ||
328 | removeExpiration(connection, r); | 356 | removeExpiration(connection, r); |
329 | return new Deregistration(r, obsRemoved); | 357 | return new Deregistration(r, obsRemoved); |
330 | } | 358 | } |
@@ -337,20 +365,27 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | @@ -337,20 +365,27 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | ||
337 | } | 365 | } |
338 | } | 366 | } |
339 | 367 | ||
368 | + private void removeAddrIndex(RedisConnection connection, Registration r) { | ||
369 | + removeSecondaryIndex(connection, toRegAddrKey(r.getSocketAddress()), r.getEndpoint()); | ||
370 | + } | ||
371 | + | ||
372 | + private void removeIdentityIndex(RedisConnection connection, Registration r) { | ||
373 | + removeSecondaryIndex(connection, toRegIdentityKey(r.getIdentity()), r.getEndpoint()); | ||
374 | + } | ||
375 | + | ||
340 | //TODO: JedisCluster didn't implement Transaction, maybe should use some advanced key creation strategies | 376 | //TODO: JedisCluster didn't implement Transaction, maybe should use some advanced key creation strategies |
341 | - private void removeAddrIndex(RedisConnection connection, Registration registration) { | 377 | + private void removeSecondaryIndex(RedisConnection connection, byte[] indexKey, String endpointName) { |
342 | // Watch the key to remove. | 378 | // Watch the key to remove. |
343 | - byte[] regAddrKey = toRegAddrKey(registration.getSocketAddress()); | ||
344 | -// connection.watch(regAddrKey); | 379 | +// connection.watch(indexKey); |
345 | 380 | ||
346 | - byte[] epFromAddr = connection.get(regAddrKey); | 381 | + byte[] epFromAddr = connection.get(indexKey); |
347 | // Delete the key if needed. | 382 | // Delete the key if needed. |
348 | - if (Arrays.equals(epFromAddr, registration.getEndpoint().getBytes(UTF_8))) { | 383 | + if (Arrays.equals(epFromAddr, endpointName.getBytes(UTF_8))) { |
349 | // Try to delete the key | 384 | // Try to delete the key |
350 | // connection.multi(); | 385 | // connection.multi(); |
351 | - connection.del(regAddrKey); | 386 | + connection.del(indexKey); |
352 | // connection.exec(); | 387 | // connection.exec(); |
353 | - // if transaction failed this is not an issue as the socket address is probably reused and we don't neeed to | 388 | + // if transaction failed this is not an issue as the index is probably reused and we don't need to |
354 | // delete it anymore. | 389 | // delete it anymore. |
355 | } else { | 390 | } else { |
356 | // the key must not be deleted. | 391 | // the key must not be deleted. |
@@ -374,6 +409,10 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | @@ -374,6 +409,10 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | ||
374 | return toKey(REG_EP_ADDR_IDX, addr.getAddress().toString() + ":" + addr.getPort()); | 409 | return toKey(REG_EP_ADDR_IDX, addr.getAddress().toString() + ":" + addr.getPort()); |
375 | } | 410 | } |
376 | 411 | ||
412 | + private byte[] toRegIdentityKey(Identity identity) { | ||
413 | + return toKey(REG_EP_IDENTITY, IdentitySerDes.serialize(identity).toString()); | ||
414 | + } | ||
415 | + | ||
377 | private byte[] toEndpointKey(String endpoint) { | 416 | private byte[] toEndpointKey(String endpoint) { |
378 | return toKey(REG_EP, endpoint); | 417 | return toKey(REG_EP, endpoint); |
379 | } | 418 | } |
@@ -723,7 +762,6 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | @@ -723,7 +762,6 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto | ||
723 | 762 | ||
724 | @Override | 763 | @Override |
725 | public void run() { | 764 | public void run() { |
726 | - | ||
727 | try (var connection = connectionFactory.getConnection()) { | 765 | try (var connection = connectionFactory.getConnection()) { |
728 | Set<byte[]> endpointsExpired = connection.zRangeByScore(EXP_EP, Double.NEGATIVE_INFINITY, | 766 | Set<byte[]> endpointsExpired = connection.zRangeByScore(EXP_EP, Double.NEGATIVE_INFINITY, |
729 | System.currentTimeMillis(), 0, cleanLimit); | 767 | System.currentTimeMillis(), 0, cleanLimit); |
@@ -24,13 +24,14 @@ import org.springframework.data.redis.connection.RedisClusterConnection; | @@ -24,13 +24,14 @@ import org.springframework.data.redis.connection.RedisClusterConnection; | ||
24 | import org.springframework.data.redis.connection.RedisConnectionFactory; | 24 | import org.springframework.data.redis.connection.RedisConnectionFactory; |
25 | import org.springframework.data.redis.core.Cursor; | 25 | import org.springframework.data.redis.core.Cursor; |
26 | import org.springframework.data.redis.core.ScanOptions; | 26 | import org.springframework.data.redis.core.ScanOptions; |
27 | +import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; | ||
27 | 28 | ||
28 | import java.util.ArrayList; | 29 | import java.util.ArrayList; |
29 | import java.util.Collection; | 30 | import java.util.Collection; |
30 | import java.util.LinkedList; | 31 | import java.util.LinkedList; |
31 | import java.util.List; | 32 | import java.util.List; |
32 | 33 | ||
33 | -public class TbLwM2mRedisSecurityStore implements EditableSecurityStore { | 34 | +public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { |
34 | private static final String SEC_EP = "SEC#EP#"; | 35 | private static final String SEC_EP = "SEC#EP#"; |
35 | 36 | ||
36 | private static final String PSKID_SEC = "PSKID#SEC"; | 37 | private static final String PSKID_SEC = "PSKID#SEC"; |
@@ -72,73 +73,89 @@ public class TbLwM2mRedisSecurityStore implements EditableSecurityStore { | @@ -72,73 +73,89 @@ public class TbLwM2mRedisSecurityStore implements EditableSecurityStore { | ||
72 | } | 73 | } |
73 | 74 | ||
74 | @Override | 75 | @Override |
75 | - public Collection<SecurityInfo> getAll() { | ||
76 | - try (var connection = connectionFactory.getConnection()) { | ||
77 | - Collection<SecurityInfo> list = new LinkedList<>(); | ||
78 | - ScanOptions scanOptions = ScanOptions.scanOptions().count(100).match(SEC_EP + "*").build(); | ||
79 | - List<Cursor<byte[]>> scans = new ArrayList<>(); | ||
80 | - if (connection instanceof RedisClusterConnection) { | ||
81 | - ((RedisClusterConnection) connection).clusterGetNodes().forEach(node -> { | ||
82 | - scans.add(((RedisClusterConnection) connection).scan(node, scanOptions)); | ||
83 | - }); | ||
84 | - } else { | ||
85 | - scans.add(connection.scan(scanOptions)); | ||
86 | - } | ||
87 | - | ||
88 | - scans.forEach(scan -> { | ||
89 | - scan.forEachRemaining(key -> { | ||
90 | - byte[] element = connection.get(key); | ||
91 | - list.add(deserialize(element)); | ||
92 | - }); | ||
93 | - }); | ||
94 | - return list; | ||
95 | - } | 76 | + public void put(TbLwM2MSecurityInfo tbSecurityInfo) throws NonUniqueSecurityInfoException { |
77 | + //TODO: implement | ||
96 | } | 78 | } |
97 | 79 | ||
98 | @Override | 80 | @Override |
99 | - public SecurityInfo add(SecurityInfo info) throws NonUniqueSecurityInfoException { | ||
100 | - byte[] data = serialize(info); | ||
101 | - try (var connection = connectionFactory.getConnection()) { | ||
102 | - if (info.getIdentity() != null) { | ||
103 | - // populate the secondary index (security info by PSK id) | ||
104 | - String oldEndpoint = new String(connection.hGet(PSKID_SEC.getBytes(), info.getIdentity().getBytes())); | ||
105 | - if (!oldEndpoint.equals(info.getEndpoint())) { | ||
106 | - throw new NonUniqueSecurityInfoException("PSK Identity " + info.getIdentity() + " is already used"); | ||
107 | - } | ||
108 | - connection.hSet(PSKID_SEC.getBytes(), info.getIdentity().getBytes(), info.getEndpoint().getBytes()); | ||
109 | - } | ||
110 | - | ||
111 | - byte[] previousData = connection.getSet((SEC_EP + info.getEndpoint()).getBytes(), data); | ||
112 | - SecurityInfo previous = previousData == null ? null : deserialize(previousData); | ||
113 | - String previousIdentity = previous == null ? null : previous.getIdentity(); | ||
114 | - if (previousIdentity != null && !previousIdentity.equals(info.getIdentity())) { | ||
115 | - connection.hDel(PSKID_SEC.getBytes(), previousIdentity.getBytes()); | ||
116 | - } | ||
117 | - | ||
118 | - return previous; | ||
119 | - } | 81 | + public TbLwM2MSecurityInfo getTbLwM2MSecurityInfoByEndpoint(String endpoint) { |
82 | + //TODO: implement | ||
83 | + return null; | ||
120 | } | 84 | } |
121 | 85 | ||
122 | @Override | 86 | @Override |
123 | - public SecurityInfo remove(String endpoint, boolean infosAreCompromised) { | ||
124 | - try (var connection = connectionFactory.getConnection()) { | ||
125 | - byte[] data = connection.get((SEC_EP + endpoint).getBytes()); | ||
126 | - | ||
127 | - if (data != null) { | ||
128 | - SecurityInfo info = deserialize(data); | ||
129 | - if (info.getIdentity() != null) { | ||
130 | - connection.hDel(PSKID_SEC.getBytes(), info.getIdentity().getBytes()); | ||
131 | - } | ||
132 | - connection.del((SEC_EP + endpoint).getBytes()); | ||
133 | - if (listener != null) { | ||
134 | - listener.securityInfoRemoved(infosAreCompromised, info); | ||
135 | - } | ||
136 | - return info; | ||
137 | - } | ||
138 | - } | ||
139 | - return null; | 87 | + public void remove(String endpoint) { |
88 | + //TODO: implement | ||
140 | } | 89 | } |
141 | 90 | ||
91 | + // @Override | ||
92 | +// public Collection<SecurityInfo> getAll() { | ||
93 | +// try (var connection = connectionFactory.getConnection()) { | ||
94 | +// Collection<SecurityInfo> list = new LinkedList<>(); | ||
95 | +// ScanOptions scanOptions = ScanOptions.scanOptions().count(100).match(SEC_EP + "*").build(); | ||
96 | +// List<Cursor<byte[]>> scans = new ArrayList<>(); | ||
97 | +// if (connection instanceof RedisClusterConnection) { | ||
98 | +// ((RedisClusterConnection) connection).clusterGetNodes().forEach(node -> { | ||
99 | +// scans.add(((RedisClusterConnection) connection).scan(node, scanOptions)); | ||
100 | +// }); | ||
101 | +// } else { | ||
102 | +// scans.add(connection.scan(scanOptions)); | ||
103 | +// } | ||
104 | +// | ||
105 | +// scans.forEach(scan -> { | ||
106 | +// scan.forEachRemaining(key -> { | ||
107 | +// byte[] element = connection.get(key); | ||
108 | +// list.add(deserialize(element)); | ||
109 | +// }); | ||
110 | +// }); | ||
111 | +// return list; | ||
112 | +// } | ||
113 | +// } | ||
114 | +// | ||
115 | +// @Override | ||
116 | +// public SecurityInfo add(SecurityInfo info) throws NonUniqueSecurityInfoException { | ||
117 | +// byte[] data = serialize(info); | ||
118 | +// try (var connection = connectionFactory.getConnection()) { | ||
119 | +// if (info.getIdentity() != null) { | ||
120 | +// // populate the secondary index (security info by PSK id) | ||
121 | +// String oldEndpoint = new String(connection.hGet(PSKID_SEC.getBytes(), info.getIdentity().getBytes())); | ||
122 | +// if (!oldEndpoint.equals(info.getEndpoint())) { | ||
123 | +// throw new NonUniqueSecurityInfoException("PSK Identity " + info.getIdentity() + " is already used"); | ||
124 | +// } | ||
125 | +// connection.hSet(PSKID_SEC.getBytes(), info.getIdentity().getBytes(), info.getEndpoint().getBytes()); | ||
126 | +// } | ||
127 | +// | ||
128 | +// byte[] previousData = connection.getSet((SEC_EP + info.getEndpoint()).getBytes(), data); | ||
129 | +// SecurityInfo previous = previousData == null ? null : deserialize(previousData); | ||
130 | +// String previousIdentity = previous == null ? null : previous.getIdentity(); | ||
131 | +// if (previousIdentity != null && !previousIdentity.equals(info.getIdentity())) { | ||
132 | +// connection.hDel(PSKID_SEC.getBytes(), previousIdentity.getBytes()); | ||
133 | +// } | ||
134 | +// | ||
135 | +// return previous; | ||
136 | +// } | ||
137 | +// } | ||
138 | +// | ||
139 | +// @Override | ||
140 | +// public SecurityInfo remove(String endpoint, boolean infosAreCompromised) { | ||
141 | +// try (var connection = connectionFactory.getConnection()) { | ||
142 | +// byte[] data = connection.get((SEC_EP + endpoint).getBytes()); | ||
143 | +// | ||
144 | +// if (data != null) { | ||
145 | +// SecurityInfo info = deserialize(data); | ||
146 | +// if (info.getIdentity() != null) { | ||
147 | +// connection.hDel(PSKID_SEC.getBytes(), info.getIdentity().getBytes()); | ||
148 | +// } | ||
149 | +// connection.del((SEC_EP + endpoint).getBytes()); | ||
150 | +// if (listener != null) { | ||
151 | +// listener.securityInfoRemoved(infosAreCompromised, info); | ||
152 | +// } | ||
153 | +// return info; | ||
154 | +// } | ||
155 | +// } | ||
156 | +// return null; | ||
157 | +// } | ||
158 | + | ||
142 | private byte[] serialize(SecurityInfo secInfo) { | 159 | private byte[] serialize(SecurityInfo secInfo) { |
143 | return SecurityInfoSerDes.serialize(secInfo); | 160 | return SecurityInfoSerDes.serialize(secInfo); |
144 | } | 161 | } |
@@ -147,8 +164,4 @@ public class TbLwM2mRedisSecurityStore implements EditableSecurityStore { | @@ -147,8 +164,4 @@ public class TbLwM2mRedisSecurityStore implements EditableSecurityStore { | ||
147 | return SecurityInfoSerDes.deserialize(data); | 164 | return SecurityInfoSerDes.deserialize(data); |
148 | } | 165 | } |
149 | 166 | ||
150 | - @Override | ||
151 | - public void setListener(SecurityStoreListener listener) { | ||
152 | - this.listener = listener; | ||
153 | - } | ||
154 | } | 167 | } |
@@ -19,63 +19,39 @@ import lombok.extern.slf4j.Slf4j; | @@ -19,63 +19,39 @@ import lombok.extern.slf4j.Slf4j; | ||
19 | import org.eclipse.leshan.server.security.EditableSecurityStore; | 19 | import org.eclipse.leshan.server.security.EditableSecurityStore; |
20 | import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException; | 20 | import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException; |
21 | import org.eclipse.leshan.server.security.SecurityInfo; | 21 | import org.eclipse.leshan.server.security.SecurityInfo; |
22 | +import org.eclipse.leshan.server.security.SecurityStore; | ||
22 | import org.eclipse.leshan.server.security.SecurityStoreListener; | 23 | import org.eclipse.leshan.server.security.SecurityStoreListener; |
24 | +import org.jetbrains.annotations.Nullable; | ||
23 | import org.springframework.stereotype.Component; | 25 | import org.springframework.stereotype.Component; |
24 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | 26 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
25 | -import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; | 27 | +import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; |
28 | +import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; | ||
29 | +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; | ||
26 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; | 30 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
27 | 31 | ||
28 | import java.util.Collection; | 32 | import java.util.Collection; |
29 | 33 | ||
30 | @Slf4j | 34 | @Slf4j |
31 | -@Component | ||
32 | -@TbLwM2mTransportComponent | ||
33 | -public class TbLwM2mSecurityStore implements EditableSecurityStore { | 35 | +public class TbLwM2mSecurityStore implements TbEditableSecurityStore { |
34 | 36 | ||
35 | - private final LwM2mClientContext clientContext; | ||
36 | - private final EditableSecurityStore securityStore; | 37 | + private final TbEditableSecurityStore securityStore; |
38 | + private final LwM2mCredentialsSecurityInfoValidator validator; | ||
37 | 39 | ||
38 | - public TbLwM2mSecurityStore(LwM2mClientContext clientContext, EditableSecurityStore securityStore) { | ||
39 | - this.clientContext = clientContext; | 40 | + public TbLwM2mSecurityStore(TbEditableSecurityStore securityStore, LwM2mCredentialsSecurityInfoValidator validator) { |
40 | this.securityStore = securityStore; | 41 | this.securityStore = securityStore; |
42 | + this.validator = validator; | ||
41 | } | 43 | } |
42 | 44 | ||
43 | @Override | 45 | @Override |
44 | - public Collection<SecurityInfo> getAll() { | ||
45 | - return securityStore.getAll(); | ||
46 | - } | ||
47 | - | ||
48 | - @Override | ||
49 | - public SecurityInfo add(SecurityInfo info) throws NonUniqueSecurityInfoException { | ||
50 | - return securityStore.add(info); | ||
51 | - } | ||
52 | - | ||
53 | - @Override | ||
54 | - public SecurityInfo remove(String endpoint, boolean infosAreCompromised) { | ||
55 | - return securityStore.remove(endpoint, infosAreCompromised); | ||
56 | - } | ||
57 | - | ||
58 | - @Override | ||
59 | - public void setListener(SecurityStoreListener listener) { | ||
60 | - securityStore.setListener(listener); | 46 | + public TbLwM2MSecurityInfo getTbLwM2MSecurityInfoByEndpoint(String endpoint) { |
47 | + return securityStore.getTbLwM2MSecurityInfoByEndpoint(endpoint); | ||
61 | } | 48 | } |
62 | 49 | ||
63 | @Override | 50 | @Override |
64 | public SecurityInfo getByEndpoint(String endpoint) { | 51 | public SecurityInfo getByEndpoint(String endpoint) { |
65 | SecurityInfo securityInfo = securityStore.getByEndpoint(endpoint); | 52 | SecurityInfo securityInfo = securityStore.getByEndpoint(endpoint); |
66 | if (securityInfo == null) { | 53 | if (securityInfo == null) { |
67 | - LwM2mClient lwM2mClient = clientContext.getClientByEndpoint(endpoint); | ||
68 | - if (lwM2mClient != null && lwM2mClient.getRegistration() != null && !lwM2mClient.getRegistration().getIdentity().isSecure()) { | ||
69 | - return null; | ||
70 | - } | ||
71 | - securityInfo = clientContext.fetchClientByEndpoint(endpoint).getSecurityInfo(); | ||
72 | - try { | ||
73 | - if (securityInfo != null) { | ||
74 | - add(securityInfo); | ||
75 | - } | ||
76 | - } catch (NonUniqueSecurityInfoException e) { | ||
77 | - log.trace("Failed to add security info: {}", securityInfo, e); | ||
78 | - } | 54 | + securityInfo = fetchAndPutSecurityInfo(endpoint); |
79 | } | 55 | } |
80 | return securityInfo; | 56 | return securityInfo; |
81 | } | 57 | } |
@@ -84,15 +60,31 @@ public class TbLwM2mSecurityStore implements EditableSecurityStore { | @@ -84,15 +60,31 @@ public class TbLwM2mSecurityStore implements EditableSecurityStore { | ||
84 | public SecurityInfo getByIdentity(String pskIdentity) { | 60 | public SecurityInfo getByIdentity(String pskIdentity) { |
85 | SecurityInfo securityInfo = securityStore.getByIdentity(pskIdentity); | 61 | SecurityInfo securityInfo = securityStore.getByIdentity(pskIdentity); |
86 | if (securityInfo == null) { | 62 | if (securityInfo == null) { |
87 | - securityInfo = clientContext.fetchClientByEndpoint(pskIdentity).getSecurityInfo(); | ||
88 | - try { | ||
89 | - if (securityInfo != null) { | ||
90 | - add(securityInfo); | ||
91 | - } | ||
92 | - } catch (NonUniqueSecurityInfoException e) { | ||
93 | - log.trace("Failed to add security info: {}", securityInfo, e); | ||
94 | - } | 63 | + securityInfo = fetchAndPutSecurityInfo(pskIdentity); |
95 | } | 64 | } |
96 | return securityInfo; | 65 | return securityInfo; |
97 | } | 66 | } |
67 | + | ||
68 | + @Nullable | ||
69 | + public SecurityInfo fetchAndPutSecurityInfo(String credentialsId) { | ||
70 | + TbLwM2MSecurityInfo securityInfo = validator.getEndpointSecurityInfoByCredentialsId(credentialsId, LwM2mTransportUtil.LwM2mTypeServer.CLIENT); | ||
71 | + try { | ||
72 | + if (securityInfo != null) { | ||
73 | + securityStore.put(securityInfo); | ||
74 | + } | ||
75 | + } catch (NonUniqueSecurityInfoException e) { | ||
76 | + log.trace("Failed to add security info: {}", securityInfo, e); | ||
77 | + } | ||
78 | + return securityInfo != null ? securityInfo.getSecurityInfo() : null; | ||
79 | + } | ||
80 | + | ||
81 | + @Override | ||
82 | + public void put(TbLwM2MSecurityInfo tbSecurityInfo) throws NonUniqueSecurityInfoException { | ||
83 | + securityStore.put(tbSecurityInfo); | ||
84 | + } | ||
85 | + | ||
86 | + @Override | ||
87 | + public void remove(String endpoint) { | ||
88 | + securityStore.remove(endpoint); | ||
89 | + } | ||
98 | } | 90 | } |
@@ -17,17 +17,14 @@ package org.thingsboard.server.transport.lwm2m.server.store; | @@ -17,17 +17,14 @@ package org.thingsboard.server.transport.lwm2m.server.store; | ||
17 | 17 | ||
18 | import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore; | 18 | import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore; |
19 | import org.eclipse.leshan.server.californium.registration.InMemoryRegistrationStore; | 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.springframework.beans.factory.annotation.Autowired; | 20 | import org.springframework.beans.factory.annotation.Autowired; |
23 | import org.springframework.beans.factory.annotation.Value; | 21 | import org.springframework.beans.factory.annotation.Value; |
24 | import org.springframework.context.annotation.Bean; | 22 | import org.springframework.context.annotation.Bean; |
25 | -import org.springframework.context.annotation.Lazy; | ||
26 | import org.springframework.stereotype.Component; | 23 | import org.springframework.stereotype.Component; |
27 | import org.thingsboard.server.cache.TBRedisCacheConfiguration; | 24 | import org.thingsboard.server.cache.TBRedisCacheConfiguration; |
28 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | 25 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
29 | import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; | 26 | import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; |
30 | -import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; | 27 | +import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; |
31 | 28 | ||
32 | import java.util.Optional; | 29 | import java.util.Optional; |
33 | 30 | ||
@@ -42,8 +39,7 @@ public class TbLwM2mStoreFactory { | @@ -42,8 +39,7 @@ public class TbLwM2mStoreFactory { | ||
42 | private LwM2MTransportServerConfig config; | 39 | private LwM2MTransportServerConfig config; |
43 | 40 | ||
44 | @Autowired | 41 | @Autowired |
45 | - @Lazy | ||
46 | - private LwM2mClientContext clientContext; | 42 | + private LwM2mCredentialsSecurityInfoValidator validator; |
47 | 43 | ||
48 | @Value("${transport.lwm2m.redis.enabled:false}") | 44 | @Value("${transport.lwm2m.redis.enabled:false}") |
49 | private boolean useRedis; | 45 | private boolean useRedis; |
@@ -55,9 +51,9 @@ public class TbLwM2mStoreFactory { | @@ -55,9 +51,9 @@ public class TbLwM2mStoreFactory { | ||
55 | } | 51 | } |
56 | 52 | ||
57 | @Bean | 53 | @Bean |
58 | - private EditableSecurityStore securityStore() { | ||
59 | - return new TbLwM2mSecurityStore(clientContext, redisConfiguration.isPresent() && useRedis ? | ||
60 | - new TbLwM2mRedisSecurityStore(redisConfiguration.get().redisConnectionFactory()) : new InMemorySecurityStore()); | 54 | + private TbEditableSecurityStore securityStore() { |
55 | + return new TbLwM2mSecurityStore(redisConfiguration.isPresent() && useRedis ? | ||
56 | + new TbLwM2mRedisSecurityStore(redisConfiguration.get().redisConnectionFactory()) : new TbInMemorySecurityStore(), validator); | ||
61 | } | 57 | } |
62 | 58 | ||
63 | @Bean | 59 | @Bean |
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.security.SecurityStore; | ||
19 | +import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; | ||
20 | + | ||
21 | +public interface TbSecurityStore extends SecurityStore { | ||
22 | + | ||
23 | + TbLwM2MSecurityInfo getTbLwM2MSecurityInfoByEndpoint(String endpoint); | ||
24 | + | ||
25 | +} |
@@ -69,9 +69,7 @@ | @@ -69,9 +69,7 @@ | ||
69 | <jackson-core.version>2.12.1</jackson-core.version> | 69 | <jackson-core.version>2.12.1</jackson-core.version> |
70 | <json-schema-validator.version>2.2.6</json-schema-validator.version> | 70 | <json-schema-validator.version>2.2.6</json-schema-validator.version> |
71 | <californium.version>2.6.1</californium.version> | 71 | <californium.version>2.6.1</californium.version> |
72 | - <leshan-server.version>1.3.1</leshan-server.version> | ||
73 | - <leshan-core.version>1.3.1</leshan-core.version> | ||
74 | - <leshan-client.version>1.3.1</leshan-client.version> | 72 | + <leshan.version>2.0.0-M3</leshan.version> |
75 | <gson.version>2.6.2</gson.version> | 73 | <gson.version>2.6.2</gson.version> |
76 | <freemarker.version>2.3.30</freemarker.version> | 74 | <freemarker.version>2.3.30</freemarker.version> |
77 | <mail.version>1.6.2</mail.version> | 75 | <mail.version>1.6.2</mail.version> |
@@ -1222,22 +1220,22 @@ | @@ -1222,22 +1220,22 @@ | ||
1222 | <dependency> | 1220 | <dependency> |
1223 | <groupId>org.eclipse.leshan</groupId> | 1221 | <groupId>org.eclipse.leshan</groupId> |
1224 | <artifactId>leshan-server-cf</artifactId> | 1222 | <artifactId>leshan-server-cf</artifactId> |
1225 | - <version>${leshan-server.version}</version> | 1223 | + <version>${leshan.version}</version> |
1226 | </dependency> | 1224 | </dependency> |
1227 | <dependency> | 1225 | <dependency> |
1228 | <groupId>org.eclipse.leshan</groupId> | 1226 | <groupId>org.eclipse.leshan</groupId> |
1229 | <artifactId>leshan-client-cf</artifactId> | 1227 | <artifactId>leshan-client-cf</artifactId> |
1230 | - <version>${leshan-client.version}</version> | 1228 | + <version>${leshan.version}</version> |
1231 | </dependency> | 1229 | </dependency> |
1232 | <dependency> | 1230 | <dependency> |
1233 | <groupId>org.eclipse.leshan</groupId> | 1231 | <groupId>org.eclipse.leshan</groupId> |
1234 | <artifactId>leshan-server-redis</artifactId> | 1232 | <artifactId>leshan-server-redis</artifactId> |
1235 | - <version>${leshan-server.version}</version> | 1233 | + <version>${leshan.version}</version> |
1236 | </dependency> | 1234 | </dependency> |
1237 | <dependency> | 1235 | <dependency> |
1238 | <groupId>org.eclipse.leshan</groupId> | 1236 | <groupId>org.eclipse.leshan</groupId> |
1239 | <artifactId>leshan-core</artifactId> | 1237 | <artifactId>leshan-core</artifactId> |
1240 | - <version>${leshan-core.version}</version> | 1238 | + <version>${leshan.version}</version> |
1241 | </dependency> | 1239 | </dependency> |
1242 | <dependency> | 1240 | <dependency> |
1243 | <groupId>org.eclipse.californium</groupId> | 1241 | <groupId>org.eclipse.californium</groupId> |