Commit 4bc417456b04e08f988a0db718a619a931a842b2

Authored by nickAS21
Committed by GitHub
1 parent ad7c314b

lwm2m: back transport newKey start (#4278)

* lwm2m: back transport newKey start

* lwm2m: back transport newKey start1

* lwm2m: back transport newKey fix bug save

* lwm2m: back transport newKey test All security - ok

* lwm2m: back transport newKey fix bug updateAttrShared
  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.common.data.lwm2m;
  17 +
  18 +public interface LwM2mConstants {
  19 +
  20 + String LWM2M_SEPARATOR_PATH = "/";
  21 + String LWM2M_SEPARATOR_KEY = "_";
  22 + String LWM2M_SEPARATOR_SEARCH_TEXT = ":";
  23 +}
... ...
... ... @@ -41,6 +41,10 @@
41 41 <artifactId>transport-api</artifactId>
42 42 </dependency>
43 43 <dependency>
  44 + <groupId>org.thingsboard.common</groupId>
  45 + <artifactId>data</artifactId>
  46 + </dependency>
  47 + <dependency>
44 48 <groupId>org.springframework</groupId>
45 49 <artifactId>spring-context-support</artifactId>
46 50 </dependency>
... ...
... ... @@ -26,6 +26,8 @@ import org.eclipse.leshan.server.registration.RegistrationUpdate;
26 26
27 27 import java.util.Collection;
28 28
  29 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToIdVerFromObjectId;
  30 +
29 31 @Slf4j
30 32 public class LwM2mServerListener {
31 33
... ... @@ -90,7 +92,7 @@ public class LwM2mServerListener {
90 92 public void onResponse(Observation observation, Registration registration, ObserveResponse response) {
91 93 if (registration != null) {
92 94 try {
93   - service.onObservationResponse(registration, observation.getPath().toString(), response);
  95 + service.onObservationResponse(registration, convertToIdVerFromObjectId(observation.getPath().toString(), registration), response);
94 96 } catch (Exception e) {
95 97 log.error("[{}] onResponse", e.toString());
96 98
... ...
... ... @@ -22,6 +22,7 @@ import com.google.gson.JsonSyntaxException;
22 22 import lombok.extern.slf4j.Slf4j;
23 23 import org.apache.commons.lang3.StringUtils;
24 24 import org.eclipse.californium.core.network.config.NetworkConfig;
  25 +import org.eclipse.leshan.core.model.ObjectModel;
25 26 import org.eclipse.leshan.core.model.ResourceModel;
26 27 import org.eclipse.leshan.core.node.LwM2mMultipleResource;
27 28 import org.eclipse.leshan.core.node.LwM2mNode;
... ... @@ -32,6 +33,7 @@ import org.eclipse.leshan.core.node.LwM2mSingleResource;
32 33 import org.eclipse.leshan.core.node.codec.CodecException;
33 34 import org.eclipse.leshan.core.util.Hex;
34 35 import org.eclipse.leshan.server.californium.LeshanServerBuilder;
  36 +import org.eclipse.leshan.server.registration.Registration;
35 37 import org.nustaq.serialization.FSTConfiguration;
36 38 import org.thingsboard.server.common.data.DeviceProfile;
37 39 import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
... ... @@ -47,14 +49,12 @@ import java.util.Date;
47 49 import java.util.LinkedList;
48 50 import java.util.Optional;
49 51
  52 +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY;
  53 +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
  54 +
50 55 @Slf4j
51   -//@Component("LwM2MTransportHandler")
52   -//@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' )|| ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")
53 56 public class LwM2mTransportHandler {
54 57
55   - // We choose a default timeout a bit higher to the MAX_TRANSMIT_WAIT(62-93s) which is the time from starting to
56   - // send a Confirmable message to the time when an acknowledgement is no longer expected.
57   -
58 58 public static final String BASE_DEVICE_API_TOPIC = "v1/devices/me";
59 59 public static final String ATTRIBUTE = "attribute";
60 60 public static final String TELEMETRY = "telemetry";
... ... @@ -84,6 +84,8 @@ public class LwM2mTransportHandler {
84 84 public static final String LOG_LW2M_ERROR = "error";
85 85 public static final String LOG_LW2M_WARN = "warn";
86 86
  87 + public static final int LWM2M_STRATEGY_1 = 1;
  88 + public static final int LWM2M_STRATEGY_2 = 2;
87 89
88 90 public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized";
89 91
... ... @@ -110,39 +112,6 @@ public class LwM2mTransportHandler {
110 112 public static final String SERVICE_CHANNEL = "SERVICE";
111 113 public static final String RESPONSE_CHANNEL = "RESP";
112 114
113   -// @Autowired
114   -// @Qualifier("LeshanServerCert")
115   -// private LeshanServer lhServerCert;
116   -//
117   -// @Autowired
118   -// @Qualifier("LeshanServerNoSecPskRpk")
119   -// private LeshanServer lhServerNoSecPskRpk;
120   -
121   -// @Autowired
122   -// @Qualifier("ServerListenerCert")
123   -// private LwM2mServerListener serverListenerCert;
124   -//
125   -// @Autowired
126   -// @Qualifier("ServerListenerNoSecPskRpk")
127   -// private LwM2mServerListener serverListenerNoSecPskRpk;
128   -
129   -
130   -// @PostConstruct
131   -// public void init() {
132   -// try {
133   -// serverListenerCert.init(lhServerCert);
134   -// this.lhServerCert.getRegistrationService().addListener(serverListenerCert.registrationListener);
135   -// this.lhServerCert.getPresenceService().addListener(serverListenerCert.presenceListener);
136   -// this.lhServerCert.getObservationService().addListener(serverListenerCert.observationListener);
137   -// serverListenerNoSecPskRpk.init(lhServerNoSecPskRpk);
138   -// this.lhServerNoSecPskRpk.getRegistrationService().addListener(serverListenerNoSecPskRpk.registrationListener);
139   -// this.lhServerNoSecPskRpk.getPresenceService().addListener(serverListenerNoSecPskRpk.presenceListener);
140   -// this.lhServerNoSecPskRpk.getObservationService().addListener(serverListenerNoSecPskRpk.observationListener);
141   -// } catch (Exception e) {
142   -// log.error("init [{}]", e.toString());
143   -// }
144   -// }
145   -
146 115 public static NetworkConfig getCoapConfig(Integer serverPortNoSec, Integer serverSecurePort) {
147 116 NetworkConfig coapConfig;
148 117 File configFile = new File(NetworkConfig.DEFAULT_FILE_NAME);
... ... @@ -202,10 +171,10 @@ public class LwM2mTransportHandler {
202 171
203 172 /**
204 173 * @return deviceProfileBody with Observe&Attribute&Telemetry From Thingsboard
205   - * Example:
  174 + * Example:
206 175 * property: {"clientLwM2mSettings": {
207   - * clientUpdateValueAfterConnect: false;
208   - * }
  176 + * clientUpdateValueAfterConnect: false;
  177 + * }
209 178 * property: "observeAttr"
210 179 * {"keyName": {
211 180 * "/3/0/1": "modelNumber",
... ... @@ -222,7 +191,7 @@ public class LwM2mTransportHandler {
222 191 try {
223 192 ObjectMapper mapper = new ObjectMapper();
224 193 String profileStr = mapper.writeValueAsString(profile);
225   - JsonObject profileJson = (profileStr != null) ? validateJson(profileStr) : null;
  194 + JsonObject profileJson = (profileStr != null) ? validateJson(profileStr) : null;
226 195 return (getValidateCredentialsBodyFromThingsboard(profileJson)) ? LwM2mTransportHandler.getNewProfileParameters(profileJson, deviceProfile.getTenantId()) : null;
227 196 } catch (IOException e) {
228 197 log.error("", e);
... ... @@ -246,9 +215,9 @@ public class LwM2mTransportHandler {
246 215 return null;
247 216 }
248 217
249   - public static boolean getClientOnlyObserveAfterConnect (LwM2mClientProfile profile) {
250   - return profile.getPostClientLwM2mSettings().getAsJsonObject().has("clientOnlyObserveAfterConnect") &&
251   - profile.getPostClientLwM2mSettings().getAsJsonObject().get("clientOnlyObserveAfterConnect").getAsBoolean();
  218 + public static int getClientOnlyObserveAfterConnect(LwM2mClientProfile profile) {
  219 + return profile.getPostClientLwM2mSettings().getAsJsonObject().has("clientOnlyObserveAfterConnect") ?
  220 + profile.getPostClientLwM2mSettings().getAsJsonObject().get("clientOnlyObserveAfterConnect").getAsInt() : 1;
252 221 }
253 222
254 223 private static boolean getValidateCredentialsBodyFromThingsboard(JsonObject objectMsg) {
... ... @@ -346,4 +315,49 @@ public class LwM2mTransportHandler {
346 315 }
347 316 };
348 317 }
  318 +
  319 + public static String convertToObjectIdFromIdVer(String key) {
  320 + try {
  321 + String[] keyArray = key.split(LWM2M_SEPARATOR_PATH);
  322 + if (keyArray.length > 1 && keyArray[1].split(LWM2M_SEPARATOR_KEY).length == 2) {
  323 + keyArray[1] = keyArray[1].split(LWM2M_SEPARATOR_KEY)[0];
  324 + return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH);
  325 + } else {
  326 + return key;
  327 + }
  328 + } catch (Exception e) {
  329 + return null;
  330 + }
  331 + }
  332 +
  333 + public static String convertToIdVerFromObjectId(String path, Registration registration) {
  334 + String ver = registration.getSupportedObject().get(new LwM2mPath(path).getObjectId());
  335 + try {
  336 + String[] keyArray = path.split(LWM2M_SEPARATOR_PATH);
  337 + if (keyArray.length > 1) {
  338 + keyArray[1] = keyArray[1] + LWM2M_SEPARATOR_KEY + ver;
  339 + return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH);
  340 + } else {
  341 + return path;
  342 + }
  343 + } catch (Exception e) {
  344 + return null;
  345 + }
  346 + }
  347 +
  348 + public static Integer validateObjectIdFromKey(String key) {
  349 + try {
  350 + return Integer.parseInt(key.split(LWM2M_SEPARATOR_PATH)[1].split(LWM2M_SEPARATOR_KEY)[0]);
  351 + } catch (Exception e) {
  352 + return null;
  353 + }
  354 + }
  355 +
  356 + public static String validateObjectVerFromKey(String key) {
  357 + try {
  358 + return (key.split(LWM2M_SEPARATOR_PATH)[1].split(LWM2M_SEPARATOR_KEY)[1]);
  359 + } catch (Exception e) {
  360 + return ObjectModel.DEFAULT_VERSION;
  361 + }
  362 + }
349 363 }
... ...
... ... @@ -72,6 +72,8 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle
72 72 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_ATTRIBUTES;
73 73 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_UPDATE;
74 74 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.RESPONSE_CHANNEL;
  75 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToIdVerFromObjectId;
  76 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToObjectIdFromIdVer;
75 77
76 78 @Slf4j
77 79 @Service
... ... @@ -114,7 +116,7 @@ public class LwM2mTransportRequest {
114 116 */
115 117 public void sendAllRequest(Registration registration, String target, String typeOper,
116 118 String contentFormatParam, Observation observation, Object params, long timeoutInMs) {
117   - LwM2mPath resultIds = new LwM2mPath(target);
  119 + LwM2mPath resultIds = new LwM2mPath(convertToObjectIdFromIdVer(target));
118 120 if (registration != null && resultIds.getObjectId() >= 0) {
119 121 DownlinkRequest request = null;
120 122 ContentFormat contentFormat = contentFormatParam != null ? ContentFormat.fromName(contentFormatParam.toUpperCase()) : null;
... ... @@ -229,9 +231,8 @@ public class LwM2mTransportRequest {
229 231 private void sendRequest(Registration registration, DownlinkRequest request, long timeoutInMs) {
230 232 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);
231 233 leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> {
232   -
233 234 if (!lwM2MClient.isInit()) {
234   - lwM2MClient.initValue(this.serviceImpl, request.getPath().toString());
  235 + lwM2MClient.initValue(this.serviceImpl, convertToIdVerFromObjectId(request.getPath().toString(), registration));
235 236 }
236 237 if (isSuccess(((Response) response.getCoapResponse()).getCode())) {
237 238 this.handleResponse(registration, request.getPath().toString(), response, request);
... ... @@ -251,7 +252,7 @@ public class LwM2mTransportRequest {
251 252 }
252 253 }, e -> {
253 254 if (!lwM2MClient.isInit()) {
254   - lwM2MClient.initValue(this.serviceImpl, request.getPath().toString());
  255 + lwM2MClient.initValue(this.serviceImpl, convertToIdVerFromObjectId(request.getPath().toString(), registration));
255 256 }
256 257 String msg = String.format("%s: sendRequest: Resource path - %s msg error - %s SendRequest to Client",
257 258 LOG_LW2M_ERROR, request.getPath().toString(), e.toString());
... ... @@ -310,21 +311,22 @@ public class LwM2mTransportRequest {
310 311 * @param response -
311 312 */
312 313 private void sendResponse(Registration registration, String path, LwM2mResponse response, DownlinkRequest request) {
  314 + String pathIdVer = convertToIdVerFromObjectId(path, registration);
313 315 if (response instanceof ReadResponse) {
314   - serviceImpl.onObservationResponse(registration, path, (ReadResponse) response);
  316 + serviceImpl.onObservationResponse(registration, pathIdVer, (ReadResponse) response);
315 317 } else if (response instanceof CancelObservationResponse) {
316   - log.info("[{}] Path [{}] CancelObservationResponse 3_Send", path, response);
  318 + log.info("[{}] Path [{}] CancelObservationResponse 3_Send", pathIdVer, response);
317 319 } else if (response instanceof DeleteResponse) {
318   - log.info("[{}] Path [{}] DeleteResponse 5_Send", path, response);
  320 + log.info("[{}] Path [{}] DeleteResponse 5_Send", pathIdVer, response);
319 321 } else if (response instanceof DiscoverResponse) {
320   - log.info("[{}] Path [{}] DiscoverResponse 6_Send", path, response);
  322 + log.info("[{}] Path [{}] DiscoverResponse 6_Send", pathIdVer, response);
321 323 } else if (response instanceof ExecuteResponse) {
322   - log.info("[{}] Path [{}] ExecuteResponse 7_Send", path, response);
  324 + log.info("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response);
323 325 } else if (response instanceof WriteAttributesResponse) {
324   - log.info("[{}] Path [{}] WriteAttributesResponse 8_Send", path, response);
  326 + log.info("[{}] Path [{}] WriteAttributesResponse 8_Send", pathIdVer, response);
325 327 } else if (response instanceof WriteResponse) {
326   - log.info("[{}] Path [{}] WriteAttributesResponse 9_Send", path, response);
327   - serviceImpl.onWriteResponseOk(registration, path, (WriteRequest) request);
  328 + log.info("[{}] Path [{}] WriteAttributesResponse 9_Send", pathIdVer, response);
  329 + serviceImpl.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request);
328 330 }
329 331 }
330 332 }
... ...
... ... @@ -88,10 +88,15 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle
88 88 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR;
89 89 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO;
90 90 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY;
  91 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LWM2M_STRATEGY_2;
91 92 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_EXECUTE;
92 93 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_WRITE_REPLACE;
93 94 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.SERVICE_CHANNEL;
  95 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToIdVerFromObjectId;
  96 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToObjectIdFromIdVer;
94 97 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getAckCallback;
  98 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validateObjectIdFromKey;
  99 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validateObjectVerFromKey;
95 100
96 101 @Slf4j
97 102 @Service
... ... @@ -290,19 +295,19 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
290 295 if (msg.getSharedUpdatedCount() > 0) {
291 296 JsonElement el = JsonConverter.toJson(msg);
292 297 el.getAsJsonObject().entrySet().forEach(de -> {
293   - String path = this.getPathAttributeUpdate(sessionInfo, de.getKey());
  298 + String pathIdVer = this.getPathAttributeUpdate(sessionInfo, de.getKey());
294 299 String value = de.getValue().getAsString();
295 300 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
296 301 LwM2mClientProfile clientProfile = lwM2mClientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));
297   - if (path != null && !path.isEmpty() && (this.validatePathInAttrProfile(clientProfile, path) || this.validatePathInTelemetryProfile(clientProfile, path))) {
298   - ResourceModel resourceModel = lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(path));
  302 + if (pathIdVer != null && !pathIdVer.isEmpty() && (this.validatePathInAttrProfile(clientProfile, pathIdVer) || this.validatePathInTelemetryProfile(clientProfile, pathIdVer))) {
  303 + ResourceModel resourceModel = lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(convertToObjectIdFromIdVer(pathIdVer)));
299 304 if (resourceModel != null && resourceModel.operations.isWritable()) {
300   - lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), path, POST_TYPE_OPER_WRITE_REPLACE,
  305 + lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), pathIdVer, POST_TYPE_OPER_WRITE_REPLACE,
301 306 ContentFormat.TLV.getName(), null, value, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout());
302 307 } else {
303   - log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", path, value);
  308 + log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", pathIdVer, value);
304 309 String logMsg = String.format("%s: attributeUpdate: Resource path - %s value - %s is not Writable and cannot be updated",
305   - LOG_LW2M_ERROR, path, value);
  310 + LOG_LW2M_ERROR, pathIdVer, value);
306 311 this.sentLogsToThingsboard(logMsg, lwM2MClient.getRegistration());
307 312 }
308 313 } else {
... ... @@ -348,7 +353,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
348 353
349 354 /**
350 355 * Trigger Server path = "/1/0/8"
351   - *
  356 + * <p>
352 357 * Trigger bootStrap path = "/1/0/9" - have to implemented on client
353 358 */
354 359 @Override
... ... @@ -458,7 +463,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
458 463 private void initLwM2mFromClientValue(Registration registration, LwM2mClient lwM2MClient) {
459 464 LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration);
460 465 Set<String> clientObjects = this.getAllOjectsInClient(registration);
461   - if (clientObjects != null && !LwM2mTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) {
  466 + if (clientObjects != null && LWM2M_STRATEGY_2 == LwM2mTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) {
462 467 // #2
463 468 lwM2MClient.getPendingRequests().addAll(clientObjects);
464 469 clientObjects.forEach(path -> lwM2mTransportRequest.sendAllRequest(registration, path, GET_TYPE_OPER_READ, ContentFormat.TLV.getName(),
... ... @@ -499,9 +504,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
499 504 * #1 Return old Value Resource from LwM2MClient
500 505 * #2 Update new Resources (replace old Resource Value on new Resource Value)
501 506 *
502   - * @param registration - Registration LwM2M Client
  507 + * @param registration - Registration LwM2M Client
503 508 * @param lwM2mResource - LwM2mSingleResource response.getContent()
504   - * @param path - resource
  509 + * @param path - resource
505 510 */
506 511 private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) {
507 512 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);
... ... @@ -539,7 +544,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
539 544
540 545 /**
541 546 * @param clientProfile -
542   - * @param path -
  547 + * @param path -
543 548 * @return true if path isPresent in postAttributeProfile
544 549 */
545 550 private boolean validatePathInAttrProfile(LwM2mClientProfile clientProfile, String path) {
... ... @@ -555,7 +560,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
555 560
556 561 /**
557 562 * @param clientProfile -
558   - * @param path -
  563 + * @param path -
559 564 * @return true if path isPresent in postAttributeProfile
560 565 */
561 566 private boolean validatePathInTelemetryProfile(LwM2mClientProfile clientProfile, String path) {
... ... @@ -581,10 +586,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
581 586 Set<String> clientInstances = this.getAllInstancesInClient(registration);
582 587 Set<String> result;
583 588 if (GET_TYPE_OPER_READ.equals(typeOper)) {
584   - result = JacksonUtil.fromString(lwM2MClientProfile.getPostAttributeProfile().toString(), new TypeReference<>() {});
585   - result.addAll(JacksonUtil.fromString(lwM2MClientProfile.getPostTelemetryProfile().toString(), new TypeReference<>() {}));
  589 + result = JacksonUtil.fromString(lwM2MClientProfile.getPostAttributeProfile().toString(), new TypeReference<>() {
  590 + });
  591 + result.addAll(JacksonUtil.fromString(lwM2MClientProfile.getPostTelemetryProfile().toString(), new TypeReference<>() {
  592 + }));
586 593 } else {
587   - result = JacksonUtil.fromString(lwM2MClientProfile.getPostObserveProfile().toString(), new TypeReference<>() {});
  594 + result = JacksonUtil.fromString(lwM2MClientProfile.getPostObserveProfile().toString(), new TypeReference<>() {
  595 + });
588 596 }
589 597 Set<String> pathSent = ConcurrentHashMap.newKeySet();
590 598 result.forEach(target -> {
... ... @@ -646,7 +654,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
646 654 Arrays.stream(registration.getObjectLinks()).forEach(url -> {
647 655 LwM2mPath pathIds = new LwM2mPath(url.getUrl());
648 656 if (pathIds.isObjectInstance()) {
649   - clientInstances.add(url.getUrl());
  657 + clientInstances.add(convertToIdVerFromObjectId(url.getUrl(), registration));
650 658 }
651 659 });
652 660 return (clientInstances.size() > 0) ? clientInstances : null;
... ... @@ -656,26 +664,22 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
656 664 * @param attributes - new JsonObject
657 665 * @param telemetry - new JsonObject
658 666 * @param registration - Registration LwM2M Client
659   - * @param path -
  667 + * @param path -
660 668 */
661 669 private void getParametersFromProfile(JsonObject attributes, JsonObject telemetry, Registration registration, Set<String> path) {
662   - LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration);
663   - lwM2MClientProfile.getPostAttributeProfile().forEach(p -> {
664   - LwM2mPath pathIds = new LwM2mPath(p.getAsString());
665   - if (pathIds.isResource()) {
666   - if (path == null || path.contains(p.getAsString())) {
667   - this.addParameters(p.getAsString(), attributes, registration);
  670 + if (path != null && path.size() > 0) {
  671 + LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration);
  672 + lwM2MClientProfile.getPostAttributeProfile().forEach(idVer -> {
  673 + if (path.contains(idVer.getAsString())) {
  674 + this.addParameters(idVer.getAsString(), attributes, registration);
668 675 }
669   - }
670   - });
671   - lwM2MClientProfile.getPostTelemetryProfile().forEach(p -> {
672   - LwM2mPath pathIds = new LwM2mPath(p.getAsString());
673   - if (pathIds.isResource()) {
674   - if (path == null || path.contains(p.getAsString())) {
675   - this.addParameters(p.getAsString(), telemetry, registration);
  676 + });
  677 + lwM2MClientProfile.getPostTelemetryProfile().forEach(idVer -> {
  678 + if (path.contains(idVer.getAsString())) {
  679 + this.addParameters(idVer.getAsString(), telemetry, registration);
676 680 }
677   - }
678   - });
  681 + });
  682 + }
679 683 }
680 684
681 685 /**
... ... @@ -703,22 +707,21 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
703 707 * @return - value of Resource or null
704 708 */
705 709 private String getResourceValueToString(LwM2mClient lwM2MClient, String path) {
706   - LwM2mPath pathIds = new LwM2mPath(path);
707   - ResourceValue resourceValue = this.returnResourceValueFromLwM2MClient(lwM2MClient, pathIds);
  710 + LwM2mPath pathIds =new LwM2mPath(convertToObjectIdFromIdVer(path));
  711 + ResourceValue resourceValue = this.returnResourceValueFromLwM2MClient(lwM2MClient, path);
708 712 return resourceValue == null ? null :
709 713 this.converter.convertValue(resourceValue.getResourceValue(), this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModelType(lwM2MClient.getRegistration(), pathIds), ResourceModel.Type.STRING, pathIds).toString();
710 714 }
711 715
712 716 /**
713   - *
714 717 * @param lwM2MClient -
715   - * @param pathIds -
  718 + * @param path -
716 719 * @return - return value of Resource by idPath
717 720 */
718   - private ResourceValue returnResourceValueFromLwM2MClient(LwM2mClient lwM2MClient, LwM2mPath pathIds) {
  721 + private ResourceValue returnResourceValueFromLwM2MClient(LwM2mClient lwM2MClient, String path) {
719 722 ResourceValue resourceValue = null;
720   - if (pathIds.isResource()) {
721   - resourceValue = lwM2MClient.getResources().get(pathIds.toString());
  723 + if (new LwM2mPath(convertToObjectIdFromIdVer(path)).isResource()) {
  724 + resourceValue = lwM2MClient.getResources().get(path);
722 725 }
723 726 return resourceValue;
724 727 }
... ... @@ -818,8 +821,10 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
818 821
819 822 // #5.1
820 823 if (!observeOld.equals(observeNew)) {
821   - Set<String> observeSetOld = new Gson().fromJson(observeOld, new TypeToken<>() {}.getType());
822   - Set<String> observeSetNew = new Gson().fromJson(observeNew, new TypeToken<>() {}.getType());
  824 + Set<String> observeSetOld = new Gson().fromJson(observeOld, new TypeToken<>() {
  825 + }.getType());
  826 + Set<String> observeSetNew = new Gson().fromJson(observeNew, new TypeToken<>() {
  827 + }.getType());
823 828 //#5.2 add
824 829 // path Attr/Telemetry includes newObserve
825 830 attributeSetOld.addAll(telemetrySetOld);
... ... @@ -840,7 +845,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
840 845 }
841 846 }
842 847
843   - private Set <String> convertJsonArrayToSet (JsonArray jsonArray) {
  848 + private Set<String> convertJsonArrayToSet(JsonArray jsonArray) {
844 849 List<String> attributeListOld = new Gson().fromJson(jsonArray, new TypeToken<>() {
845 850 }.getType());
846 851 return Sets.newConcurrentHashSet(attributeListOld);
... ... @@ -907,7 +912,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
907 912 private void cancelObserveIsValue(Registration registration, Set<String> paramAnallyzer) {
908 913 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);
909 914 paramAnallyzer.forEach(p -> {
910   - if (this.returnResourceValueFromLwM2MClient(lwM2MClient, new LwM2mPath(p)) != null) {
  915 + if (this.returnResourceValueFromLwM2MClient(lwM2MClient, p) != null) {
911 916 this.setCancelObservationRecourse(registration, p);
912 917 }
913 918 }
... ... @@ -953,8 +958,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
953 958 */
954 959 private String getPathAttributeUpdateProfile(TransportProtos.SessionInfoProto sessionInfo, String name) {
955 960 LwM2mClientProfile profile = lwM2mClientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));
  961 + Registration registration = lwM2mClientContext.getLwM2MClient(sessionInfo).getRegistration();
956 962 return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream()
957   - .filter(e -> e.getValue().getAsString().equals(name)).findFirst().map(Map.Entry::getKey)
  963 + .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModelByVer(registration, e.getKey())).findFirst().map(Map.Entry::getKey)
958 964 .orElse("");
959 965 }
960 966
... ... @@ -974,12 +980,14 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
974 980 try {
975 981 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo);
976 982 attributesResponse.getSharedAttributeListList().forEach(attr -> {
977   - String path = this.getPathAttributeUpdate(sessionInfo, attr.getKv().getKey());
978   - // #1.1
979   - if (lwM2MClient.getDelayedRequests().containsKey(path) && attr.getTs() > lwM2MClient.getDelayedRequests().get(path).getTs()) {
980   - lwM2MClient.getDelayedRequests().put(path, attr);
981   - } else {
982   - lwM2MClient.getDelayedRequests().put(path, attr);
  983 + String path =this.getPathAttributeUpdate(sessionInfo, attr.getKv().getKey());
  984 + if (path != null) {
  985 + // #1.1
  986 + if (lwM2MClient.getDelayedRequests().containsKey(path) && attr.getTs() > lwM2MClient.getDelayedRequests().get(path).getTs()) {
  987 + lwM2MClient.getDelayedRequests().put(path, attr);
  988 + } else {
  989 + lwM2MClient.getDelayedRequests().put(path, attr);
  990 + }
983 991 }
984 992 });
985 993 // #2.1
... ... @@ -1057,6 +1065,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
1057 1065 }
1058 1066
1059 1067 /**
  1068 + * !!! sharedAttr === profileAttr !!!
1060 1069 * If there is a difference in values between the current resource values and the shared attribute values
1061 1070 * when the client connects to the server
1062 1071 * #1 get attributes name from profile include name resources in ModelObject if resource isWritable
... ... @@ -1083,24 +1092,42 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
1083 1092
1084 1093
1085 1094 /**
1086   - * Get names and keyNames from profile shared!!!! attr resources IsWritable
  1095 + * !!! sharedAttr === profileAttr !!!
  1096 + * Get names or keyNames from profile: resources IsWritable
1087 1097 *
1088 1098 * @param lwM2MClient -
1089   - * @return ArrayList keyNames from profile attr resources shared!!!! && IsWritable
  1099 + * @return ArrayList keyNames from profile profileAttr && IsWritable
1090 1100 */
1091 1101 private List<String> getNamesAttrFromProfileIsWritable(LwM2mClient lwM2MClient) {
1092 1102 LwM2mClientProfile profile = lwM2mClientContext.getProfile(lwM2MClient.getProfileId());
1093   - Set<String> attrSet = new Gson().fromJson(profile.getPostAttributeProfile(), new TypeToken<>() {}.getType());
1094   - ConcurrentMap<String, String> keyNamesMap = new Gson().fromJson(profile.getPostKeyNameProfile().toString(), new TypeToken<ConcurrentHashMap<String, String>>() {}.getType());
  1103 + Set<String> attrSet = new Gson().fromJson(profile.getPostAttributeProfile(),
  1104 + new TypeToken<HashSet<String>>() {
  1105 + }.getType());
  1106 + ConcurrentMap<String, String> keyNamesMap = new Gson().fromJson(profile.getPostKeyNameProfile().toString(),
  1107 + new TypeToken<ConcurrentHashMap<String, String>>() {
  1108 + }.getType());
1095 1109
1096 1110 ConcurrentMap<String, String> keyNamesIsWritable = keyNamesMap.entrySet()
1097 1111 .stream()
1098   - .filter(e -> (attrSet.contains(e.getKey()) && lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(e.getKey())) != null &&
1099   - lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(e.getKey())).operations.isWritable()))
  1112 + .filter(e -> (attrSet.contains(e.getKey()) && resourceIsWritable(lwM2MClient.getRegistration(), e.getKey())))
1100 1113 .collect(Collectors.toConcurrentMap(Map.Entry::getKey, Map.Entry::getValue));
1101 1114
1102 1115 Set<String> namesIsWritable = ConcurrentHashMap.newKeySet();
1103 1116 namesIsWritable.addAll(new HashSet<>(keyNamesIsWritable.values()));
1104 1117 return new ArrayList<>(namesIsWritable);
1105 1118 }
  1119 +
  1120 + private boolean resourceIsWritable(Registration registration, String pathKey) {
  1121 + return validateResourceInModelByVer(registration, pathKey) &&
  1122 + lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(registration,
  1123 + new LwM2mPath(convertToObjectIdFromIdVer(pathKey))).operations.isWritable();
  1124 + }
  1125 +
  1126 + private boolean validateResourceInModelByVer(Registration registration, String pathKey) {
  1127 + Integer objectId = validateObjectIdFromKey(pathKey);
  1128 + String objectVer = validateObjectVerFromKey(pathKey);
  1129 + LwM2mPath lwM2mPath = new LwM2mPath(convertToObjectIdFromIdVer(pathKey));
  1130 + return objectId != null && objectVer != null && objectVer.equals(registration.getSupportedVersion(objectId)) &&
  1131 + lwM2mTransportContextServer.getLwM2MTransportConfigServer().getResourceModel(registration, lwM2mPath) != null;
  1132 + }
1106 1133 }
... ...
... ... @@ -32,6 +32,7 @@ import java.util.Iterator;
32 32 import java.util.Map;
33 33
34 34 import static org.thingsboard.server.common.data.ResourceType.LWM2M_MODEL;
  35 +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY;
35 36
36 37 @Slf4j
37 38 public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
... ... @@ -49,12 +50,9 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
49 50 this.lwM2mClientContext = lwM2mClientContext;
50 51 this.lwM2mTransportContextServer = lwM2mTransportContextServer;
51 52 }
52   - private String getIdVer(ObjectModel objectModel) {
53   - return objectModel.id + "##" + ((objectModel.getVersion() == null || objectModel.getVersion().isEmpty()) ? ObjectModel.DEFAULT_VERSION : objectModel.getVersion());
54   - }
55 53
56   - private String getIdVer(Integer objectId, String version) {
57   - return objectId != null ? objectId + "##" + ((version == null || version.isEmpty()) ? ObjectModel.DEFAULT_VERSION : version) : null;
  54 + private String getKeyIdVer(Integer objectId, String version) {
  55 + return objectId != null ? objectId + LWM2M_SEPARATOR_KEY + ((version == null || version.isEmpty()) ? ObjectModel.DEFAULT_VERSION : version) : null;
58 56 }
59 57
60 58 /**
... ... @@ -65,8 +63,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
65 63 */
66 64 @Override
67 65 public LwM2mModel getObjectModel(Registration registration) {
68   - return new DynamicModel(registration
69   - );
  66 + return new DynamicModel(registration);
70 67 }
71 68
72 69 private class DynamicModel implements LwM2mModel {
... ... @@ -107,7 +104,6 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
107 104 Map<Integer, String> supportedObjects = this.registration.getSupportedObject();
108 105 Collection<ObjectModel> result = new ArrayList<>(supportedObjects.size());
109 106 Iterator<Map.Entry<Integer, String>> i$ = supportedObjects.entrySet().iterator();
110   -
111 107 while (i$.hasNext()) {
112 108 Map.Entry<Integer, String> supportedObject = i$.next();
113 109 ObjectModel objectModel = this.getObjectModelDynamic(supportedObject.getKey(), supportedObject.getValue());
... ... @@ -119,7 +115,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
119 115 }
120 116
121 117 private ObjectModel getObjectModelDynamic(Integer objectId, String version) {
122   - String key = getIdVer(objectId, version);
  118 + String key = getKeyIdVer(objectId, version);
123 119 String xmlB64 = lwM2mTransportContextServer.getTransportResourceCache().get(
124 120 this.tenantId,
125 121 LWM2M_MODEL,
... ...
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 lombok.extern.slf4j.Slf4j;
19   -import org.eclipse.leshan.core.util.Hex;
20   -import org.eclipse.leshan.server.registration.Registration;
21   -import org.eclipse.leshan.server.security.InMemorySecurityStore;
22   -import org.eclipse.leshan.server.security.SecurityInfo;
23   -import org.eclipse.leshan.server.security.SecurityStoreListener;
24   -import org.springframework.beans.factory.annotation.Autowired;
25   -import org.thingsboard.server.common.data.DeviceProfile;
26   -import org.thingsboard.server.gen.transport.TransportProtos;
27   -import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
28   -import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
29   -import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore;
30   -import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler;
31   -import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
32   -import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile;
33   -import org.thingsboard.server.transport.lwm2m.utils.TypeServer;
34   -
35   -import java.util.Collection;
36   -import java.util.List;
37   -import java.util.Map;
38   -import java.util.UUID;
39   -import java.util.concurrent.ConcurrentHashMap;
40   -import java.util.concurrent.locks.Lock;
41   -import java.util.concurrent.locks.ReadWriteLock;
42   -import java.util.concurrent.locks.ReentrantReadWriteLock;
43   -import java.util.stream.Collectors;
44   -
45   -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC;
46   -
47   -@Slf4j
48   -//@Service("LwM2mInMemorySecurityStore")
49   -//@TbLwM2mTransportComponent
50   -@Deprecated
51   -public class LwM2mInMemorySecurityStore extends InMemorySecurityStore {
52   - private static final boolean INFOS_ARE_COMPROMISED = false;
53   -
54   - // lock for the two maps
55   - private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
56   - private final Lock readLock = readWriteLock.readLock();
57   - private final Lock writeLock = readWriteLock.writeLock();
58   - private final Map<String /** registrationId */, LwM2mClient> sessions = new ConcurrentHashMap<>();
59   - private Map<UUID /** profileUUid */, LwM2mClientProfile> profiles = new ConcurrentHashMap<>();
60   - private SecurityStoreListener listener;
61   -
62   - @Autowired
63   - LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator;
64   -
65   - /**
66   - * Start after DefaultAuthorizer or LwM2mPskStore
67   - * @param endPoint -
68   - * @return SecurityInfo
69   - */
70   - @Override
71   - public SecurityInfo getByEndpoint(String endPoint) {
72   - readLock.lock();
73   - try {
74   - String registrationId = this.getRegistrationId(endPoint, null);
75   - return (registrationId != null && sessions.size() > 0 && sessions.get(registrationId) != null) ?
76   - sessions.get(registrationId).getSecurityInfo() : this.addLwM2MClientToSession(endPoint);
77   - } finally {
78   - readLock.unlock();
79   - }
80   - }
81   -
82   - /**
83   - * Start after LwM2mPskStore
84   - * @param identity -
85   - * @return SecurityInfo
86   - */
87   - @Override
88   - public SecurityInfo getByIdentity(String identity) {
89   - readLock.lock();
90   - try {
91   - String integrationId = this.getRegistrationId(null, identity);
92   - return (integrationId != null) ? sessions.get(integrationId).getSecurityInfo() : this.addLwM2MClientToSession(identity);
93   - } finally {
94   - readLock.unlock();
95   - }
96   - }
97   -
98   - @Override
99   - public Collection<SecurityInfo> getAll() {
100   - readLock.lock();
101   - try {
102   - return this.sessions.values().stream().map(LwM2mClient::getSecurityInfo).collect(Collectors.toUnmodifiableList());
103   - } finally {
104   - readLock.unlock();
105   - }
106   - }
107   -
108   - /**
109   - * Removed registration Client from sessions and listener
110   - * @param registrationId if Client
111   - */
112   - public void delRemoveSessionAndListener(String registrationId) {
113   - writeLock.lock();
114   - try {
115   - LwM2mClient lwM2MClient = (sessions.get(registrationId) != null) ? sessions.get(registrationId) : null;
116   - if (lwM2MClient != null) {
117   - if (listener != null) {
118   - listener.securityInfoRemoved(INFOS_ARE_COMPROMISED, lwM2MClient.getSecurityInfo());
119   - }
120   - sessions.remove(registrationId);
121   - }
122   - } finally {
123   - writeLock.unlock();
124   - }
125   - }
126   -
127   - @Override
128   - public void setListener(SecurityStoreListener listener) {
129   - this.listener = listener;
130   - }
131   -
132   - public LwM2mClient getLwM2MClient(String endPoint, String identity) {
133   - Map.Entry<String, LwM2mClient> modelClients = endPoint != null ?
134   - this.sessions.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndpoint())).findAny().orElse(null) :
135   - this.sessions.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).findAny().orElse(null);
136   - return modelClients != null ? modelClients.getValue() : null;
137   - }
138   -
139   - public LwM2mClient getLwM2MClientWithReg(Registration registration, String registrationId) {
140   - return registrationId != null ?
141   - this.sessions.get(registrationId) :
142   - this.sessions.containsKey(registration.getId()) ?
143   - this.sessions.get(registration.getId()) :
144   - this.sessions.get(registration.getEndpoint());
145   - }
146   -
147   - public LwM2mClient getLwM2MClient(TransportProtos.SessionInfoProto sessionInfo) {
148   - return this.getSession(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).entrySet().iterator().next().getValue();
149   - }
150   -
151   - /**
152   - * Update in sessions (LwM2MClient for key registration_Id) after starting registration LwM2MClient in LwM2MTransportServiceImpl
153   - * Remove from sessions LwM2MClient with key registration_Endpoint
154   - * @param registration -
155   - * @return LwM2MClient after adding it to session
156   - */
157   - public LwM2mClient updateInSessionsLwM2MClient(Registration registration) {
158   - writeLock.lock();
159   - try {
160   - if (this.sessions.get(registration.getEndpoint()) == null) {
161   - this.addLwM2MClientToSession(registration.getEndpoint());
162   - }
163   - LwM2mClient lwM2MClient = this.sessions.get(registration.getEndpoint());
164   - lwM2MClient.setRegistration(registration);
165   -// lwM2MClient.getAttributes().putAll(registration.getAdditionalRegistrationAttributes());
166   - this.sessions.remove(registration.getEndpoint());
167   - this.sessions.put(registration.getId(), lwM2MClient);
168   - return lwM2MClient;
169   - } finally {
170   - writeLock.unlock();
171   - }
172   - }
173   -
174   - private String getRegistrationId(String endPoint, String identity) {
175   - List<String> registrationIds = (endPoint != null) ?
176   - this.sessions.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndpoint())).map(Map.Entry::getKey).collect(Collectors.toList()) :
177   - this.sessions.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).map(Map.Entry::getKey).collect(Collectors.toList());
178   - return (registrationIds != null && registrationIds.size() > 0) ? registrationIds.get(0) : null;
179   - }
180   -
181   - public Registration getByRegistration(String registrationId) {
182   - return this.sessions.get(registrationId).getRegistration();
183   - }
184   -
185   - /**
186   - * Add new LwM2MClient to session
187   - * @param identity-
188   - * @return SecurityInfo. If error - SecurityInfoError
189   - * and log:
190   - * - FORBIDDEN - if there is no authorization
191   - * - profileUuid - if the device does not have a profile
192   - * - device - if the thingsboard does not have a device with a name equal to the identity
193   - */
194   - private SecurityInfo addLwM2MClientToSession(String identity) {
195   - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, TypeServer.CLIENT);
196   - if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
197   - UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null;
198   - if (store.getSecurityInfo() != null && profileUuid != null) {
199   - String endpoint = store.getSecurityInfo().getEndpoint();
200   - sessions.put(endpoint, new LwM2mClient(endpoint, store.getSecurityInfo().getIdentity(), store.getSecurityInfo(), store.getMsg(), profileUuid, UUID.randomUUID()));
201   - } else if (store.getSecurityMode() == NO_SEC.code && profileUuid != null) {
202   - sessions.put(identity, new LwM2mClient(identity, null, null, store.getMsg(), profileUuid, UUID.randomUUID()));
203   - } else {
204   - log.error("Registration failed: FORBIDDEN/profileUuid/device [{}] , endpointId: [{}]", profileUuid, identity);
205   - /**
206   - * Return Error securityInfo
207   - */
208   - byte[] preSharedKey = Hex.decodeHex("0A0B".toCharArray());
209   - SecurityInfo infoError = SecurityInfo.newPreSharedKeyInfo("error", "error_identity", preSharedKey);
210   - return infoError;
211   - }
212   - }
213   - return store.getSecurityInfo();
214   - }
215   -
216   - public Map<String, LwM2mClient> getSession(UUID sessionUuId) {
217   - return this.sessions.entrySet().stream()
218   - .filter(e -> e.getValue().getSessionId().equals(sessionUuId))
219   - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
220   - }
221   -
222   - public Map<String, LwM2mClient> getSessions() {
223   - return this.sessions;
224   - }
225   -
226   - public Map<UUID, LwM2mClientProfile> getProfiles() {
227   - return this.profiles;
228   - }
229   -
230   - public LwM2mClientProfile getProfile(UUID profileUuId) {
231   - return this.profiles.get(profileUuId);
232   - }
233   -
234   - public LwM2mClientProfile getProfile(String registrationId) {
235   - UUID profileUUid = this.getSessions().get(registrationId).getProfileId();
236   - return this.getProfiles().get(profileUUid);
237   - }
238   -
239   - public Map<UUID, LwM2mClientProfile> setProfiles(Map<UUID, LwM2mClientProfile> profiles) {
240   - return this.profiles = profiles;
241   - }
242   -
243   - public boolean addUpdateProfileParameters(DeviceProfile deviceProfile) {
244   - LwM2mClientProfile lwM2MClientProfile = LwM2mTransportHandler.getLwM2MClientProfileFromThingsboard(deviceProfile);
245   - if (lwM2MClientProfile != null) {
246   - profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile);
247   - return true;
248   - }
249   - return false;
250   - }
251   -}
... ... @@ -29,6 +29,7 @@ import org.springframework.context.annotation.Lazy;
29 29 import org.springframework.stereotype.Service;
30 30 import org.thingsboard.server.cache.TBRedisCacheConfiguration;
31 31 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
  32 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
32 33 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
33 34
34 35 import java.util.Collection;
... ... @@ -89,10 +90,14 @@ public class TbLwM2mStoreConfiguration {
89 90 }
90 91
91 92 @Override
92   - public SecurityInfo getByEndpoint(String endpoint) {
93   - SecurityInfo securityInfo = securityStore.getByEndpoint(endpoint);
  93 + public SecurityInfo getByEndpoint(String endPoint) {
  94 + SecurityInfo securityInfo = securityStore.getByEndpoint(endPoint);
94 95 if (securityInfo == null) {
95   - securityInfo = clientContext.addLwM2mClientToSession(endpoint).getSecurityInfo();
  96 + LwM2mClient lwM2mClient = clientContext.getLwM2MClient(endPoint, null);
  97 + if (lwM2mClient != null && !lwM2mClient.getRegistration().getIdentity().isSecure()){
  98 + return null;
  99 + }
  100 + securityInfo = clientContext.addLwM2mClientToSession(endPoint).getSecurityInfo();
96 101 try {
97 102 if (securityInfo != null) {
98 103 add(securityInfo);
... ...
... ... @@ -466,7 +466,6 @@ public class ModelConstants {
466 466 public static final String RESOURCE_TITLE_COLUMN = TITLE_PROPERTY;
467 467 public static final String RESOURCE_DATA_COLUMN = "data";
468 468
469   -
470 469 /**
471 470 * Cassandra attributes and timeseries constants.
472 471 */
... ...
... ... @@ -65,7 +65,8 @@ public class TbResourceEntity extends BaseSqlEntity<TbResource> implements Searc
65 65 }
66 66
67 67 public TbResourceEntity(TbResource resource) {
68   - this.setUuid(resource.getId().getId());
  68 + this.id = resource.getUuidId();
  69 + this.createdTime = resource.getCreatedTime();
69 70 this.tenantId = resource.getTenantId().getId();
70 71 this.title = resource.getTitle();
71 72 this.resourceType = resource.getResourceType().name();
... ...
... ... @@ -43,6 +43,8 @@ import java.util.Comparator;
43 43 import java.util.List;
44 44 import java.util.stream.Collectors;
45 45
  46 +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY;
  47 +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_SEARCH_TEXT;
46 48 import static org.thingsboard.server.dao.device.DeviceServiceImpl.INCORRECT_TENANT_ID;
47 49 import static org.thingsboard.server.dao.service.Validator.validateId;
48 50
... ... @@ -62,26 +64,24 @@ public class BaseTbResourceService implements TbResourceService {
62 64 }
63 65
64 66 @Override
65   - public TbResource saveResource(TbResource resource) throws InvalidDDFFileException, IOException {
66   - log.trace("Executing saveResource [{}]", resource);
67   -
68   - if (resource.getId() == null && ResourceType.LWM2M_MODEL.equals(resource.getResourceType())) {
  67 + public TbResource saveResource(TbResource tbResource) throws InvalidDDFFileException, IOException {
  68 + log.trace("Executing saveResource [{}]", tbResource);
  69 + if (ResourceType.LWM2M_MODEL.equals(tbResource.getResourceType())) {
69 70 List<ObjectModel> objectModels =
70   - ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(resource.getData())), resource.getSearchText());
  71 + ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(tbResource.getData())), tbResource.getSearchText());
71 72 if (!objectModels.isEmpty()) {
72 73 ObjectModel objectModel = objectModels.get(0);
73   -
74   - String resourceKey = objectModel.id + "_" + objectModel.getVersion();
  74 + String resourceKey = objectModel.id + LWM2M_SEPARATOR_KEY + objectModel.getVersion();
75 75 String name = objectModel.name;
76   - resource.setResourceKey(resourceKey);
77   - resource.setTitle(name);
78   - resource.setSearchText(resourceKey + ":" + name);
  76 + tbResource.setResourceKey(resourceKey);
  77 + tbResource.setTitle(name);
  78 + tbResource.setSearchText(resourceKey + LWM2M_SEPARATOR_SEARCH_TEXT + name);
  79 + } else {
  80 + throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", tbResource.getSearchText()));
79 81 }
80 82 }
81   -
82   - validate(resource);
83   -
84   - return resourceDao.saveResource(resource);
  83 + validate(tbResource);
  84 + return resourceDao.save(tbResource.getTenantId(), tbResource);
85 85 }
86 86
87 87 @Override
... ... @@ -162,9 +162,6 @@ public class BaseTbResourceService implements TbResourceService {
162 162 throw new DataValidationException("Resource value should be specified!");
163 163 }
164 164 validate(resource.getTenantId(), resource.getResourceType(), resource.getResourceKey());
165   - if (resource.getResourceType().equals(ResourceType.LWM2M_MODEL) && this.toLwM2mObject(resource) == null) {
166   - throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText()));
167   - }
168 165 }
169 166
170 167 protected void validate(TenantId tenantId, ResourceType resourceType, String resourceId) {
... ...
... ... @@ -26,8 +26,6 @@ import java.util.List;
26 26
27 27 public interface TbResourceDao extends Dao<TbResource> {
28 28
29   - TbResource saveResource(TbResource resource);
30   -
31 29 TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId);
32 30
33 31 PageData<TbResource> findAllByTenantId(TenantId tenantId, PageLink pageLink);
... ...
... ... @@ -18,7 +18,6 @@ package org.thingsboard.server.dao.sql.resource;
18 18 import lombok.extern.slf4j.Slf4j;
19 19 import org.springframework.data.repository.CrudRepository;
20 20 import org.springframework.stereotype.Component;
21   -import org.springframework.transaction.annotation.Transactional;
22 21 import org.thingsboard.server.common.data.ResourceType;
23 22 import org.thingsboard.server.common.data.TbResource;
24 23 import org.thingsboard.server.common.data.id.TenantId;
... ... @@ -54,12 +53,6 @@ public class JpaTbResourceDao extends JpaAbstractSearchTextDao<TbResourceEntity,
54 53 }
55 54
56 55 @Override
57   - @Transactional
58   - public TbResource saveResource(TbResource resource) {
59   - return DaoUtil.getData(resourceRepository.save(new TbResourceEntity(resource)));
60   - }
61   -
62   - @Override
63 56 public TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceKey) {
64 57
65 58 return DaoUtil.getData(resourceRepository.findByTenantIdAndResourceTypeAndResourceKey(tenantId.getId(), resourceType.name(), resourceKey));
... ...