Commit 72382a52e3e4b7d1b550c0d7fdb03a027c77c5a4

Authored by Andrii Shvaika
1 parent dd5195e8

LwM2M Server refactoring

Showing 11 changed files with 423 additions and 398 deletions
@@ -32,7 +32,7 @@ import org.springframework.stereotype.Service; @@ -32,7 +32,7 @@ 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.LwM2MSecurityMode; 33 import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
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.secure.ReadResultSecurityStore; 35 +import org.thingsboard.server.transport.lwm2m.secure.EndpointSecurityInfo;
36 import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener; 36 import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener;
37 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; 37 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
38 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper; 38 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper;
@@ -72,7 +72,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { @@ -72,7 +72,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
72 72
73 @Override 73 @Override
74 public List<SecurityInfo> getAllByEndpoint(String endPoint) { 74 public List<SecurityInfo> getAllByEndpoint(String endPoint) {
75 - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(endPoint, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP); 75 + EndpointSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(endPoint, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP);
76 if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { 76 if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
77 /* add value to store from BootstrapJson */ 77 /* add value to store from BootstrapJson */
78 this.setBootstrapConfigScurityInfo(store); 78 this.setBootstrapConfigScurityInfo(store);
@@ -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 - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP); 99 + EndpointSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(identity, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP);
100 if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { 100 if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
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(ReadResultSecurityStore store) { 116 + private void setBootstrapConfigScurityInfo(EndpointSecurityInfo 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(ReadResultSecurityStore store) { 153 + private LwM2MBootstrapConfig getParametersBootstrap(EndpointSecurityInfo store) {
154 try { 154 try {
155 JsonObject bootstrapJsonCredential = store.getBootstrapJsonCredential(); 155 JsonObject bootstrapJsonCredential = store.getBootstrapJsonCredential();
156 if (bootstrapJsonCredential != null) { 156 if (bootstrapJsonCredential != null) {
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/EndpointSecurityInfo.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/ReadResultSecurityStore.java
@@ -25,7 +25,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCreden @@ -25,7 +25,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCreden
25 import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.DEFAULT_MODE; 25 import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.DEFAULT_MODE;
26 26
27 @Data 27 @Data
28 -public class ReadResultSecurityStore { 28 +public class EndpointSecurityInfo {
29 private ValidateDeviceCredentialsResponseMsg msg; 29 private ValidateDeviceCredentialsResponseMsg msg;
30 private SecurityInfo securityInfo; 30 private SecurityInfo securityInfo;
31 private int securityMode = DEFAULT_MODE.code; 31 private int securityMode = DEFAULT_MODE.code;
@@ -52,15 +52,10 @@ public class LwM2mCredentialsSecurityInfoValidator { @@ -52,15 +52,10 @@ public class LwM2mCredentialsSecurityInfoValidator {
52 private final LwM2mTransportContext context; 52 private final LwM2mTransportContext context;
53 private final LwM2MTransportServerConfig config; 53 private final LwM2MTransportServerConfig config;
54 54
55 - /**  
56 - * Request to thingsboard Response from thingsboard ValidateDeviceLwM2MCredentials  
57 - * @param endpoint -  
58 - * @param keyValue -  
59 - * @return ValidateDeviceCredentialsResponseMsg and SecurityInfo  
60 - */  
61 - public ReadResultSecurityStore createAndValidateCredentialsSecurityInfo(String endpoint, LwM2mTransportUtil.LwM2mTypeServer keyValue) { 55 +
  56 + public EndpointSecurityInfo getEndpointSecurityInfo(String endpoint, LwM2mTransportUtil.LwM2mTypeServer keyValue) {
62 CountDownLatch latch = new CountDownLatch(1); 57 CountDownLatch latch = new CountDownLatch(1);
63 - final ReadResultSecurityStore[] resultSecurityStore = new ReadResultSecurityStore[1]; 58 + final EndpointSecurityInfo[] resultSecurityStore = new EndpointSecurityInfo[1];
64 context.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endpoint).build(), 59 context.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endpoint).build(),
65 new TransportServiceCallback<>() { 60 new TransportServiceCallback<>() {
66 @Override 61 @Override
@@ -90,27 +85,27 @@ public class LwM2mCredentialsSecurityInfoValidator { @@ -90,27 +85,27 @@ public class LwM2mCredentialsSecurityInfoValidator {
90 85
91 /** 86 /**
92 * Create new SecurityInfo 87 * Create new SecurityInfo
93 - * @param endPoint - 88 + * @param endpoint -
94 * @param jsonStr - 89 * @param jsonStr -
95 * @param keyValue - 90 * @param keyValue -
96 * @return SecurityInfo 91 * @return SecurityInfo
97 */ 92 */
98 - private ReadResultSecurityStore createSecurityInfo(String endPoint, String jsonStr, LwM2mTransportUtil.LwM2mTypeServer keyValue) {  
99 - ReadResultSecurityStore result = new ReadResultSecurityStore(); 93 + private EndpointSecurityInfo createSecurityInfo(String endpoint, String jsonStr, LwM2mTransportUtil.LwM2mTypeServer keyValue) {
  94 + EndpointSecurityInfo result = new EndpointSecurityInfo();
100 JsonObject objectMsg = LwM2mTransportUtil.validateJson(jsonStr); 95 JsonObject objectMsg = LwM2mTransportUtil.validateJson(jsonStr);
101 if (objectMsg != null && !objectMsg.isJsonNull()) { 96 if (objectMsg != null && !objectMsg.isJsonNull()) {
102 JsonObject object = (objectMsg.has(keyValue.type) && !objectMsg.get(keyValue.type).isJsonNull()) ? objectMsg.get(keyValue.type).getAsJsonObject() : null; 97 JsonObject object = (objectMsg.has(keyValue.type) && !objectMsg.get(keyValue.type).isJsonNull()) ? objectMsg.get(keyValue.type).getAsJsonObject() : null;
103 /** 98 /**
104 * Only PSK 99 * Only PSK
105 */ 100 */
106 - String endPointPsk = (objectMsg.has("client") 101 + String endpointPsk = (objectMsg.has("client")
107 && objectMsg.get("client").getAsJsonObject().has("endpoint") 102 && objectMsg.get("client").getAsJsonObject().has("endpoint")
108 && objectMsg.get("client").getAsJsonObject().get("endpoint").isJsonPrimitive()) ? objectMsg.get("client").getAsJsonObject().get("endpoint").getAsString() : null; 103 && objectMsg.get("client").getAsJsonObject().get("endpoint").isJsonPrimitive()) ? objectMsg.get("client").getAsJsonObject().get("endpoint").getAsString() : null;
109 - endPoint = (endPointPsk == null || endPointPsk.isEmpty()) ? endPoint : endPointPsk; 104 + endpoint = (endpointPsk == null || endpointPsk.isEmpty()) ? endpoint : endpointPsk;
110 if (object != null && !object.isJsonNull()) { 105 if (object != null && !object.isJsonNull()) {
111 if (keyValue.equals(LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP)) { 106 if (keyValue.equals(LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP)) {
112 result.setBootstrapJsonCredential(object); 107 result.setBootstrapJsonCredential(object);
113 - result.setEndPoint(endPoint); 108 + result.setEndPoint(endpoint);
114 result.setSecurityMode(LwM2MSecurityMode.fromSecurityMode(object.get("bootstrapServer").getAsJsonObject().get("securityMode").getAsString().toLowerCase()).code); 109 result.setSecurityMode(LwM2MSecurityMode.fromSecurityMode(object.get("bootstrapServer").getAsJsonObject().get("securityMode").getAsString().toLowerCase()).code);
115 } else { 110 } else {
116 LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(object.get("securityConfigClientMode").getAsString().toLowerCase()); 111 LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(object.get("securityConfigClientMode").getAsString().toLowerCase());
@@ -119,13 +114,13 @@ public class LwM2mCredentialsSecurityInfoValidator { @@ -119,13 +114,13 @@ public class LwM2mCredentialsSecurityInfoValidator {
119 createClientSecurityInfoNoSec(result); 114 createClientSecurityInfoNoSec(result);
120 break; 115 break;
121 case PSK: 116 case PSK:
122 - createClientSecurityInfoPSK(result, endPoint, object); 117 + createClientSecurityInfoPSK(result, endpoint, object);
123 break; 118 break;
124 case RPK: 119 case RPK:
125 - createClientSecurityInfoRPK(result, endPoint, object); 120 + createClientSecurityInfoRPK(result, endpoint, object);
126 break; 121 break;
127 case X509: 122 case X509:
128 - createClientSecurityInfoX509(result, endPoint); 123 + createClientSecurityInfoX509(result, endpoint);
129 break; 124 break;
130 default: 125 default:
131 break; 126 break;
@@ -136,20 +131,20 @@ public class LwM2mCredentialsSecurityInfoValidator { @@ -136,20 +131,20 @@ public class LwM2mCredentialsSecurityInfoValidator {
136 return result; 131 return result;
137 } 132 }
138 133
139 - private void createClientSecurityInfoNoSec(ReadResultSecurityStore result) { 134 + private void createClientSecurityInfoNoSec(EndpointSecurityInfo result) {
140 result.setSecurityInfo(null); 135 result.setSecurityInfo(null);
141 result.setSecurityMode(NO_SEC.code); 136 result.setSecurityMode(NO_SEC.code);
142 } 137 }
143 138
144 - private void createClientSecurityInfoPSK(ReadResultSecurityStore result, String endPoint, JsonObject object) { 139 + private void createClientSecurityInfoPSK(EndpointSecurityInfo result, String endpoint, JsonObject object) {
145 /** PSK Deserialization */ 140 /** PSK Deserialization */
146 String identity = (object.has("identity") && object.get("identity").isJsonPrimitive()) ? object.get("identity").getAsString() : null; 141 String identity = (object.has("identity") && object.get("identity").isJsonPrimitive()) ? object.get("identity").getAsString() : null;
147 if (identity != null && !identity.isEmpty()) { 142 if (identity != null && !identity.isEmpty()) {
148 try { 143 try {
149 byte[] key = (object.has("key") && object.get("key").isJsonPrimitive()) ? Hex.decodeHex(object.get("key").getAsString().toCharArray()) : null; 144 byte[] key = (object.has("key") && object.get("key").isJsonPrimitive()) ? Hex.decodeHex(object.get("key").getAsString().toCharArray()) : null;
150 if (key != null && key.length > 0) { 145 if (key != null && key.length > 0) {
151 - if (endPoint != null && !endPoint.isEmpty()) {  
152 - result.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(endPoint, identity, key)); 146 + if (endpoint != null && !endpoint.isEmpty()) {
  147 + result.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(endpoint, identity, key));
153 result.setSecurityMode(PSK.code); 148 result.setSecurityMode(PSK.code);
154 } 149 }
155 } 150 }
@@ -161,7 +156,7 @@ public class LwM2mCredentialsSecurityInfoValidator { @@ -161,7 +156,7 @@ public class LwM2mCredentialsSecurityInfoValidator {
161 } 156 }
162 } 157 }
163 158
164 - private void createClientSecurityInfoRPK(ReadResultSecurityStore result, String endpoint, JsonObject object) { 159 + private void createClientSecurityInfoRPK(EndpointSecurityInfo result, String endpoint, JsonObject object) {
165 try { 160 try {
166 if (object.has("key") && object.get("key").isJsonPrimitive()) { 161 if (object.has("key") && object.get("key").isJsonPrimitive()) {
167 byte[] rpkkey = Hex.decodeHex(object.get("key").getAsString().toLowerCase().toCharArray()); 162 byte[] rpkkey = Hex.decodeHex(object.get("key").getAsString().toLowerCase().toCharArray());
@@ -176,7 +171,7 @@ public class LwM2mCredentialsSecurityInfoValidator { @@ -176,7 +171,7 @@ public class LwM2mCredentialsSecurityInfoValidator {
176 } 171 }
177 } 172 }
178 173
179 - private void createClientSecurityInfoX509(ReadResultSecurityStore result, String endpoint) { 174 + private void createClientSecurityInfoX509(EndpointSecurityInfo result, String endpoint) {
180 result.setSecurityInfo(SecurityInfo.newX509CertInfo(endpoint)); 175 result.setSecurityInfo(SecurityInfo.newX509CertInfo(endpoint));
181 result.setSecurityMode(X509.code); 176 result.setSecurityMode(X509.code);
182 } 177 }
@@ -32,11 +32,11 @@ import org.eclipse.leshan.core.observation.Observation; @@ -32,11 +32,11 @@ 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.WriteRequest; 33 import org.eclipse.leshan.core.request.WriteRequest;
34 import org.eclipse.leshan.core.response.ReadResponse; 34 import org.eclipse.leshan.core.response.ReadResponse;
35 -import org.eclipse.leshan.core.util.NamedThreadFactory;  
36 import org.eclipse.leshan.server.registration.Registration; 35 import org.eclipse.leshan.server.registration.Registration;
37 import org.springframework.context.annotation.Lazy; 36 import org.springframework.context.annotation.Lazy;
38 import org.springframework.stereotype.Service; 37 import org.springframework.stereotype.Service;
39 import org.thingsboard.common.util.JacksonUtil; 38 import org.thingsboard.common.util.JacksonUtil;
  39 +import org.thingsboard.common.util.ThingsBoardExecutors;
40 import org.thingsboard.server.cache.firmware.FirmwareDataCache; 40 import org.thingsboard.server.cache.firmware.FirmwareDataCache;
41 import org.thingsboard.server.common.data.Device; 41 import org.thingsboard.server.common.data.Device;
42 import org.thingsboard.server.common.data.DeviceProfile; 42 import org.thingsboard.server.common.data.DeviceProfile;
@@ -66,8 +66,8 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; @@ -66,8 +66,8 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
66 import javax.annotation.PostConstruct; 66 import javax.annotation.PostConstruct;
67 import java.util.ArrayList; 67 import java.util.ArrayList;
68 import java.util.Collection; 68 import java.util.Collection;
  69 +import java.util.Collections;
69 import java.util.HashSet; 70 import java.util.HashSet;
70 -import java.util.LinkedHashSet;  
71 import java.util.List; 71 import java.util.List;
72 import java.util.Map; 72 import java.util.Map;
73 import java.util.Optional; 73 import java.util.Optional;
@@ -77,7 +77,6 @@ import java.util.UUID; @@ -77,7 +77,6 @@ import java.util.UUID;
77 import java.util.concurrent.ConcurrentHashMap; 77 import java.util.concurrent.ConcurrentHashMap;
78 import java.util.concurrent.ConcurrentMap; 78 import java.util.concurrent.ConcurrentMap;
79 import java.util.concurrent.ExecutorService; 79 import java.util.concurrent.ExecutorService;
80 -import java.util.concurrent.Executors;  
81 import java.util.concurrent.TimeUnit; 80 import java.util.concurrent.TimeUnit;
82 import java.util.stream.Collectors; 81 import java.util.stream.Collectors;
83 82
@@ -85,6 +84,7 @@ import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; @@ -85,6 +84,7 @@ import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST;
85 import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; 84 import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION;
86 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; 85 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY;
87 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; 86 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
  87 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto;
88 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.CLIENT_NOT_AUTHORIZED; 88 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.CLIENT_NOT_AUTHORIZED;
89 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEVICE_ATTRIBUTES_REQUEST; 89 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEVICE_ATTRIBUTES_REQUEST;
90 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FR_OBJECT_ID; 90 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FR_OBJECT_ID;
@@ -103,7 +103,6 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L @@ -103,7 +103,6 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L
103 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES; 103 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES;
104 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; 104 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE;
105 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE; 105 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE;
106 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SERVICE_CHANNEL;  
107 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertJsonArrayToSet; 106 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertJsonArrayToSet;
108 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId; 107 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId;
109 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer; 108 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer;
@@ -115,9 +114,9 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.v @@ -115,9 +114,9 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.v
115 @TbLwM2mTransportComponent 114 @TbLwM2mTransportComponent
116 public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler { 115 public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler {
117 116
118 - private ExecutorService executorRegistered;  
119 - private ExecutorService executorUpdateRegistered;  
120 - private ExecutorService executorUnRegistered; 117 + private ExecutorService registrationExecutor;
  118 + private ExecutorService updateRegistrationExecutor;
  119 + private ExecutorService unregistrationExecutor;
121 private LwM2mValueConverterImpl converter; 120 private LwM2mValueConverterImpl converter;
122 121
123 private final TransportService transportService; 122 private final TransportService transportService;
@@ -126,18 +125,18 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -126,18 +125,18 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
126 private final FirmwareDataCache firmwareDataCache; 125 private final FirmwareDataCache firmwareDataCache;
127 private final LwM2mTransportServerHelper helper; 126 private final LwM2mTransportServerHelper helper;
128 private final LwM2MJsonAdaptor adaptor; 127 private final LwM2MJsonAdaptor adaptor;
129 - private final LwM2mClientContext lwM2mClientContext; 128 + private final LwM2mClientContext clientContext;
130 private final LwM2mTransportRequest lwM2mTransportRequest; 129 private final LwM2mTransportRequest lwM2mTransportRequest;
131 130
132 public DefaultLwM2MTransportMsgHandler(TransportService transportService, LwM2MTransportServerConfig config, LwM2mTransportServerHelper helper, 131 public DefaultLwM2MTransportMsgHandler(TransportService transportService, LwM2MTransportServerConfig config, LwM2mTransportServerHelper helper,
133 - LwM2mClientContext lwM2mClientContext, 132 + LwM2mClientContext clientContext,
134 @Lazy LwM2mTransportRequest lwM2mTransportRequest, 133 @Lazy LwM2mTransportRequest lwM2mTransportRequest,
135 FirmwareDataCache firmwareDataCache, 134 FirmwareDataCache firmwareDataCache,
136 LwM2mTransportContext context, LwM2MJsonAdaptor adaptor) { 135 LwM2mTransportContext context, LwM2MJsonAdaptor adaptor) {
137 this.transportService = transportService; 136 this.transportService = transportService;
138 this.config = config; 137 this.config = config;
139 this.helper = helper; 138 this.helper = helper;
140 - this.lwM2mClientContext = lwM2mClientContext; 139 + this.clientContext = clientContext;
141 this.lwM2mTransportRequest = lwM2mTransportRequest; 140 this.lwM2mTransportRequest = lwM2mTransportRequest;
142 this.firmwareDataCache = firmwareDataCache; 141 this.firmwareDataCache = firmwareDataCache;
143 this.context = context; 142 this.context = context;
@@ -146,13 +145,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -146,13 +145,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
146 145
147 @PostConstruct 146 @PostConstruct
148 public void init() { 147 public void init() {
149 - this.context.getScheduler().scheduleAtFixedRate(this::checkInactivityAndReportActivity, new Random().nextInt((int) config.getSessionReportTimeout()), config.getSessionReportTimeout(), TimeUnit.MILLISECONDS);  
150 - this.executorRegistered = Executors.newFixedThreadPool(this.config.getRegisteredPoolSize(),  
151 - new NamedThreadFactory(String.format("LwM2M %s channel registered", SERVICE_CHANNEL)));  
152 - this.executorUpdateRegistered = Executors.newFixedThreadPool(this.config.getUpdateRegisteredPoolSize(),  
153 - new NamedThreadFactory(String.format("LwM2M %s channel update registered", SERVICE_CHANNEL)));  
154 - this.executorUnRegistered = Executors.newFixedThreadPool(this.config.getUnRegisteredPoolSize(),  
155 - new NamedThreadFactory(String.format("LwM2M %s channel un registered", SERVICE_CHANNEL))); 148 + this.context.getScheduler().scheduleAtFixedRate(this::reportActivity, new Random().nextInt((int) config.getSessionReportTimeout()), config.getSessionReportTimeout(), TimeUnit.MILLISECONDS);
  149 + this.registrationExecutor = ThingsBoardExecutors.newWorkStealingPool(this.config.getRegisteredPoolSize(), "LwM2M registration");
  150 + this.updateRegistrationExecutor = ThingsBoardExecutors.newWorkStealingPool(this.config.getUpdateRegisteredPoolSize(), "LwM2M update registration");
  151 + this.unregistrationExecutor = ThingsBoardExecutors.newWorkStealingPool(this.config.getUnRegisteredPoolSize(), "LwM2M unregistration");
156 this.converter = LwM2mValueConverterImpl.getInstance(); 152 this.converter = LwM2mValueConverterImpl.getInstance();
157 } 153 }
158 154
@@ -171,14 +167,13 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -171,14 +167,13 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
171 * @param previousObservations - may be null 167 * @param previousObservations - may be null
172 */ 168 */
173 public void onRegistered(Registration registration, Collection<Observation> previousObservations) { 169 public void onRegistered(Registration registration, Collection<Observation> previousObservations) {
174 - executorRegistered.submit(() -> { 170 + registrationExecutor.submit(() -> {
175 try { 171 try {
176 log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); 172 log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId());
177 - LwM2mClient lwM2MClient = this.lwM2mClientContext.updateInSessionsLwM2MClient(registration); 173 + LwM2mClient lwM2MClient = this.clientContext.registerOrUpdate(registration);
178 if (lwM2MClient != null) { 174 if (lwM2MClient != null) {
179 - SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration); 175 + SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient);
180 if (sessionInfo != null) { 176 if (sessionInfo != null) {
181 - this.initLwM2mClient(lwM2MClient, sessionInfo);  
182 transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); 177 transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo));
183 transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN), null); 178 transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN), null);
184 transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), null); 179 transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), null);
@@ -204,24 +199,18 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -204,24 +199,18 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
204 * @param registration - Registration LwM2M Client 199 * @param registration - Registration LwM2M Client
205 */ 200 */
206 public void updatedReg(Registration registration) { 201 public void updatedReg(Registration registration) {
207 - executorUpdateRegistered.submit(() -> { 202 + updateRegistrationExecutor.submit(() -> {
208 try { 203 try {
209 - SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration);  
210 - if (sessionInfo != null) {  
211 - this.checkInactivity(sessionInfo);  
212 - LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2MClient(sessionInfo);  
213 - if (lwM2MClient.getDeviceId() == null && lwM2MClient.getProfileId() == null) {  
214 - initLwM2mClient(lwM2MClient, sessionInfo);  
215 - } else {  
216 - if (registration.getBindingMode().useQueueMode()) {  
217 - LwM2mQueuedRequest request;  
218 - while ((request = lwM2MClient.getQueuedRequests().poll()) != null) {  
219 - request.send();  
220 - } 204 + LwM2mClient client = clientContext.getOrRegister(registration);
  205 + if (client != null && client.getSession() != null) {
  206 + SessionInfoProto sessionInfo = client.getSession();
  207 + this.reportActivityAndRegister(sessionInfo);
  208 + if (registration.getBindingMode().useQueueMode()) {
  209 + LwM2mQueuedRequest request;
  210 + while ((request = client.getQueuedRequests().poll()) != null) {
  211 + request.send();
221 } 212 }
222 } 213 }
223 -  
224 - log.info("Client: [{}] updatedReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType());  
225 } else { 214 } else {
226 log.error("Client: [{}] updatedReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); 215 log.error("Client: [{}] updatedReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null);
227 } 216 }
@@ -237,7 +226,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -237,7 +226,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
237 * !!! Warn: if have not finishing unReg, then this operation will be finished on next Client`s connect 226 * !!! Warn: if have not finishing unReg, then this operation will be finished on next Client`s connect
238 */ 227 */
239 public void unReg(Registration registration, Collection<Observation> observations) { 228 public void unReg(Registration registration, Collection<Observation> observations) {
240 - executorUnRegistered.submit(() -> { 229 + unregistrationExecutor.submit(() -> {
241 try { 230 try {
242 this.setCancelObservations(registration); 231 this.setCancelObservations(registration);
243 this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId()); 232 this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId());
@@ -248,22 +237,12 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -248,22 +237,12 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
248 }); 237 });
249 } 238 }
250 239
251 - private void initLwM2mClient(LwM2mClient lwM2MClient, SessionInfoProto sessionInfo) {  
252 - lwM2MClient.setDeviceId(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB()));  
253 - lwM2MClient.setProfileId(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));  
254 - lwM2MClient.setDeviceName(sessionInfo.getDeviceName());  
255 - lwM2MClient.setDeviceProfileName(sessionInfo.getDeviceType());  
256 - }  
257 -  
258 private void closeClientSession(Registration registration) { 240 private void closeClientSession(Registration registration) {
259 - SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration); 241 + SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registration);
260 if (sessionInfo != null) { 242 if (sessionInfo != null) {
261 transportService.deregisterSession(sessionInfo); 243 transportService.deregisterSession(sessionInfo);
262 this.doCloseSession(sessionInfo); 244 this.doCloseSession(sessionInfo);
263 - lwM2mClientContext.delRemoveSessionAndListener(registration.getId());  
264 - if (lwM2mClientContext.getProfiles().size() > 0) {  
265 - this.syncSessionsAndProfiles();  
266 - } 245 + clientContext.removeClientByRegistrationId(registration.getId());
267 log.info("Client close session: [{}] unReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType()); 246 log.info("Client close session: [{}] unReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType());
268 } else { 247 } else {
269 log.error("Client close session: [{}] unReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); 248 log.error("Client close session: [{}] unReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null);
@@ -331,12 +310,12 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -331,12 +310,12 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
331 */ 310 */
332 @Override 311 @Override
333 public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) { 312 public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) {
334 - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); 313 + LwM2mClient lwM2MClient = clientContext.getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
335 if (msg.getSharedUpdatedCount() > 0) { 314 if (msg.getSharedUpdatedCount() > 0) {
336 msg.getSharedUpdatedList().forEach(tsKvProto -> { 315 msg.getSharedUpdatedList().forEach(tsKvProto -> {
337 String pathName = tsKvProto.getKv().getKey(); 316 String pathName = tsKvProto.getKv().getKey();
338 String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); 317 String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName);
339 - Object valueNew = LwM2mTransportServerHelper.getValueFromKvProto(tsKvProto.getKv()); 318 + Object valueNew = getValueFromKvProto(tsKvProto.getKv());
340 //TODO: react on change of the firmware name. 319 //TODO: react on change of the firmware name.
341 if (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) { 320 if (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) {
342 this.getInfoFirmwareUpdate(lwM2MClient); 321 this.getInfoFirmwareUpdate(lwM2MClient);
@@ -363,7 +342,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -363,7 +342,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
363 } else if (msg.getSharedDeletedCount() > 0) { 342 } else if (msg.getSharedDeletedCount() > 0) {
364 msg.getSharedUpdatedList().forEach(tsKvProto -> { 343 msg.getSharedUpdatedList().forEach(tsKvProto -> {
365 String pathName = tsKvProto.getKv().getKey(); 344 String pathName = tsKvProto.getKv().getKey();
366 - Object valueNew = LwM2mTransportServerHelper.getValueFromKvProto(tsKvProto.getKv()); 345 + Object valueNew = getValueFromKvProto(tsKvProto.getKv());
367 if (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) { 346 if (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) {
368 lwM2MClient.getFrUpdate().setCurrentFwVersion((String) valueNew); 347 lwM2MClient.getFrUpdate().setCurrentFwVersion((String) valueNew);
369 } 348 }
@@ -378,45 +357,34 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -378,45 +357,34 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
378 */ 357 */
379 @Override 358 @Override
380 public void onDeviceProfileUpdate(SessionInfoProto sessionInfo, DeviceProfile deviceProfile) { 359 public void onDeviceProfileUpdate(SessionInfoProto sessionInfo, DeviceProfile deviceProfile) {
381 - Set<String> registrationIds = lwM2mClientContext.getLwM2mClients().entrySet()  
382 - .stream()  
383 - .filter(e -> e.getValue().getProfileId().equals(deviceProfile.getUuidId()))  
384 - .map(Map.Entry::getKey).sorted().collect(Collectors.toCollection(LinkedHashSet::new)); 360 + Set<LwM2mClient> clients = clientContext.getLwM2mClients()
  361 + .stream().filter(e -> e.getProfileId().equals(deviceProfile.getUuidId())).collect(Collectors.toSet());
  362 + clients.forEach(client -> client.onDeviceProfileUpdate(deviceProfile));
  363 + Set<String> registrationIds = clients.stream().map(LwM2mClient::getRegistration).map(Registration::getId).collect(Collectors.toSet());
385 if (registrationIds.size() > 0) { 364 if (registrationIds.size() > 0) {
386 - this.onDeviceUpdateChangeProfile(registrationIds, deviceProfile); 365 + this.onDeviceProfileUpdate(registrationIds, deviceProfile);
387 } 366 }
388 } 367 }
389 368
390 - /**  
391 - * @param sessionInfo -  
392 - * @param device -  
393 - * @param deviceProfileOpt -  
394 - */  
395 @Override 369 @Override
396 public void onDeviceUpdate(SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) { 370 public void onDeviceUpdate(SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) {
397 - Optional<String> registrationIdOpt = lwM2mClientContext.getLwM2mClients().entrySet().stream()  
398 - .filter(e -> device.getUuidId().equals(e.getValue().getDeviceId()))  
399 - .map(Map.Entry::getKey)  
400 - .findFirst();  
401 - registrationIdOpt.ifPresent(registrationId -> this.onDeviceUpdateLwM2MClient(registrationId, device, deviceProfileOpt)); 371 + //TODO: check, maybe device has multiple sessions/registrations? Is this possible according to the standard.
  372 + LwM2mClient client = clientContext.getClientByDeviceId(device.getUuidId());
  373 + if (client != null) {
  374 + this.onDeviceUpdate(client, device, deviceProfileOpt);
  375 + }
402 } 376 }
403 377
404 - /**  
405 - * @param resourceUpdateMsgOpt -  
406 - */  
407 @Override 378 @Override
408 public void onResourceUpdate(Optional<TransportProtos.ResourceUpdateMsg> resourceUpdateMsgOpt) { 379 public void onResourceUpdate(Optional<TransportProtos.ResourceUpdateMsg> resourceUpdateMsgOpt) {
409 String idVer = resourceUpdateMsgOpt.get().getResourceKey(); 380 String idVer = resourceUpdateMsgOpt.get().getResourceKey();
410 - lwM2mClientContext.getLwM2mClients().values().stream().forEach(e -> e.updateResourceModel(idVer, this.config.getModelProvider())); 381 + clientContext.getLwM2mClients().forEach(e -> e.updateResourceModel(idVer, this.config.getModelProvider()));
411 } 382 }
412 383
413 - /**  
414 - * @param resourceDeleteMsgOpt -  
415 - */  
416 @Override 384 @Override
417 public void onResourceDelete(Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt) { 385 public void onResourceDelete(Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt) {
418 String pathIdVer = resourceDeleteMsgOpt.get().getResourceKey(); 386 String pathIdVer = resourceDeleteMsgOpt.get().getResourceKey();
419 - lwM2mClientContext.getLwM2mClients().values().stream().forEach(e -> e.deleteResources(pathIdVer, this.config.getModelProvider())); 387 + clientContext.getLwM2mClients().forEach(e -> e.deleteResources(pathIdVer, this.config.getModelProvider()));
420 } 388 }
421 389
422 @Override 390 @Override
@@ -424,9 +392,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -424,9 +392,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
424 Lwm2mClientRpcRequest lwm2mClientRpcRequest = null; 392 Lwm2mClientRpcRequest lwm2mClientRpcRequest = null;
425 try { 393 try {
426 log.info("[{}] toDeviceRpcRequest", toDeviceRequest); 394 log.info("[{}] toDeviceRpcRequest", toDeviceRequest);
427 - Registration registration = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).getRegistration(); 395 + Registration registration = clientContext.getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).getRegistration();
428 lwm2mClientRpcRequest = this.getDeviceRpcRequest(toDeviceRequest, sessionInfo, registration); 396 lwm2mClientRpcRequest = this.getDeviceRpcRequest(toDeviceRequest, sessionInfo, registration);
429 - if (lwm2mClientRpcRequest != null && lwm2mClientRpcRequest.getErrorMsg() != null) { 397 + if (lwm2mClientRpcRequest.getErrorMsg() != null) {
430 lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); 398 lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name());
431 this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); 399 this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo);
432 } else { 400 } else {
@@ -446,13 +414,6 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -446,13 +414,6 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
446 } 414 }
447 } 415 }
448 416
449 - /**  
450 - * @param toDeviceRequest -  
451 - * @param sessionInfo -  
452 - * @param registration -  
453 - * @return  
454 - * @throws IllegalArgumentException  
455 - */  
456 private Lwm2mClientRpcRequest getDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest, 417 private Lwm2mClientRpcRequest getDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest,
457 SessionInfoProto sessionInfo, Registration registration) throws IllegalArgumentException { 418 SessionInfoProto sessionInfo, Registration registration) throws IllegalArgumentException {
458 Lwm2mClientRpcRequest lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(); 419 Lwm2mClientRpcRequest lwm2mClientRpcRequest = new Lwm2mClientRpcRequest();
@@ -590,35 +551,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -590,35 +551,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
590 } 551 }
591 552
592 /** 553 /**
593 - * This method is used to sync with sessions  
594 - * Removes a profile if not used in sessions  
595 - */  
596 - private void syncSessionsAndProfiles() {  
597 - Map<UUID, LwM2mClientProfile> profilesClone = lwM2mClientContext.getProfiles().entrySet()  
598 - .stream()  
599 - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));  
600 - profilesClone.forEach((k, v) -> {  
601 - String registrationId = lwM2mClientContext.getLwM2mClients().entrySet()  
602 - .stream()  
603 - .filter(e -> e.getValue().getProfileId().equals(k))  
604 - .findFirst()  
605 - .map(Map.Entry::getKey) // return the key of the matching entry if found  
606 - .orElse("");  
607 - if (registrationId.isEmpty()) {  
608 - lwM2mClientContext.getProfiles().remove(k);  
609 - }  
610 - });  
611 - }  
612 -  
613 - /**  
614 - * @param logMsg - text msg 554 + * @param logMsg - text msg
615 * @param registrationId - Id of Registration LwM2M Client 555 * @param registrationId - Id of Registration LwM2M Client
616 */ 556 */
617 @Override 557 @Override
618 public void sendLogsToThingsboard(String logMsg, String registrationId) { 558 public void sendLogsToThingsboard(String logMsg, String registrationId) {
619 - SessionInfoProto sessionInfo = this.getValidateSessionInfo(registrationId); 559 + SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registrationId);
620 if (logMsg != null && sessionInfo != null) { 560 if (logMsg != null && sessionInfo != null) {
621 - if(logMsg.length() > 1024){ 561 + if (logMsg.length() > 1024) {
622 logMsg = logMsg.substring(0, 1024); 562 logMsg = logMsg.substring(0, 1024);
623 } 563 }
624 this.helper.sendParametersOnThingsboardTelemetry(this.helper.getKvLogyToThingsboard(logMsg), sessionInfo); 564 this.helper.sendParametersOnThingsboardTelemetry(this.helper.getKvLogyToThingsboard(logMsg), sessionInfo);
@@ -638,8 +578,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -638,8 +578,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
638 * @param lwM2MClient - object with All parameters off client 578 * @param lwM2MClient - object with All parameters off client
639 */ 579 */
640 private void initLwM2mFromClientValue(Registration registration, LwM2mClient lwM2MClient) { 580 private void initLwM2mFromClientValue(Registration registration, LwM2mClient lwM2MClient) {
641 - LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration);  
642 - Set<String> clientObjects = lwM2mClientContext.getSupportedIdVerInClient(registration); 581 + LwM2mClientProfile lwM2MClientProfile = clientContext.getProfile(registration);
  582 + Set<String> clientObjects = clientContext.getSupportedIdVerInClient(registration);
643 if (clientObjects != null && clientObjects.size() > 0) { 583 if (clientObjects != null && clientObjects.size() > 0) {
644 if (LWM2M_STRATEGY_2 == LwM2mTransportUtil.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { 584 if (LWM2M_STRATEGY_2 == LwM2mTransportUtil.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) {
645 // #2 585 // #2
@@ -693,7 +633,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -693,7 +633,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
693 * @param path - resource 633 * @param path - resource
694 */ 634 */
695 private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) { 635 private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) {
696 - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); 636 + LwM2mClient lwM2MClient = clientContext.getOrRegister(registration);
697 if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.config 637 if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.config
698 .getModelProvider())) { 638 .getModelProvider())) {
699 if (FR_PATH_RESOURCE_VER_ID.equals(convertPathFromIdVerToObjectId(path)) && 639 if (FR_PATH_RESOURCE_VER_ID.equals(convertPathFromIdVerToObjectId(path)) &&
@@ -730,7 +670,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -730,7 +670,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
730 private void updateAttrTelemetry(Registration registration, Set<String> paths) { 670 private void updateAttrTelemetry(Registration registration, Set<String> paths) {
731 try { 671 try {
732 ResultsAddKeyValueProto results = getParametersFromProfile(registration, paths); 672 ResultsAddKeyValueProto results = getParametersFromProfile(registration, paths);
733 - SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration); 673 + SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registration);
734 if (results != null && sessionInfo != null) { 674 if (results != null && sessionInfo != null) {
735 if (results.getResultAttributes().size() > 0) { 675 if (results.getResultAttributes().size() > 0) {
736 this.helper.sendParametersOnThingsboardAttribute(results.getResultAttributes(), sessionInfo); 676 this.helper.sendParametersOnThingsboardAttribute(results.getResultAttributes(), sessionInfo);
@@ -752,7 +692,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -752,7 +692,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
752 */ 692 */
753 private void initReadAttrTelemetryObserveToClient(Registration registration, LwM2mClient lwM2MClient, 693 private void initReadAttrTelemetryObserveToClient(Registration registration, LwM2mClient lwM2MClient,
754 LwM2mTypeOper typeOper, Set<String> clientObjects) { 694 LwM2mTypeOper typeOper, Set<String> clientObjects) {
755 - LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); 695 + LwM2mClientProfile lwM2MClientProfile = clientContext.getProfile(registration);
756 Set<String> result = null; 696 Set<String> result = null;
757 ConcurrentHashMap<String, Object> params = null; 697 ConcurrentHashMap<String, Object> params = null;
758 if (READ.equals(typeOper)) { 698 if (READ.equals(typeOper)) {
@@ -784,8 +724,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -784,8 +724,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
784 lwM2MClient.getPendingReadRequests().addAll(pathSend); 724 lwM2MClient.getPendingReadRequests().addAll(pathSend);
785 ConcurrentHashMap<String, Object> finalParams = params; 725 ConcurrentHashMap<String, Object> finalParams = params;
786 pathSend.forEach(target -> { 726 pathSend.forEach(target -> {
787 - lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, ContentFormat.TLV.getName(),  
788 - finalParams != null ? finalParams.get(target) : null, this.config.getTimeout(), null); 727 + lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, ContentFormat.TLV.getName(),
  728 + finalParams != null ? finalParams.get(target) : null, this.config.getTimeout(), null);
789 }); 729 });
790 if (OBSERVE.equals(typeOper)) { 730 if (OBSERVE.equals(typeOper)) {
791 lwM2MClient.initReadValue(this, null); 731 lwM2MClient.initReadValue(this, null);
@@ -801,23 +741,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -801,23 +741,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
801 return pathAttributes; 741 return pathAttributes;
802 } 742 }
803 743
804 - /**  
805 - * Update parameters device in LwM2MClient  
806 - * If new deviceProfile != old deviceProfile => update deviceProfile  
807 - *  
808 - * @param registrationId -  
809 - * @param device -  
810 - */  
811 - private void onDeviceUpdateLwM2MClient(String registrationId, Device device, Optional<DeviceProfile> deviceProfileOpt) {  
812 - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClients().get(registrationId);  
813 - lwM2MClient.setDeviceName(device.getName());  
814 - if (!lwM2MClient.getProfileId().equals(device.getDeviceProfileId().getId())) {  
815 - Set<String> registrationIds = new HashSet<>();  
816 - registrationIds.add(registrationId);  
817 - deviceProfileOpt.ifPresent(deviceProfile -> this.onDeviceUpdateChangeProfile(registrationIds, deviceProfile));  
818 - }  
819 -  
820 - lwM2MClient.setProfileId(device.getDeviceProfileId().getId()); 744 + private void onDeviceUpdate(LwM2mClient lwM2MClient, Device device, Optional<DeviceProfile> deviceProfileOpt) {
  745 + deviceProfileOpt.ifPresent(deviceProfile -> this.onDeviceProfileUpdate(Collections.singleton(lwM2MClient.getRegistration().getId()), deviceProfile));
  746 + lwM2MClient.onDeviceUpdate(device, deviceProfileOpt);
821 } 747 }
822 748
823 /** 749 /**
@@ -830,7 +756,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -830,7 +756,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
830 private ResultsAddKeyValueProto getParametersFromProfile(Registration registration, Set<String> path) { 756 private ResultsAddKeyValueProto getParametersFromProfile(Registration registration, Set<String> path) {
831 if (path != null && path.size() > 0) { 757 if (path != null && path.size() > 0) {
832 ResultsAddKeyValueProto results = new ResultsAddKeyValueProto(); 758 ResultsAddKeyValueProto results = new ResultsAddKeyValueProto();
833 - LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); 759 + LwM2mClientProfile lwM2MClientProfile = clientContext.getProfile(registration);
834 List<TransportProtos.KeyValueProto> resultAttributes = new ArrayList<>(); 760 List<TransportProtos.KeyValueProto> resultAttributes = new ArrayList<>();
835 lwM2MClientProfile.getPostAttributeProfile().forEach(pathIdVer -> { 761 lwM2MClientProfile.getPostAttributeProfile().forEach(pathIdVer -> {
836 if (path.contains(pathIdVer.getAsString())) { 762 if (path.contains(pathIdVer.getAsString())) {
@@ -861,8 +787,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -861,8 +787,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
861 } 787 }
862 788
863 private TransportProtos.KeyValueProto getKvToThingsboard(String pathIdVer, Registration registration) { 789 private TransportProtos.KeyValueProto getKvToThingsboard(String pathIdVer, Registration registration) {
864 - LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(null, registration.getId());  
865 - JsonObject names = lwM2mClientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile(); 790 + LwM2mClient lwM2MClient = this.clientContext.getClientByRegistrationId(registration.getId());
  791 + JsonObject names = clientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile();
866 if (names != null && names.has(pathIdVer)) { 792 if (names != null && names.has(pathIdVer)) {
867 String resourceName = names.get(pathIdVer).getAsString(); 793 String resourceName = names.get(pathIdVer).getAsString();
868 if (resourceName != null && !resourceName.isEmpty()) { 794 if (resourceName != null && !resourceName.isEmpty()) {
@@ -960,9 +886,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -960,9 +886,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
960 * @param registrationIds - 886 * @param registrationIds -
961 * @param deviceProfile - 887 * @param deviceProfile -
962 */ 888 */
963 - private void onDeviceUpdateChangeProfile(Set<String> registrationIds, DeviceProfile deviceProfile) {  
964 - LwM2mClientProfile lwM2MClientProfileOld = lwM2mClientContext.getProfiles().get(deviceProfile.getUuidId()).clone();  
965 - if (lwM2mClientContext.addUpdateProfileParameters(deviceProfile)) { 889 + private void onDeviceProfileUpdate(Set<String> registrationIds, DeviceProfile deviceProfile) {
  890 + LwM2mClientProfile lwM2MClientProfileOld = clientContext.getProfiles().get(deviceProfile.getUuidId()).clone();
  891 + if (clientContext.toClientProfile(deviceProfile) != null) {
966 // #1 892 // #1
967 JsonArray attributeOld = lwM2MClientProfileOld.getPostAttributeProfile(); 893 JsonArray attributeOld = lwM2MClientProfileOld.getPostAttributeProfile();
968 Set<String> attributeSetOld = convertJsonArrayToSet(attributeOld); 894 Set<String> attributeSetOld = convertJsonArrayToSet(attributeOld);
@@ -972,7 +898,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -972,7 +898,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
972 JsonObject keyNameOld = lwM2MClientProfileOld.getPostKeyNameProfile(); 898 JsonObject keyNameOld = lwM2MClientProfileOld.getPostKeyNameProfile();
973 JsonObject attributeLwm2mOld = lwM2MClientProfileOld.getPostAttributeLwm2mProfile(); 899 JsonObject attributeLwm2mOld = lwM2MClientProfileOld.getPostAttributeLwm2mProfile();
974 900
975 - LwM2mClientProfile lwM2MClientProfileNew = lwM2mClientContext.getProfiles().get(deviceProfile.getUuidId()); 901 + LwM2mClientProfile lwM2MClientProfileNew = clientContext.getProfiles().get(deviceProfile.getUuidId());
976 JsonArray attributeNew = lwM2MClientProfileNew.getPostAttributeProfile(); 902 JsonArray attributeNew = lwM2MClientProfileNew.getPostAttributeProfile();
977 Set<String> attributeSetNew = convertJsonArrayToSet(attributeNew); 903 Set<String> attributeSetNew = convertJsonArrayToSet(attributeNew);
978 JsonArray telemetryNew = lwM2MClientProfileNew.getPostTelemetryProfile(); 904 JsonArray telemetryNew = lwM2MClientProfileNew.getPostTelemetryProfile();
@@ -1018,7 +944,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1018,7 +944,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1018 if (sendAttrToThingsboard.getPathPostParametersAdd().size() > 0) { 944 if (sendAttrToThingsboard.getPathPostParametersAdd().size() > 0) {
1019 // update value in Resources 945 // update value in Resources
1020 registrationIds.forEach(registrationId -> { 946 registrationIds.forEach(registrationId -> {
1021 - Registration registration = lwM2mClientContext.getRegistration(registrationId); 947 + Registration registration = clientContext.getRegistration(registrationId);
1022 this.readObserveFromProfile(registration, sendAttrToThingsboard.getPathPostParametersAdd(), READ); 948 this.readObserveFromProfile(registration, sendAttrToThingsboard.getPathPostParametersAdd(), READ);
1023 // send attr/telemetry to tingsboard for new path 949 // send attr/telemetry to tingsboard for new path
1024 this.updateAttrTelemetry(registration, sendAttrToThingsboard.getPathPostParametersAdd()); 950 this.updateAttrTelemetry(registration, sendAttrToThingsboard.getPathPostParametersAdd());
@@ -1046,7 +972,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1046,7 +972,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1046 ResultsAnalyzerParameters postObserveAnalyzer = this.getAnalyzerParameters(sendObserveToClientOld.getPathPostParametersAdd(), sendObserveToClientNew.getPathPostParametersAdd()); 972 ResultsAnalyzerParameters postObserveAnalyzer = this.getAnalyzerParameters(sendObserveToClientOld.getPathPostParametersAdd(), sendObserveToClientNew.getPathPostParametersAdd());
1047 // send Request observe to Client 973 // send Request observe to Client
1048 registrationIds.forEach(registrationId -> { 974 registrationIds.forEach(registrationId -> {
1049 - Registration registration = lwM2mClientContext.getRegistration(registrationId); 975 + Registration registration = clientContext.getRegistration(registrationId);
1050 if (postObserveAnalyzer.getPathPostParametersAdd().size() > 0) { 976 if (postObserveAnalyzer.getPathPostParametersAdd().size() > 0) {
1051 this.readObserveFromProfile(registration, postObserveAnalyzer.getPathPostParametersAdd(), OBSERVE); 977 this.readObserveFromProfile(registration, postObserveAnalyzer.getPathPostParametersAdd(), OBSERVE);
1052 } 978 }
@@ -1151,8 +1077,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1151,8 +1077,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1151 // #6.2 1077 // #6.2
1152 if (analyzerParameters.getPathPostParametersAdd().size() > 0) { 1078 if (analyzerParameters.getPathPostParametersAdd().size() > 0) {
1153 registrationIds.forEach(registrationId -> { 1079 registrationIds.forEach(registrationId -> {
1154 - Registration registration = this.lwM2mClientContext.getRegistration(registrationId);  
1155 - Set<String> clientObjects = lwM2mClientContext.getSupportedIdVerInClient(registration); 1080 + Registration registration = this.clientContext.getRegistration(registrationId);
  1081 + Set<String> clientObjects = clientContext.getSupportedIdVerInClient(registration);
1156 Set<String> pathSend = analyzerParameters.getPathPostParametersAdd().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) 1082 Set<String> pathSend = analyzerParameters.getPathPostParametersAdd().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1]))
1157 .collect(Collectors.toUnmodifiableSet()); 1083 .collect(Collectors.toUnmodifiableSet());
1158 if (!pathSend.isEmpty()) { 1084 if (!pathSend.isEmpty()) {
@@ -1165,8 +1091,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1165,8 +1091,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1165 // #6.2 1091 // #6.2
1166 if (analyzerParameters.getPathPostParametersDel().size() > 0) { 1092 if (analyzerParameters.getPathPostParametersDel().size() > 0) {
1167 registrationIds.forEach(registrationId -> { 1093 registrationIds.forEach(registrationId -> {
1168 - Registration registration = this.lwM2mClientContext.getRegistration(registrationId);  
1169 - Set<String> clientObjects = lwM2mClientContext.getSupportedIdVerInClient(registration); 1094 + Registration registration = this.clientContext.getRegistration(registrationId);
  1095 + Set<String> clientObjects = clientContext.getSupportedIdVerInClient(registration);
1170 Set<String> pathSend = analyzerParameters.getPathPostParametersDel().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) 1096 Set<String> pathSend = analyzerParameters.getPathPostParametersDel().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1]))
1171 .collect(Collectors.toUnmodifiableSet()); 1097 .collect(Collectors.toUnmodifiableSet());
1172 if (!pathSend.isEmpty()) { 1098 if (!pathSend.isEmpty()) {
@@ -1184,7 +1110,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1184,7 +1110,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1184 } 1110 }
1185 1111
1186 private void cancelObserveFromProfile(Registration registration, Set<String> paramAnallyzer) { 1112 private void cancelObserveFromProfile(Registration registration, Set<String> paramAnallyzer) {
1187 - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); 1113 + LwM2mClient lwM2MClient = clientContext.getOrRegister(registration);
1188 paramAnallyzer.forEach(pathIdVer -> { 1114 paramAnallyzer.forEach(pathIdVer -> {
1189 if (this.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer) != null) { 1115 if (this.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer) != null) {
1190 lwM2mTransportRequest.sendAllRequest(registration, pathIdVer, OBSERVE_CANCEL, null, 1116 lwM2mTransportRequest.sendAllRequest(registration, pathIdVer, OBSERVE_CANCEL, null,
@@ -1224,8 +1150,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1224,8 +1150,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1224 * @return - 1150 * @return -
1225 */ 1151 */
1226 private String getPresentPathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) { 1152 private String getPresentPathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) {
1227 - LwM2mClientProfile profile = lwM2mClientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));  
1228 - LwM2mClient lwM2mClient = lwM2mClientContext.getLwM2MClient(sessionInfo); 1153 + LwM2mClientProfile profile = clientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));
  1154 + LwM2mClient lwM2mClient = clientContext.getClient(sessionInfo);
1229 return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() 1155 return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream()
1230 .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModel(lwM2mClient, e.getKey(), false)).findFirst().map(Map.Entry::getKey) 1156 .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModel(lwM2mClient, e.getKey(), false)).findFirst().map(Map.Entry::getKey)
1231 .orElse(null); 1157 .orElse(null);
@@ -1244,7 +1170,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1244,7 +1170,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1244 try { 1170 try {
1245 List<TransportProtos.TsKvProto> tsKvProtos = attributesResponse.getSharedAttributeListList(); 1171 List<TransportProtos.TsKvProto> tsKvProtos = attributesResponse.getSharedAttributeListList();
1246 1172
1247 - this.updateAttriuteFromThingsboard(tsKvProtos, sessionInfo); 1173 + this.updateAttributeFromThingsboard(tsKvProtos, sessionInfo);
1248 } catch (Exception e) { 1174 } catch (Exception e) {
1249 log.error(String.valueOf(e)); 1175 log.error(String.valueOf(e));
1250 } 1176 }
@@ -1260,8 +1186,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1260,8 +1186,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1260 * @param tsKvProtos 1186 * @param tsKvProtos
1261 * @param sessionInfo 1187 * @param sessionInfo
1262 */ 1188 */
1263 - public void updateAttriuteFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) {  
1264 - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo); 1189 + public void updateAttributeFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) {
  1190 + LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo);
1265 tsKvProtos.forEach(tsKvProto -> { 1191 tsKvProtos.forEach(tsKvProto -> {
1266 String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, tsKvProto.getKv().getKey()); 1192 String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, tsKvProto.getKv().getKey());
1267 if (pathIdVer != null) { 1193 if (pathIdVer != null) {
@@ -1276,7 +1202,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1276,7 +1202,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1276 // #2.1 1202 // #2.1
1277 lwM2MClient.getDelayedRequests().forEach((pathIdVer, tsKvProto) -> { 1203 lwM2MClient.getDelayedRequests().forEach((pathIdVer, tsKvProto) -> {
1278 this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), 1204 this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer),
1279 - this.helper.getValueFromKvProto(tsKvProto.getKv()), pathIdVer); 1205 + getValueFromKvProto(tsKvProto.getKv()), pathIdVer);
1280 }); 1206 });
1281 } 1207 }
1282 1208
@@ -1284,30 +1210,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1284,30 +1210,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1284 * @param lwM2MClient - 1210 * @param lwM2MClient -
1285 * @return SessionInfoProto - 1211 * @return SessionInfoProto -
1286 */ 1212 */
1287 - private SessionInfoProto getNewSessionInfoProto(LwM2mClient lwM2MClient) { 1213 + private SessionInfoProto getSessionInfoOrCloseSession(LwM2mClient lwM2MClient) {
1288 if (lwM2MClient != null) { 1214 if (lwM2MClient != null) {
1289 - TransportProtos.ValidateDeviceCredentialsResponseMsg msg = lwM2MClient.getCredentialsResponse();  
1290 - if (msg == null) {  
1291 - log.error("[{}] [{}]", lwM2MClient.getEndpoint(), CLIENT_NOT_AUTHORIZED); 1215 + SessionInfoProto sessionInfoProto = lwM2MClient.getSession();
  1216 + if (sessionInfoProto == null) {
  1217 + log.info("[{}] [{}]", lwM2MClient.getEndpoint(), CLIENT_NOT_AUTHORIZED);
1292 this.closeClientSession(lwM2MClient.getRegistration()); 1218 this.closeClientSession(lwM2MClient.getRegistration());
1293 - return null;  
1294 - } else {  
1295 - return SessionInfoProto.newBuilder()  
1296 - .setNodeId(this.context.getNodeId())  
1297 - .setSessionIdMSB(lwM2MClient.getSessionId().getMostSignificantBits())  
1298 - .setSessionIdLSB(lwM2MClient.getSessionId().getLeastSignificantBits())  
1299 - .setDeviceIdMSB(msg.getDeviceInfo().getDeviceIdMSB())  
1300 - .setDeviceIdLSB(msg.getDeviceInfo().getDeviceIdLSB())  
1301 - .setTenantIdMSB(msg.getDeviceInfo().getTenantIdMSB())  
1302 - .setTenantIdLSB(msg.getDeviceInfo().getTenantIdLSB())  
1303 - .setCustomerIdMSB(msg.getDeviceInfo().getCustomerIdMSB())  
1304 - .setCustomerIdLSB(msg.getDeviceInfo().getCustomerIdLSB())  
1305 - .setDeviceName(msg.getDeviceInfo().getDeviceName())  
1306 - .setDeviceType(msg.getDeviceInfo().getDeviceType())  
1307 - .setDeviceProfileIdLSB(msg.getDeviceInfo().getDeviceProfileIdLSB())  
1308 - .setDeviceProfileIdMSB(msg.getDeviceInfo().getDeviceProfileIdMSB())  
1309 - .build();  
1310 } 1219 }
  1220 + return sessionInfoProto;
1311 } 1221 }
1312 return null; 1222 return null;
1313 } 1223 }
@@ -1316,18 +1226,16 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1316,18 +1226,16 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1316 * @param registration - Registration LwM2M Client 1226 * @param registration - Registration LwM2M Client
1317 * @return - sessionInfo after access connect client 1227 * @return - sessionInfo after access connect client
1318 */ 1228 */
1319 - private SessionInfoProto getValidateSessionInfo(Registration registration) {  
1320 - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);  
1321 - return getNewSessionInfoProto(lwM2MClient); 1229 + private SessionInfoProto getSessionInfoOrCloseSession(Registration registration) {
  1230 + return getSessionInfoOrCloseSession(clientContext.getOrRegister(registration));
1322 } 1231 }
1323 1232
1324 /** 1233 /**
1325 * @param registrationId - 1234 * @param registrationId -
1326 * @return - 1235 * @return -
1327 */ 1236 */
1328 - private SessionInfoProto getValidateSessionInfo(String registrationId) {  
1329 - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(null, registrationId);  
1330 - return lwM2MClient != null ? this.getNewSessionInfoProto(lwM2MClient) : null; 1237 + private SessionInfoProto getSessionInfoOrCloseSession(String registrationId) {
  1238 + return getSessionInfoOrCloseSession(clientContext.getClientByRegistrationId(registrationId));
1331 } 1239 }
1332 1240
1333 /** 1241 /**
@@ -1335,14 +1243,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1335,14 +1243,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1335 * 1243 *
1336 * @param sessionInfo - 1244 * @param sessionInfo -
1337 */ 1245 */
1338 - private void checkInactivity(SessionInfoProto sessionInfo) {  
1339 - if (transportService.reportActivity(sessionInfo) == null) { 1246 + private void reportActivityAndRegister(SessionInfoProto sessionInfo) {
  1247 + if (sessionInfo != null && transportService.reportActivity(sessionInfo) == null) {
1340 transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); 1248 transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo));
1341 } 1249 }
1342 } 1250 }
1343 1251
1344 - private void checkInactivityAndReportActivity() {  
1345 - lwM2mClientContext.getLwM2mClients().forEach((key, value) -> this.checkInactivity(this.getValidateSessionInfo(key))); 1252 + private void reportActivity() {
  1253 + clientContext.getLwM2mClients().forEach(client -> reportActivityAndRegister(client.getSession()));
1346 } 1254 }
1347 1255
1348 /** 1256 /**
@@ -1356,7 +1264,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1356,7 +1264,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1356 * @param lwM2MClient - LwM2M Client 1264 * @param lwM2MClient - LwM2M Client
1357 */ 1265 */
1358 public void putDelayedUpdateResourcesThingsboard(LwM2mClient lwM2MClient) { 1266 public void putDelayedUpdateResourcesThingsboard(LwM2mClient lwM2MClient) {
1359 - SessionInfoProto sessionInfo = this.getValidateSessionInfo(lwM2MClient.getRegistration()); 1267 + SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient);
1360 if (sessionInfo != null) { 1268 if (sessionInfo != null) {
1361 //#1.1 1269 //#1.1
1362 ConcurrentMap<String, String> keyNamesMap = this.getNamesFromProfileForSharedAttributes(lwM2MClient); 1270 ConcurrentMap<String, String> keyNamesMap = this.getNamesFromProfileForSharedAttributes(lwM2MClient);
@@ -1374,7 +1282,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1374,7 +1282,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1374 } 1282 }
1375 1283
1376 public void getInfoFirmwareUpdate(LwM2mClient lwM2MClient) { 1284 public void getInfoFirmwareUpdate(LwM2mClient lwM2MClient) {
1377 - SessionInfoProto sessionInfo = this.getValidateSessionInfo(lwM2MClient.getRegistration()); 1285 + SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient);
1378 if (sessionInfo != null) { 1286 if (sessionInfo != null) {
1379 TransportProtos.GetFirmwareRequestMsg getFirmwareRequestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder() 1287 TransportProtos.GetFirmwareRequestMsg getFirmwareRequestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder()
1380 .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) 1288 .setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
@@ -1415,7 +1323,6 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1415,7 +1323,6 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1415 } 1323 }
1416 1324
1417 /** 1325 /**
1418 - *  
1419 * @param lwM2MClient - 1326 * @param lwM2MClient -
1420 */ 1327 */
1421 public void updateFirmwareClient(LwM2mClient lwM2MClient) { 1328 public void updateFirmwareClient(LwM2mClient lwM2MClient) {
@@ -1441,7 +1348,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @@ -1441,7 +1348,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
1441 */ 1348 */
1442 private ConcurrentMap<String, String> getNamesFromProfileForSharedAttributes(LwM2mClient lwM2MClient) { 1349 private ConcurrentMap<String, String> getNamesFromProfileForSharedAttributes(LwM2mClient lwM2MClient) {
1443 1350
1444 - LwM2mClientProfile profile = lwM2mClientContext.getProfile(lwM2MClient.getProfileId()); 1351 + LwM2mClientProfile profile = clientContext.getProfile(lwM2MClient.getProfileId());
1445 return new Gson().fromJson(profile.getPostKeyNameProfile().toString(), 1352 return new Gson().fromJson(profile.getPostKeyNameProfile().toString(),
1446 new TypeToken<ConcurrentHashMap<String, String>>() { 1353 new TypeToken<ConcurrentHashMap<String, String>>() {
1447 }.getType()); 1354 }.getType());
@@ -115,7 +115,7 @@ public class LwM2mTransportRequest { @@ -115,7 +115,7 @@ public class LwM2mTransportRequest {
115 String target = convertPathFromIdVerToObjectId(targetIdVer); 115 String target = convertPathFromIdVerToObjectId(targetIdVer);
116 DownlinkRequest request = null; 116 DownlinkRequest request = null;
117 ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT; 117 ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT;
118 - LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(registration, null); 118 + LwM2mClient lwM2MClient = this.lwM2mClientContext.getOrRegister(registration);
119 LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null; 119 LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null;
120 if (!OBSERVE_READ_ALL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && lwM2MClient != null) { 120 if (!OBSERVE_READ_ALL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && lwM2MClient != null) {
121 if (lwM2MClient.isValidObjectVersion(targetIdVer)) { 121 if (lwM2MClient.isValidObjectVersion(targetIdVer)) {
@@ -183,7 +183,6 @@ public class LwM2mTransportUtil { @@ -183,7 +183,6 @@ public class LwM2mTransportUtil {
183 } 183 }
184 184
185 public static final String EVENT_AWAKE = "AWAKE"; 185 public static final String EVENT_AWAKE = "AWAKE";
186 - public static final String SERVICE_CHANNEL = "SERVICE";  
187 public static final String RESPONSE_CHANNEL = "RESP"; 186 public static final String RESPONSE_CHANNEL = "RESP";
188 187
189 public static boolean equalsResourceValue(Object valueOld, Object valueNew, ResourceModel.Type type, LwM2mPath resourcePath) throws CodecException { 188 public static boolean equalsResourceValue(Object valueOld, Object valueNew, ResourceModel.Type type, LwM2mPath resourcePath) throws CodecException {
@@ -249,7 +248,7 @@ public class LwM2mTransportUtil { @@ -249,7 +248,7 @@ public class LwM2mTransportUtil {
249 * "/3_1.0/0": {"gt": 17}, 248 * "/3_1.0/0": {"gt": 17},
250 * "/3_1.0/0/9": {"pmax": 45}, "/3_1.2": {ver": "3_1.2"}} 249 * "/3_1.0/0/9": {"pmax": 45}, "/3_1.2": {ver": "3_1.2"}}
251 */ 250 */
252 - public static LwM2mClientProfile getLwM2MClientProfileFromThingsboard(DeviceProfile deviceProfile) { 251 + public static LwM2mClientProfile toLwM2MClientProfile(DeviceProfile deviceProfile) {
253 if (deviceProfile != null && ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties().size() > 0) { 252 if (deviceProfile != null && ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties().size() > 0) {
254 Object profile = ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties(); 253 Object profile = ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties();
255 try { 254 try {
@@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
16 package org.thingsboard.server.transport.lwm2m.server.client; 16 package org.thingsboard.server.transport.lwm2m.server.client;
17 17
18 import lombok.Data; 18 import lombok.Data;
  19 +import lombok.Getter;
  20 +import lombok.Setter;
19 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
20 import org.eclipse.leshan.core.model.ResourceModel; 22 import org.eclipse.leshan.core.model.ResourceModel;
21 import org.eclipse.leshan.core.node.LwM2mPath; 23 import org.eclipse.leshan.core.node.LwM2mPath;
@@ -24,7 +26,11 @@ import org.eclipse.leshan.core.node.LwM2mSingleResource; @@ -24,7 +26,11 @@ import org.eclipse.leshan.core.node.LwM2mSingleResource;
24 import org.eclipse.leshan.server.model.LwM2mModelProvider; 26 import org.eclipse.leshan.server.model.LwM2mModelProvider;
25 import org.eclipse.leshan.server.registration.Registration; 27 import org.eclipse.leshan.server.registration.Registration;
26 import org.eclipse.leshan.server.security.SecurityInfo; 28 import org.eclipse.leshan.server.security.SecurityInfo;
  29 +import org.thingsboard.server.common.data.Device;
  30 +import org.thingsboard.server.common.data.DeviceProfile;
27 import org.thingsboard.server.gen.transport.TransportProtos; 31 import org.thingsboard.server.gen.transport.TransportProtos;
  32 +import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto;
  33 +import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
28 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; 34 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
29 import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler; 35 import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler;
30 import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest; 36 import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest;
@@ -33,6 +39,7 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; @@ -33,6 +39,7 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
33 import java.util.Collection; 39 import java.util.Collection;
34 import java.util.List; 40 import java.util.List;
35 import java.util.Map; 41 import java.util.Map;
  42 +import java.util.Optional;
36 import java.util.Queue; 43 import java.util.Queue;
37 import java.util.Set; 44 import java.util.Set;
38 import java.util.UUID; 45 import java.util.UUID;
@@ -47,31 +54,52 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.c @@ -47,31 +54,52 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.c
47 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getVerFromPathIdVerOrId; 54 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getVerFromPathIdVerOrId;
48 55
49 @Slf4j 56 @Slf4j
50 -@Data  
51 public class LwM2mClient implements Cloneable { 57 public class LwM2mClient implements Cloneable {
  58 + @Getter
52 private String deviceName; 59 private String deviceName;
  60 + @Getter
53 private String deviceProfileName; 61 private String deviceProfileName;
  62 + @Getter
54 private String endpoint; 63 private String endpoint;
  64 + @Getter
55 private String identity; 65 private String identity;
  66 + @Getter
56 private SecurityInfo securityInfo; 67 private SecurityInfo securityInfo;
  68 + @Getter
57 private UUID deviceId; 69 private UUID deviceId;
  70 + @Getter
58 private UUID sessionId; 71 private UUID sessionId;
  72 + @Getter
  73 + private SessionInfoProto session;
  74 + @Getter
59 private UUID profileId; 75 private UUID profileId;
  76 + @Getter
  77 + @Setter
60 private volatile LwM2mFirmwareUpdate frUpdate; 78 private volatile LwM2mFirmwareUpdate frUpdate;
  79 + @Getter
  80 + @Setter
61 private Registration registration; 81 private Registration registration;
  82 +
62 private ValidateDeviceCredentialsResponseMsg credentialsResponse; 83 private ValidateDeviceCredentialsResponseMsg credentialsResponse;
  84 + @Getter
63 private final Map<String, ResourceValue> resources; 85 private final Map<String, ResourceValue> resources;
64 - private final Map<String, TransportProtos.TsKvProto> delayedRequests; 86 + @Getter
  87 + private final Map<String, TsKvProto> delayedRequests;
  88 + @Getter
65 private final List<String> pendingReadRequests; 89 private final List<String> pendingReadRequests;
  90 + @Getter
66 private final Queue<LwM2mQueuedRequest> queuedRequests; 91 private final Queue<LwM2mQueuedRequest> queuedRequests;
  92 + @Getter
67 private boolean init; 93 private boolean init;
  94 + @Getter
  95 + @Setter
68 private volatile boolean updateFw; 96 private volatile boolean updateFw;
69 97
70 public Object clone() throws CloneNotSupportedException { 98 public Object clone() throws CloneNotSupportedException {
71 return super.clone(); 99 return super.clone();
72 } 100 }
73 101
74 - public LwM2mClient(String endpoint, String identity, SecurityInfo securityInfo, ValidateDeviceCredentialsResponseMsg credentialsResponse, UUID profileId, UUID sessionId) { 102 + public LwM2mClient(String nodeId, String endpoint, String identity, SecurityInfo securityInfo, ValidateDeviceCredentialsResponseMsg credentialsResponse, UUID profileId, UUID sessionId) {
75 this.endpoint = endpoint; 103 this.endpoint = endpoint;
76 this.identity = identity; 104 this.identity = identity;
77 this.securityInfo = securityInfo; 105 this.securityInfo = securityInfo;
@@ -85,6 +113,56 @@ public class LwM2mClient implements Cloneable { @@ -85,6 +113,56 @@ public class LwM2mClient implements Cloneable {
85 this.updateFw = false; 113 this.updateFw = false;
86 this.queuedRequests = new ConcurrentLinkedQueue<>(); 114 this.queuedRequests = new ConcurrentLinkedQueue<>();
87 this.frUpdate = new LwM2mFirmwareUpdate(); 115 this.frUpdate = new LwM2mFirmwareUpdate();
  116 + if (this.credentialsResponse != null && this.credentialsResponse.hasDeviceInfo()) {
  117 + this.session = createSession(nodeId, sessionId, credentialsResponse);
  118 + this.deviceId = new UUID(session.getDeviceIdMSB(), session.getDeviceIdLSB());
  119 + this.profileId = new UUID(session.getDeviceProfileIdMSB(), session.getDeviceProfileIdLSB());
  120 + this.deviceName = session.getDeviceName();
  121 + this.deviceProfileName = session.getDeviceType();
  122 + }
  123 + }
  124 +
  125 + public void onDeviceUpdate(Device device, Optional<DeviceProfile> deviceProfileOpt) {
  126 + SessionInfoProto.Builder builder = SessionInfoProto.newBuilder().mergeFrom(session);
  127 + this.deviceId = device.getUuidId();
  128 + this.deviceName = device.getName();
  129 + builder.setDeviceIdMSB(deviceId.getMostSignificantBits());
  130 + builder.setDeviceIdLSB(deviceId.getLeastSignificantBits());
  131 + builder.setDeviceName(deviceName);
  132 + deviceProfileOpt.ifPresent(deviceProfile -> updateSession(deviceProfile, builder));
  133 + this.session = builder.build();
  134 + }
  135 +
  136 + public void onDeviceProfileUpdate(DeviceProfile deviceProfile) {
  137 + SessionInfoProto.Builder builder = SessionInfoProto.newBuilder().mergeFrom(session);
  138 + updateSession(deviceProfile, builder);
  139 + this.session = builder.build();
  140 + }
  141 +
  142 + private void updateSession(DeviceProfile deviceProfile, SessionInfoProto.Builder builder) {
  143 + this.deviceProfileName = deviceProfile.getName();
  144 + this.profileId = deviceProfile.getUuidId();
  145 + builder.setDeviceProfileIdMSB(profileId.getMostSignificantBits());
  146 + builder.setDeviceProfileIdLSB(profileId.getLeastSignificantBits());
  147 + builder.setDeviceType(this.deviceProfileName);
  148 + }
  149 +
  150 + private SessionInfoProto createSession(String nodeId, UUID sessionId, ValidateDeviceCredentialsResponseMsg msg) {
  151 + return SessionInfoProto.newBuilder()
  152 + .setNodeId(nodeId)
  153 + .setSessionIdMSB(sessionId.getMostSignificantBits())
  154 + .setSessionIdLSB(sessionId.getLeastSignificantBits())
  155 + .setDeviceIdMSB(msg.getDeviceInfo().getDeviceIdMSB())
  156 + .setDeviceIdLSB(msg.getDeviceInfo().getDeviceIdLSB())
  157 + .setTenantIdMSB(msg.getDeviceInfo().getTenantIdMSB())
  158 + .setTenantIdLSB(msg.getDeviceInfo().getTenantIdLSB())
  159 + .setCustomerIdMSB(msg.getDeviceInfo().getCustomerIdMSB())
  160 + .setCustomerIdLSB(msg.getDeviceInfo().getCustomerIdLSB())
  161 + .setDeviceName(msg.getDeviceInfo().getDeviceName())
  162 + .setDeviceType(msg.getDeviceInfo().getDeviceType())
  163 + .setDeviceProfileIdLSB(msg.getDeviceInfo().getDeviceProfileIdLSB())
  164 + .setDeviceProfileIdMSB(msg.getDeviceInfo().getDeviceProfileIdMSB())
  165 + .build();
88 } 166 }
89 167
90 public boolean saveResourceValue(String pathRez, LwM2mResource rez, LwM2mModelProvider modelProvider) { 168 public boolean saveResourceValue(String pathRez, LwM2mResource rez, LwM2mModelProvider modelProvider) {
@@ -123,7 +201,7 @@ public class LwM2mClient implements Cloneable { @@ -123,7 +201,7 @@ public class LwM2mClient implements Cloneable {
123 return resources; 201 return resources;
124 } 202 }
125 203
126 - public boolean isValidObjectVersion (String path) { 204 + public boolean isValidObjectVersion(String path) {
127 LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(path)); 205 LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(path));
128 String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId()); 206 String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId());
129 String verRez = getVerFromPathIdVerOrId(path); 207 String verRez = getVerFromPathIdVerOrId(path);
@@ -131,8 +209,7 @@ public class LwM2mClient implements Cloneable { @@ -131,8 +209,7 @@ public class LwM2mClient implements Cloneable {
131 } 209 }
132 210
133 /** 211 /**
134 - *  
135 - * @param pathIdVer == "3_1.0" 212 + * @param pathIdVer == "3_1.0"
136 * @param modelProvider - 213 * @param modelProvider -
137 */ 214 */
138 public void deleteResources(String pathIdVer, LwM2mModelProvider modelProvider) { 215 public void deleteResources(String pathIdVer, LwM2mModelProvider modelProvider) {
@@ -142,16 +219,14 @@ public class LwM2mClient implements Cloneable { @@ -142,16 +219,14 @@ public class LwM2mClient implements Cloneable {
142 ResourceModel resourceModel = modelProvider.getObjectModel(registration).getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()); 219 ResourceModel resourceModel = modelProvider.getObjectModel(registration).getResourceModel(pathIds.getObjectId(), pathIds.getResourceId());
143 if (resourceModel != null) { 220 if (resourceModel != null) {
144 this.resources.get(pathRez).setResourceModel(resourceModel); 221 this.resources.get(pathRez).setResourceModel(resourceModel);
145 - }  
146 - else { 222 + } else {
147 this.resources.remove(pathRez); 223 this.resources.remove(pathRez);
148 } 224 }
149 }); 225 });
150 } 226 }
151 227
152 /** 228 /**
153 - *  
154 - * @param idVer - 229 + * @param idVer -
155 * @param modelProvider - 230 * @param modelProvider -
156 */ 231 */
157 public void updateResourceModel(String idVer, LwM2mModelProvider modelProvider) { 232 public void updateResourceModel(String idVer, LwM2mModelProvider modelProvider) {
@@ -182,8 +257,5 @@ public class LwM2mClient implements Cloneable { @@ -182,8 +257,5 @@ public class LwM2mClient implements Cloneable {
182 } 257 }
183 } 258 }
184 259
185 - public LwM2mClient copy() {  
186 - return new LwM2mClient(this.endpoint, this.identity, this.securityInfo, this.credentialsResponse, this.profileId, this.sessionId);  
187 - }  
188 } 260 }
189 261
@@ -19,29 +19,32 @@ import org.eclipse.leshan.server.registration.Registration; @@ -19,29 +19,32 @@ import org.eclipse.leshan.server.registration.Registration;
19 import org.thingsboard.server.common.data.DeviceProfile; 19 import org.thingsboard.server.common.data.DeviceProfile;
20 import org.thingsboard.server.gen.transport.TransportProtos; 20 import org.thingsboard.server.gen.transport.TransportProtos;
21 21
  22 +import java.util.Collection;
22 import java.util.Map; 23 import java.util.Map;
23 import java.util.Set; 24 import java.util.Set;
24 import java.util.UUID; 25 import java.util.UUID;
25 26
26 public interface LwM2mClientContext { 27 public interface LwM2mClientContext {
27 28
28 - void delRemoveSessionAndListener(String registrationId); 29 + void removeClientByRegistrationId(String registrationId);
29 30
30 - LwM2mClient getLwM2MClient(String endPoint, String identity); 31 + LwM2mClient getClientByEndpoint(String endpoint);
31 32
32 - LwM2mClient getLwM2MClient(TransportProtos.SessionInfoProto sessionInfo); 33 + LwM2mClient getClientByRegistrationId(String registrationId);
33 34
34 - LwM2mClient getLwM2mClient(UUID sessionId); 35 + LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo);
35 36
36 - LwM2mClient getLwM2mClientWithReg(Registration registration, String registrationId); 37 + LwM2mClient getClient(UUID sessionId);
37 38
38 - LwM2mClient updateInSessionsLwM2MClient(Registration registration); 39 + LwM2mClient getOrRegister(Registration registration);
39 40
40 - LwM2mClient addLwM2mClientToSession(String identity); 41 + LwM2mClient registerOrUpdate(Registration registration);
  42 +
  43 + LwM2mClient fetchClientByEndpoint(String endpoint);
41 44
42 Registration getRegistration(String registrationId); 45 Registration getRegistration(String registrationId);
43 46
44 - Map<String, LwM2mClient> getLwM2mClients(); 47 + Collection<LwM2mClient> getLwM2mClients();
45 48
46 Map<UUID, LwM2mClientProfile> getProfiles(); 49 Map<UUID, LwM2mClientProfile> getProfiles();
47 50
@@ -51,7 +54,9 @@ public interface LwM2mClientContext { @@ -51,7 +54,9 @@ public interface LwM2mClientContext {
51 54
52 Map<UUID, LwM2mClientProfile> setProfiles(Map<UUID, LwM2mClientProfile> profiles); 55 Map<UUID, LwM2mClientProfile> setProfiles(Map<UUID, LwM2mClientProfile> profiles);
53 56
54 - boolean addUpdateProfileParameters(DeviceProfile deviceProfile); 57 + LwM2mClientProfile toClientProfile(DeviceProfile deviceProfile);
55 58
56 Set<String> getSupportedIdVerInClient(Registration registration); 59 Set<String> getSupportedIdVerInClient(Registration registration);
  60 +
  61 + LwM2mClient getClientByDeviceId(UUID deviceId);
57 } 62 }
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.transport.lwm2m.server.client; 16 package org.thingsboard.server.transport.lwm2m.server.client;
17 17
  18 +import lombok.RequiredArgsConstructor;
18 import org.eclipse.leshan.core.node.LwM2mPath; 19 import org.eclipse.leshan.core.node.LwM2mPath;
19 import org.eclipse.leshan.server.registration.Registration; 20 import org.eclipse.leshan.server.registration.Registration;
20 import org.eclipse.leshan.server.security.EditableSecurityStore; 21 import org.eclipse.leshan.server.security.EditableSecurityStore;
@@ -24,123 +25,121 @@ import org.thingsboard.server.gen.transport.TransportProtos; @@ -24,123 +25,121 @@ import org.thingsboard.server.gen.transport.TransportProtos;
24 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; 25 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
25 import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; 26 import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
26 import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; 27 import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
27 -import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; 28 +import org.thingsboard.server.transport.lwm2m.secure.EndpointSecurityInfo;
  29 +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
28 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; 30 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
29 31
30 import java.util.Arrays; 32 import java.util.Arrays;
  33 +import java.util.Collection;
31 import java.util.Map; 34 import java.util.Map;
  35 +import java.util.Optional;
32 import java.util.Set; 36 import java.util.Set;
33 import java.util.UUID; 37 import java.util.UUID;
34 import java.util.concurrent.ConcurrentHashMap; 38 import java.util.concurrent.ConcurrentHashMap;
  39 +import java.util.stream.Collectors;
35 40
36 import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC; 41 import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC;
37 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer; 42 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer;
38 43
39 @Service 44 @Service
40 @TbLwM2mTransportComponent 45 @TbLwM2mTransportComponent
  46 +@RequiredArgsConstructor
41 public class LwM2mClientContextImpl implements LwM2mClientContext { 47 public class LwM2mClientContextImpl implements LwM2mClientContext {
42 48
43 - private static final boolean INFOS_ARE_COMPROMISED = false;  
44 -  
45 - private final Map<String /** registrationId */, LwM2mClient> lwM2mClients = new ConcurrentHashMap<>();  
46 - private Map<UUID /** profileUUid */, LwM2mClientProfile> profiles = new ConcurrentHashMap<>(); 49 + private final LwM2mTransportContext context;
  50 + private final Map<String, LwM2mClient> lwM2mClientsByEndpoint = new ConcurrentHashMap<>();
  51 + private final Map<String, LwM2mClient> lwM2mClientsByRegistrationId = new ConcurrentHashMap<>();
  52 + private Map<UUID, LwM2mClientProfile> profiles = new ConcurrentHashMap<>();
47 53
48 private final LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator; 54 private final LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator;
49 55
50 private final EditableSecurityStore securityStore; 56 private final EditableSecurityStore securityStore;
51 57
52 - public LwM2mClientContextImpl(LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator, EditableSecurityStore securityStore) {  
53 - this.lwM2MCredentialsSecurityInfoValidator = lwM2MCredentialsSecurityInfoValidator;  
54 - this.securityStore = securityStore;  
55 - }  
56 -  
57 - public void delRemoveSessionAndListener(String registrationId) {  
58 - LwM2mClient lwM2MClient = this.lwM2mClients.get(registrationId);  
59 - if (lwM2MClient != null) {  
60 - this.securityStore.remove(lwM2MClient.getEndpoint(), INFOS_ARE_COMPROMISED);  
61 - this.lwM2mClients.remove(registrationId);  
62 - } 58 + @Override
  59 + public LwM2mClient getClientByEndpoint(String endpoint) {
  60 + return lwM2mClientsByEndpoint.get(endpoint);
63 } 61 }
64 62
65 @Override 63 @Override
66 - public LwM2mClient getLwM2MClient(String endPoint, String identity) {  
67 - Map.Entry<String, LwM2mClient> modelClients = endPoint != null ?  
68 - this.lwM2mClients.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndpoint())).findAny().orElse(null) :  
69 - this.lwM2mClients.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).findAny().orElse(null);  
70 - return modelClients != null ? modelClients.getValue() : null; 64 + public LwM2mClient getClientByRegistrationId(String registrationId) {
  65 + return lwM2mClientsByRegistrationId.get(registrationId);
71 } 66 }
72 67
73 @Override 68 @Override
74 - public LwM2mClient getLwM2MClient(TransportProtos.SessionInfoProto sessionInfo) {  
75 - return getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); 69 + public LwM2mClient getOrRegister(Registration registration) {
  70 + if (registration == null) {
  71 + return null;
  72 + }
  73 + LwM2mClient client = lwM2mClientsByRegistrationId.get(registration.getId());
  74 + if (client == null) {
  75 + client = lwM2mClientsByEndpoint.get(registration.getEndpoint());
  76 + if (client == null) {
  77 + client = registerOrUpdate(registration);
  78 + }
  79 + }
  80 + return client;
76 } 81 }
77 82
78 @Override 83 @Override
79 - public LwM2mClient getLwM2mClient(UUID sessionId) {  
80 - return lwM2mClients.values().stream().filter(c -> c.getSessionId().equals(sessionId)).findAny().get(); 84 + public LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo) {
  85 + return getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
81 } 86 }
82 87
83 @Override 88 @Override
84 - public LwM2mClient getLwM2mClientWithReg(Registration registration, String registrationId) {  
85 - LwM2mClient client = registrationId != null && this.lwM2mClients.containsKey(registrationId) ?  
86 - this.lwM2mClients.get(registrationId) :  
87 - registration !=null && this.lwM2mClients.containsKey(registration.getId()) ?  
88 - this.lwM2mClients.get(registration.getId()) : registration !=null && this.lwM2mClients.containsKey(registration) ?  
89 - this.lwM2mClients.get(registration.getEndpoint()) : null;  
90 - return client != null ? client : registration!= null ? updateInSessionsLwM2MClient(registration) : null; 89 + public LwM2mClient getClient(UUID sessionId) {
  90 + //TODO: refactor this to search by sessionId efficiently.
  91 + return lwM2mClientsByEndpoint.values().stream().filter(c -> c.getSessionId().equals(sessionId)).findAny().get();
91 } 92 }
92 93
93 @Override 94 @Override
94 - public LwM2mClient updateInSessionsLwM2MClient(Registration registration) {  
95 - if (this.lwM2mClients.get(registration.getEndpoint()) == null) {  
96 - this.addLwM2mClientToSession(registration.getEndpoint()); 95 + public LwM2mClient registerOrUpdate(Registration registration) {
  96 + LwM2mClient lwM2MClient = lwM2mClientsByEndpoint.get(registration.getEndpoint());
  97 + if (lwM2MClient == null) {
  98 + lwM2MClient = this.fetchClientByEndpoint(registration.getEndpoint());
97 } 99 }
98 - LwM2mClient lwM2MClient = lwM2mClients.get(registration.getEndpoint());  
99 lwM2MClient.setRegistration(registration); 100 lwM2MClient.setRegistration(registration);
100 - this.lwM2mClients.remove(registration.getEndpoint());  
101 - this.lwM2mClients.put(registration.getId(), lwM2MClient); 101 +// TODO: this remove is probably redundant. We should remove it.
  102 +// this.lwM2mClientsByEndpoint.remove(registration.getEndpoint());
  103 + this.lwM2mClientsByRegistrationId.put(registration.getId(), lwM2MClient);
102 return lwM2MClient; 104 return lwM2MClient;
103 } 105 }
104 106
105 public Registration getRegistration(String registrationId) { 107 public Registration getRegistration(String registrationId) {
106 - return this.lwM2mClients.get(registrationId).getRegistration(); 108 + return this.lwM2mClientsByRegistrationId.get(registrationId).getRegistration();
107 } 109 }
108 110
109 - /**  
110 - * Add new LwM2MClient to session  
111 - *  
112 - * @param identity-  
113 - * @return SecurityInfo. If error - SecurityInfoError  
114 - * and log:  
115 - * - FORBIDDEN - if there is no authorization  
116 - * - profileUuid - if the device does not have a profile  
117 - * - device - if the thingsboard does not have a device with a name equal to the identity  
118 - */  
119 @Override 111 @Override
120 - public LwM2mClient addLwM2mClientToSession(String identity) {  
121 - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportUtil.LwM2mTypeServer.CLIENT);  
122 - if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {  
123 - UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null;  
124 - LwM2mClient client;  
125 - if (store.getSecurityInfo() != null && profileUuid != null) {  
126 - String endpoint = store.getSecurityInfo().getEndpoint();  
127 - client = new LwM2mClient(endpoint, store.getSecurityInfo().getIdentity(), store.getSecurityInfo(), store.getMsg(), profileUuid, UUID.randomUUID());  
128 - lwM2mClients.put(endpoint, client);  
129 - } else if (store.getSecurityMode() == NO_SEC.code && profileUuid != null) {  
130 - client = new LwM2mClient(identity, null, null, store.getMsg(), profileUuid, UUID.randomUUID());  
131 - lwM2mClients.put(identity, client); 112 + public LwM2mClient fetchClientByEndpoint(String endpoint) {
  113 + EndpointSecurityInfo securityInfo = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(endpoint, LwM2mTransportUtil.LwM2mTypeServer.CLIENT);
  114 + if (securityInfo.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
  115 + if (securityInfo.getDeviceProfile() != null) {
  116 + toClientProfile(securityInfo.getDeviceProfile());
  117 + UUID profileUuid = securityInfo.getDeviceProfile().getUuidId();
  118 + LwM2mClient client;
  119 + if (securityInfo.getSecurityInfo() != null) {
  120 + client = new LwM2mClient(context.getNodeId(), securityInfo.getSecurityInfo().getEndpoint(),
  121 + securityInfo.getSecurityInfo().getIdentity(), securityInfo.getSecurityInfo(),
  122 + securityInfo.getMsg(), profileUuid, UUID.randomUUID());
  123 + } else if (securityInfo.getSecurityMode() == NO_SEC.code) {
  124 + client = new LwM2mClient(context.getNodeId(), endpoint,
  125 + null, null,
  126 + securityInfo.getMsg(), profileUuid, UUID.randomUUID());
  127 + } else {
  128 + throw new RuntimeException(String.format("Registration failed: device %s not found.", endpoint));
  129 + }
  130 + lwM2mClientsByEndpoint.put(client.getEndpoint(), client);
  131 + return client;
132 } else { 132 } else {
133 - throw new RuntimeException(String.format("Registration failed: FORBIDDEN/profileUuid/device %s , endpointId: %s [PSK]", profileUuid, identity)); 133 + throw new RuntimeException(String.format("Registration failed: device %s not found.", endpoint));
134 } 134 }
135 - return client;  
136 } else { 135 } else {
137 - throw new RuntimeException(String.format("Registration failed: FORBIDDEN, endpointId: %s", identity)); 136 + throw new RuntimeException(String.format("Registration failed: FORBIDDEN, endpointId: %s", endpoint));
138 } 137 }
139 } 138 }
140 139
141 @Override 140 @Override
142 - public Map<String, LwM2mClient> getLwM2mClients() {  
143 - return lwM2mClients; 141 + public Collection<LwM2mClient> getLwM2mClients() {
  142 + return lwM2mClientsByEndpoint.values();
144 } 143 }
145 144
146 @Override 145 @Override
@@ -155,7 +154,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { @@ -155,7 +154,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
155 154
156 @Override 155 @Override
157 public LwM2mClientProfile getProfile(Registration registration) { 156 public LwM2mClientProfile getProfile(Registration registration) {
158 - return this.getProfiles().get(getLwM2mClientWithReg(registration, null).getProfileId()); 157 + return this.getProfiles().get(getOrRegister(registration).getProfileId());
159 } 158 }
160 159
161 @Override 160 @Override
@@ -164,17 +163,18 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { @@ -164,17 +163,18 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
164 } 163 }
165 164
166 @Override 165 @Override
167 - public boolean addUpdateProfileParameters(DeviceProfile deviceProfile) {  
168 - LwM2mClientProfile lwM2MClientProfile = LwM2mTransportUtil.getLwM2MClientProfileFromThingsboard(deviceProfile);  
169 - if (lwM2MClientProfile != null) { 166 + public LwM2mClientProfile toClientProfile(DeviceProfile deviceProfile) {
  167 + LwM2mClientProfile lwM2MClientProfile = profiles.get(deviceProfile.getUuidId());
  168 + if (lwM2MClientProfile == null) {
  169 + lwM2MClientProfile = LwM2mTransportUtil.toLwM2MClientProfile(deviceProfile);
170 profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile); 170 profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile);
171 - return true;  
172 } 171 }
173 - return false; 172 + return lwM2MClientProfile;
174 } 173 }
175 174
176 /** 175 /**
177 * if isVer - ok or default ver=DEFAULT_LWM2M_VERSION 176 * if isVer - ok or default ver=DEFAULT_LWM2M_VERSION
  177 + *
178 * @param registration - 178 * @param registration -
179 * @return - all objectIdVer in client 179 * @return - all objectIdVer in client
180 */ 180 */
@@ -184,9 +184,31 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { @@ -184,9 +184,31 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
184 Arrays.stream(registration.getObjectLinks()).forEach(url -> { 184 Arrays.stream(registration.getObjectLinks()).forEach(url -> {
185 LwM2mPath pathIds = new LwM2mPath(url.getUrl()); 185 LwM2mPath pathIds = new LwM2mPath(url.getUrl());
186 if (!pathIds.isRoot()) { 186 if (!pathIds.isRoot()) {
187 - clientObjects.add(convertPathFromObjectIdToIdVer(url.getUrl(), registration)); 187 + clientObjects.add(convertPathFromObjectIdToIdVer(url.getUrl(), registration));
188 } 188 }
189 }); 189 });
190 return (clientObjects.size() > 0) ? clientObjects : null; 190 return (clientObjects.size() > 0) ? clientObjects : null;
191 } 191 }
  192 +
  193 + @Override
  194 + public LwM2mClient getClientByDeviceId(UUID deviceId) {
  195 + return lwM2mClientsByRegistrationId.values().stream().filter(e -> deviceId.equals(e.getDeviceId())).findFirst().orElse(null);
  196 + }
  197 +
  198 + @Override
  199 + public void removeClientByRegistrationId(String registrationId) {
  200 + LwM2mClient lwM2MClient = this.lwM2mClientsByRegistrationId.get(registrationId);
  201 + if (lwM2MClient != null) {
  202 + this.securityStore.remove(lwM2MClient.getEndpoint(), false);
  203 + this.lwM2mClientsByEndpoint.remove(lwM2MClient.getEndpoint());
  204 + this.lwM2mClientsByRegistrationId.remove(registrationId);
  205 + UUID profileId = lwM2MClient.getProfileId();
  206 + if (profileId != null) {
  207 + Optional<LwM2mClient> otherClients = lwM2mClientsByRegistrationId.values().stream().filter(e -> e.getProfileId().equals(profileId)).findFirst();
  208 + if (otherClients.isEmpty()) {
  209 + profiles.remove(profileId);
  210 + }
  211 + }
  212 + }
  213 + }
192 } 214 }
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mSecurityStore.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mStoreConfiguration.java
@@ -15,114 +15,80 @@ @@ -15,114 +15,80 @@
15 */ 15 */
16 package org.thingsboard.server.transport.lwm2m.server.store; 16 package org.thingsboard.server.transport.lwm2m.server.store;
17 17
18 -import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore;  
19 -import org.eclipse.leshan.server.californium.registration.InMemoryRegistrationStore; 18 +import lombok.extern.slf4j.Slf4j;
20 import org.eclipse.leshan.server.security.EditableSecurityStore; 19 import org.eclipse.leshan.server.security.EditableSecurityStore;
21 -import org.eclipse.leshan.server.security.InMemorySecurityStore;  
22 import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException; 20 import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException;
23 import org.eclipse.leshan.server.security.SecurityInfo; 21 import org.eclipse.leshan.server.security.SecurityInfo;
24 import org.eclipse.leshan.server.security.SecurityStoreListener; 22 import org.eclipse.leshan.server.security.SecurityStoreListener;
25 -import org.springframework.beans.factory.annotation.Autowired;  
26 -import org.springframework.beans.factory.annotation.Value;  
27 -import org.springframework.context.annotation.Bean;  
28 -import org.springframework.context.annotation.Lazy;  
29 -import org.springframework.stereotype.Service;  
30 -import org.thingsboard.server.cache.TBRedisCacheConfiguration;  
31 -import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;  
32 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; 23 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
33 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; 24 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
34 25
35 import java.util.Collection; 26 import java.util.Collection;
36 -import java.util.Optional;  
37 27
38 -@Service  
39 -@TbLwM2mTransportComponent  
40 -public class TbLwM2mStoreConfiguration { 28 +@Slf4j
  29 +public class TbLwM2mSecurityStore implements EditableSecurityStore {
41 30
42 - @Autowired(required = false)  
43 - private Optional<TBRedisCacheConfiguration> redisConfiguration; 31 + private final LwM2mClientContext clientContext;
  32 + private final EditableSecurityStore securityStore;
44 33
45 - @Autowired  
46 - @Lazy  
47 - private LwM2mClientContext clientContext;  
48 -  
49 - @Value("${transport.lwm2m.redis.enabled:false}")  
50 - private boolean useRedis;  
51 -  
52 - @Bean  
53 - private CaliforniumRegistrationStore registrationStore() {  
54 - return redisConfiguration.isPresent() && useRedis ?  
55 - new TbLwM2mRedisRegistrationStore(redisConfiguration.get().redisConnectionFactory()) : new InMemoryRegistrationStore(); 34 + public TbLwM2mSecurityStore(LwM2mClientContext clientContext, EditableSecurityStore securityStore) {
  35 + this.clientContext = clientContext;
  36 + this.securityStore = securityStore;
56 } 37 }
57 38
58 - @Bean  
59 - private EditableSecurityStore securityStore() {  
60 - return new TbLwM2mSecurityStoreWrapper(redisConfiguration.isPresent() && useRedis ?  
61 - new TbLwM2mRedisSecurityStore(redisConfiguration.get().redisConnectionFactory()) : new InMemorySecurityStore()); 39 + @Override
  40 + public Collection<SecurityInfo> getAll() {
  41 + return securityStore.getAll();
62 } 42 }
63 43
64 - public class TbLwM2mSecurityStoreWrapper implements EditableSecurityStore {  
65 -  
66 - private final EditableSecurityStore securityStore;  
67 -  
68 - public TbLwM2mSecurityStoreWrapper(EditableSecurityStore securityStore) {  
69 - this.securityStore = securityStore;  
70 - }  
71 -  
72 - @Override  
73 - public Collection<SecurityInfo> getAll() {  
74 - return securityStore.getAll();  
75 - }  
76 -  
77 - @Override  
78 - public SecurityInfo add(SecurityInfo info) throws NonUniqueSecurityInfoException {  
79 - return securityStore.add(info);  
80 - } 44 + @Override
  45 + public SecurityInfo add(SecurityInfo info) throws NonUniqueSecurityInfoException {
  46 + return securityStore.add(info);
  47 + }
81 48
82 - @Override  
83 - public SecurityInfo remove(String endpoint, boolean infosAreCompromised) {  
84 - return securityStore.remove(endpoint, infosAreCompromised);  
85 - } 49 + @Override
  50 + public SecurityInfo remove(String endpoint, boolean infosAreCompromised) {
  51 + return securityStore.remove(endpoint, infosAreCompromised);
  52 + }
86 53
87 - @Override  
88 - public void setListener(SecurityStoreListener listener) {  
89 - securityStore.setListener(listener);  
90 - } 54 + @Override
  55 + public void setListener(SecurityStoreListener listener) {
  56 + securityStore.setListener(listener);
  57 + }
91 58
92 - @Override  
93 - public SecurityInfo getByEndpoint(String endPoint) {  
94 - SecurityInfo securityInfo = securityStore.getByEndpoint(endPoint);  
95 - if (securityInfo == null) {  
96 - LwM2mClient lwM2mClient = clientContext.getLwM2MClient(endPoint, null);  
97 - if (lwM2mClient != null && lwM2mClient.getRegistration() != null && !lwM2mClient.getRegistration().getIdentity().isSecure()){  
98 - return null;  
99 - }  
100 - securityInfo = clientContext.addLwM2mClientToSession(endPoint).getSecurityInfo();  
101 - try {  
102 - if (securityInfo != null) {  
103 - add(securityInfo);  
104 - }  
105 - } catch (NonUniqueSecurityInfoException e) {  
106 - e.printStackTrace(); 59 + @Override
  60 + public SecurityInfo getByEndpoint(String endpoint) {
  61 + SecurityInfo securityInfo = securityStore.getByEndpoint(endpoint);
  62 + if (securityInfo == null) {
  63 + LwM2mClient lwM2mClient = clientContext.getClientByEndpoint(endpoint);
  64 + if (lwM2mClient != null && lwM2mClient.getRegistration() != null && !lwM2mClient.getRegistration().getIdentity().isSecure()) {
  65 + return null;
  66 + }
  67 + securityInfo = clientContext.fetchClientByEndpoint(endpoint).getSecurityInfo();
  68 + try {
  69 + if (securityInfo != null) {
  70 + add(securityInfo);
107 } 71 }
  72 + } catch (NonUniqueSecurityInfoException e) {
  73 + log.warn("Failed to add security info: {}", securityInfo, e);
108 } 74 }
109 - return securityInfo;  
110 } 75 }
  76 + return securityInfo;
  77 + }
111 78
112 - @Override  
113 - public SecurityInfo getByIdentity(String pskIdentity) {  
114 - SecurityInfo securityInfo = securityStore.getByIdentity(pskIdentity);  
115 - if (securityInfo == null) {  
116 - securityInfo = clientContext.addLwM2mClientToSession(pskIdentity).getSecurityInfo();  
117 - try {  
118 - if (securityInfo != null) {  
119 - add(securityInfo);  
120 - }  
121 - } catch (NonUniqueSecurityInfoException e) {  
122 - e.printStackTrace(); 79 + @Override
  80 + public SecurityInfo getByIdentity(String pskIdentity) {
  81 + SecurityInfo securityInfo = securityStore.getByIdentity(pskIdentity);
  82 + if (securityInfo == null) {
  83 + securityInfo = clientContext.fetchClientByEndpoint(pskIdentity).getSecurityInfo();
  84 + try {
  85 + if (securityInfo != null) {
  86 + add(securityInfo);
123 } 87 }
  88 + } catch (NonUniqueSecurityInfoException e) {
  89 + log.warn("Failed to add security info: {}", securityInfo, e);
124 } 90 }
125 - return securityInfo;  
126 } 91 }
  92 + return securityInfo;
127 } 93 }
128 } 94 }
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.transport.lwm2m.server.store;
  17 +
  18 +import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore;
  19 +import org.eclipse.leshan.server.californium.registration.InMemoryRegistrationStore;
  20 +import org.eclipse.leshan.server.security.EditableSecurityStore;
  21 +import org.eclipse.leshan.server.security.InMemorySecurityStore;
  22 +import org.springframework.beans.factory.annotation.Autowired;
  23 +import org.springframework.beans.factory.annotation.Value;
  24 +import org.springframework.context.annotation.Bean;
  25 +import org.springframework.context.annotation.Lazy;
  26 +import org.springframework.stereotype.Component;
  27 +import org.thingsboard.server.cache.TBRedisCacheConfiguration;
  28 +import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
  29 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
  30 +
  31 +import java.util.Optional;
  32 +
  33 +@Component
  34 +@TbLwM2mTransportComponent
  35 +public class TbLwM2mStoreFactory {
  36 +
  37 + @Autowired(required = false)
  38 + private Optional<TBRedisCacheConfiguration> redisConfiguration;
  39 +
  40 + @Autowired
  41 + @Lazy
  42 + private LwM2mClientContext clientContext;
  43 +
  44 + @Value("${transport.lwm2m.redis.enabled:false}")
  45 + private boolean useRedis;
  46 +
  47 + @Bean
  48 + private CaliforniumRegistrationStore registrationStore() {
  49 + return redisConfiguration.isPresent() && useRedis ?
  50 + new TbLwM2mRedisRegistrationStore(redisConfiguration.get().redisConnectionFactory()) : new InMemoryRegistrationStore();
  51 + }
  52 +
  53 + @Bean
  54 + private EditableSecurityStore securityStore() {
  55 + return new TbLwM2mSecurityStore(clientContext, redisConfiguration.isPresent() && useRedis ?
  56 + new TbLwM2mRedisSecurityStore(redisConfiguration.get().redisConnectionFactory()) : new InMemorySecurityStore());
  57 + }
  58 +
  59 +}