Commit 247941bcf74d936c4479bd2c8e383a5716640360

Authored by YevhenBondarenko
Committed by Andrew Shvayka
1 parent 118a0671

fixed ObjectModel extra parsing and refactoring

... ... @@ -15,24 +15,16 @@
15 15 */
16 16 package org.thingsboard.server.transport.lwm2m.config;
17 17
18   -import com.google.common.io.Resources;
19 18 import lombok.Getter;
20 19 import lombok.Setter;
21 20 import lombok.extern.slf4j.Slf4j;
22   -import org.eclipse.leshan.server.model.LwM2mModelProvider;
23   -import org.jetbrains.annotations.NotNull;
24 21 import org.springframework.beans.factory.annotation.Value;
25 22 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
26 23 import org.springframework.stereotype.Component;
27 24 import org.thingsboard.server.common.data.ResourceUtils;
28 25
29 26 import javax.annotation.PostConstruct;
30   -import java.io.File;
31   -import java.io.FileInputStream;
32   -import java.io.FileNotFoundException;
33 27 import java.io.InputStream;
34   -import java.net.URI;
35   -import java.net.URISyntaxException;
36 28 import java.security.KeyStore;
37 29
38 30 @Slf4j
... ... @@ -41,10 +33,6 @@ import java.security.KeyStore;
41 33 public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig {
42 34
43 35 @Getter
44   - @Setter
45   - private LwM2mModelProvider modelProvider;
46   -
47   - @Getter
48 36 @Value("${transport.lwm2m.timeout:}")
49 37 private Long timeout;
50 38
... ... @@ -147,6 +135,4 @@ public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig {
147 135 }
148 136 }
149 137
150   -
151   -
152 138 }
... ...
... ... @@ -62,14 +62,13 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
62 62
63 63 private final LwM2mTransportContext context;
64 64 private final LwM2MTransportServerConfig config;
65   - private final LwM2mTransportServerHelper helper;
66 65 private final OtaPackageDataCache otaPackageDataCache;
67 66 private final DefaultLwM2MUplinkMsgHandler handler;
68 67 private final CaliforniumRegistrationStore registrationStore;
69 68 private final TbSecurityStore securityStore;
70   - private final LwM2mClientContext lwM2mClientContext;
71 69 private final TbLwM2MDtlsCertificateVerifier certificateVerifier;
72 70 private final TbLwM2MAuthorizer authorizer;
  71 + private final LwM2mVersionedModelProvider modelProvider;
73 72
74 73 private LeshanServer server;
75 74
... ... @@ -118,8 +117,6 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
118 117 builder.setCoapConfig(getCoapConfig(config.getPort(), config.getSecurePort(), config));
119 118
120 119 /* Define model provider (Create Models )*/
121   - LwM2mModelProvider modelProvider = new LwM2mVersionedModelProvider(this.lwM2mClientContext, this.helper, this.context);
122   - config.setModelProvider(modelProvider);
123 120 builder.setObjectModelProvider(modelProvider);
124 121
125 122 /* Set securityStore with new registrationStore */
... ...
... ... @@ -97,15 +97,15 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s
97 97 }
98 98
99 99 @Override
100   - public void onResourceUpdate(@NotNull Optional<TransportProtos.ResourceUpdateMsg> resourceUpdateMsgOpt) {
101   - if (ResourceType.LWM2M_MODEL.name().equals(resourceUpdateMsgOpt.get().getResourceType())) {
  100 + public void onResourceUpdate(TransportProtos.ResourceUpdateMsg resourceUpdateMsgOpt) {
  101 + if (ResourceType.LWM2M_MODEL.name().equals(resourceUpdateMsgOpt.getResourceType())) {
102 102 this.handler.onResourceUpdate(resourceUpdateMsgOpt);
103 103 }
104 104 }
105 105
106 106 @Override
107   - public void onResourceDelete(@NotNull Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt) {
108   - if (ResourceType.LWM2M_MODEL.name().equals(resourceDeleteMsgOpt.get().getResourceType())) {
  107 + public void onResourceDelete(TransportProtos.ResourceDeleteMsg resourceDeleteMsgOpt) {
  108 + if (ResourceType.LWM2M_MODEL.name().equals(resourceDeleteMsgOpt.getResourceType())) {
109 109 this.handler.onResourceDelete(resourceDeleteMsgOpt);
110 110 }
111 111 }
... ...
... ... @@ -15,7 +15,6 @@
15 15 */
16 16 package org.thingsboard.server.transport.lwm2m.server;
17 17
18   -import lombok.RequiredArgsConstructor;
19 18 import lombok.extern.slf4j.Slf4j;
20 19 import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
21 20 import org.eclipse.leshan.core.model.LwM2mModel;
... ... @@ -23,8 +22,11 @@ import org.eclipse.leshan.core.model.ObjectModel;
23 22 import org.eclipse.leshan.core.model.ResourceModel;
24 23 import org.eclipse.leshan.server.model.LwM2mModelProvider;
25 24 import org.eclipse.leshan.server.registration.Registration;
  25 +import org.springframework.context.annotation.Lazy;
  26 +import org.springframework.stereotype.Service;
26 27 import org.thingsboard.server.common.data.TbResource;
27 28 import org.thingsboard.server.common.data.id.TenantId;
  29 +import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
28 30 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
29 31
30 32 import java.util.ArrayList;
... ... @@ -32,47 +34,58 @@ import java.util.Base64;
32 34 import java.util.Collection;
33 35 import java.util.Map;
34 36 import java.util.Optional;
  37 +import java.util.concurrent.ConcurrentHashMap;
  38 +import java.util.concurrent.ConcurrentMap;
  39 +import java.util.concurrent.locks.Lock;
  40 +import java.util.concurrent.locks.ReentrantLock;
35 41
36 42 import static org.thingsboard.server.common.data.ResourceType.LWM2M_MODEL;
37 43 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY;
38 44
39 45 @Slf4j
40   -@RequiredArgsConstructor
  46 +@Service
  47 +@TbLwM2mTransportComponent
41 48 public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
42 49
43   - /**
44   - * int objectId
45   - * String version ("1.01")
46   - * Key = objectId + "##" + version
47   - * Value = TenantId
48   - */
49 50 private final LwM2mClientContext lwM2mClientContext;
50 51 private final LwM2mTransportServerHelper helper;
51 52 private final LwM2mTransportContext context;
  53 + private final ConcurrentMap<TenantId, ConcurrentMap<String, ObjectModel>> models;
  54 +
  55 + public LwM2mVersionedModelProvider(@Lazy LwM2mClientContext lwM2mClientContext, LwM2mTransportServerHelper helper, LwM2mTransportContext context) {
  56 + this.lwM2mClientContext = lwM2mClientContext;
  57 + this.helper = helper;
  58 + this.context = context;
  59 + this.models = new ConcurrentHashMap<>();
  60 + }
52 61
53 62 private String getKeyIdVer(Integer objectId, String version) {
54 63 return objectId != null ? objectId + LWM2M_SEPARATOR_KEY + ((version == null || version.isEmpty()) ? ObjectModel.DEFAULT_VERSION : version) : null;
55 64 }
56 65
57   - /**
58   - * Update repository if need
59   - *
60   - * @param registration
61   - * @return
62   - */
63 66 @Override
64 67 public LwM2mModel getObjectModel(Registration registration) {
65 68 return new DynamicModel(registration);
66 69 }
67 70
68   - private class DynamicModel implements LwM2mModel {
  71 + public void evict(TenantId tenantId, String key) {
  72 + if (tenantId.isNullUid()) {
  73 + models.values().forEach(m -> m.remove(key));
  74 + } else {
  75 + models.get(tenantId).remove(key);
  76 + }
  77 + }
69 78
  79 + private class DynamicModel implements LwM2mModel {
70 80 private final Registration registration;
71 81 private final TenantId tenantId;
  82 + private final Lock modelsLock;
72 83
73 84 public DynamicModel(Registration registration) {
74 85 this.registration = registration;
75 86 this.tenantId = lwM2mClientContext.getClientByEndpoint(registration.getEndpoint()).getTenantId();
  87 + this.modelsLock = new ReentrantLock();
  88 + models.computeIfAbsent(tenantId, t -> new ConcurrentHashMap<>());
76 89 }
77 90
78 91 @Override
... ... @@ -114,6 +127,25 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
114 127
115 128 private ObjectModel getObjectModelDynamic(Integer objectId, String version) {
116 129 String key = getKeyIdVer(objectId, version);
  130 + ObjectModel objectModel = models.get(tenantId).get(key);
  131 +
  132 + if (objectModel == null) {
  133 + modelsLock.lock();
  134 + try {
  135 + objectModel = models.get(tenantId).get(key);
  136 + if (objectModel == null) {
  137 + objectModel = getObjectModel(key);
  138 + models.get(tenantId).put(key, objectModel);
  139 + }
  140 + } finally {
  141 + modelsLock.unlock();
  142 + }
  143 + }
  144 +
  145 + return objectModel;
  146 + }
  147 +
  148 + private ObjectModel getObjectModel(String key) {
117 149 Optional<TbResource> tbResource = context.getTransportResourceCache().get(this.tenantId, LWM2M_MODEL, key);
118 150 return tbResource.map(resource -> helper.parseFromXmlToObjectModel(
119 151 Base64.getDecoder().decode(resource.getData()),
... ...
... ... @@ -21,13 +21,11 @@ import lombok.Setter;
21 21 import lombok.extern.slf4j.Slf4j;
22 22 import org.eclipse.leshan.core.model.ObjectModel;
23 23 import org.eclipse.leshan.core.model.ResourceModel;
24   -import org.eclipse.leshan.core.node.LwM2mMultipleResource;
25 24 import org.eclipse.leshan.core.node.LwM2mPath;
26 25 import org.eclipse.leshan.core.node.LwM2mResource;
27 26 import org.eclipse.leshan.core.node.LwM2mSingleResource;
28 27 import org.eclipse.leshan.core.node.codec.LwM2mValueConverter;
29 28 import org.eclipse.leshan.core.request.ContentFormat;
30   -import org.eclipse.leshan.core.util.Hex;
31 29 import org.eclipse.leshan.server.model.LwM2mModelProvider;
32 30 import org.eclipse.leshan.server.registration.Registration;
33 31 import org.thingsboard.server.common.data.Device;
... ... @@ -44,7 +42,6 @@ import java.io.IOException;
44 42 import java.io.ObjectInputStream;
45 43 import java.io.Serializable;
46 44 import java.util.Collection;
47   -import java.util.HashMap;
48 45 import java.util.Map;
49 46 import java.util.Optional;
50 47 import java.util.Set;
... ... @@ -58,7 +55,6 @@ import java.util.concurrent.locks.Lock;
58 55 import java.util.concurrent.locks.ReentrantLock;
59 56 import java.util.stream.Collectors;
60 57
61   -import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE;
62 58 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
63 59 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LWM2M_OBJECT_VERSION_DEFAULT;
64 60 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertObjectIdToVersionedId;
... ... @@ -281,8 +277,6 @@ public class LwM2mClient implements Serializable {
281 277 .getObjectModel(pathIds.getObjectId()) : null;
282 278 }
283 279
284   -
285   -
286 280 public Collection<LwM2mResource> getNewResourceForInstance(String pathRezIdVer, Object params, LwM2mModelProvider modelProvider,
287 281 LwM2mValueConverter converter) {
288 282 LwM2mPath pathIds = new LwM2mPath(fromVersionedIdToObjectId(pathRezIdVer));
... ... @@ -378,7 +372,7 @@ public class LwM2mClient implements Serializable {
378 372 this.lock = new ReentrantLock();
379 373 }
380 374
381   - public long updateLastUplinkTime(){
  375 + public long updateLastUplinkTime() {
382 376 this.lastUplinkTime = System.currentTimeMillis();
383 377 this.firstEdrxDownlink = true;
384 378 return lastUplinkTime;
... ...
... ... @@ -40,6 +40,7 @@ import org.thingsboard.server.transport.lwm2m.config.LwM2mVersion;
40 40 import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo;
41 41 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
42 42 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
  43 +import org.thingsboard.server.transport.lwm2m.server.LwM2mVersionedModelProvider;
43 44 import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MOtaUpdateService;
44 45 import org.thingsboard.server.transport.lwm2m.server.session.LwM2MSessionManager;
45 46 import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MClientStore;
... ... @@ -74,6 +75,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
74 75 private final TbLwM2MClientStore clientStore;
75 76 private final LwM2MSessionManager sessionManager;
76 77 private final TransportDeviceProfileCache deviceProfileCache;
  78 + private final LwM2mVersionedModelProvider modelProvider;
77 79
78 80 @Autowired
79 81 @Lazy
... ... @@ -543,8 +545,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
543 545 }
544 546
545 547 private boolean validateResourceInModel(LwM2mClient lwM2mClient, String pathIdVer, boolean isWritableNotOptional) {
546   - ResourceModel resourceModel = lwM2mClient.getResourceModel(pathIdVer, this.config
547   - .getModelProvider());
  548 + ResourceModel resourceModel = lwM2mClient.getResourceModel(pathIdVer, modelProvider);
548 549 Integer objectId = new LwM2mPath(fromVersionedIdToObjectId(pathIdVer)).getObjectId();
549 550 String objectVer = validateObjectVerFromKey(pathIdVer);
550 551 return resourceModel != null && (isWritableNotOptional ?
... ...
... ... @@ -60,6 +60,7 @@ import org.thingsboard.server.common.data.device.data.lwm2m.ObjectAttributes;
60 60 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
61 61 import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
62 62 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
  63 +import org.thingsboard.server.transport.lwm2m.server.LwM2mVersionedModelProvider;
63 64 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
64 65 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
65 66 import org.thingsboard.server.transport.lwm2m.server.common.LwM2MExecutorAwareService;
... ... @@ -99,6 +100,7 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
99 100 private final LwM2MTransportServerConfig config;
100 101 private final LwM2MTelemetryLogService logService;
101 102 private final LwM2mClientContext clientContext;
  103 + private final LwM2mVersionedModelProvider modelProvider;
102 104
103 105 @PostConstruct
104 106 public void init() {
... ... @@ -124,7 +126,7 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
124 126 @Override
125 127 public void sendReadRequest(LwM2mClient client, TbLwM2MReadRequest request, DownlinkRequestCallback<ReadRequest, ReadResponse> callback) {
126 128 validateVersionedId(client, request);
127   - ReadRequest downlink = new ReadRequest(getRequestContentFormat(client, request, this.config.getModelProvider()), request.getObjectId());
  129 + ReadRequest downlink = new ReadRequest(getRequestContentFormat(client, request, modelProvider), request.getObjectId());
128 130 sendSimpleRequest(client, downlink, request.getTimeout(), callback);
129 131 }
130 132
... ... @@ -145,7 +147,7 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
145 147 Set<Observation> observations = context.getServer().getObservationService().getObservations(client.getRegistration());
146 148 if (observations.stream().noneMatch(observation -> observation.getPath().equals(resultIds))) {
147 149 ObserveRequest downlink;
148   - ContentFormat contentFormat = getRequestContentFormat(client, request, this.config.getModelProvider());
  150 + ContentFormat contentFormat = getRequestContentFormat(client, request, modelProvider);
149 151 if (resultIds.isResource()) {
150 152 downlink = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId());
151 153 } else if (resultIds.isObjectInstance()) {
... ... @@ -174,7 +176,7 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
174 176
175 177 @Override
176 178 public void sendExecuteRequest(LwM2mClient client, TbLwM2MExecuteRequest request, DownlinkRequestCallback<ExecuteRequest, ExecuteResponse> callback) {
177   - ResourceModel resourceModelExecute = client.getResourceModel(request.getVersionedId(), this.config.getModelProvider());
  179 + ResourceModel resourceModelExecute = client.getResourceModel(request.getVersionedId(), modelProvider);
178 180 if (resourceModelExecute != null) {
179 181 ExecuteRequest downlink;
180 182 if (request.getParams() != null && !resourceModelExecute.multiple) {
... ... @@ -231,7 +233,7 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
231 233
232 234 @Override
233 235 public void sendWriteReplaceRequest(LwM2mClient client, TbLwM2MWriteReplaceRequest request, DownlinkRequestCallback<WriteRequest, WriteResponse> callback) {
234   - ResourceModel resourceModelWrite = client.getResourceModel(request.getVersionedId(), this.config.getModelProvider());
  236 + ResourceModel resourceModelWrite = client.getResourceModel(request.getVersionedId(), modelProvider);
235 237 if (resourceModelWrite != null) {
236 238 ContentFormat contentFormat = convertResourceModelTypeToContentFormat(client, resourceModelWrite.type);
237 239 try {
... ... @@ -267,8 +269,8 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
267 269 * send request: path = '/3/0' node == wM2mObjectInstance
268 270 * with params == "\"resources\": {15: resource:{id:15. value:'+01'...}}
269 271 **/
270   - Collection<LwM2mResource> resources = client.getNewResourceForInstance(request.getVersionedId(), request.getValue(), this.config.getModelProvider(), this.converter);
271   - ResourceModel resourceModelWrite = client.getResourceModel(request.getVersionedId(), this.config.getModelProvider());
  272 + Collection<LwM2mResource> resources = client.getNewResourceForInstance(request.getVersionedId(), request.getValue(), modelProvider, this.converter);
  273 + ResourceModel resourceModelWrite = client.getResourceModel(request.getVersionedId(), modelProvider);
272 274 ContentFormat contentFormat = request.getObjectContentFormat() != null ? request.getObjectContentFormat() : convertResourceModelTypeToContentFormat(client, resourceModelWrite.type);
273 275 WriteRequest downlink = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(),
274 276 resultIds.getObjectInstanceId(), resources);
... ... @@ -279,7 +281,7 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
279 281 * int rscId = resultIds.getObjectInstanceId();
280 282 * contentFormat – Format of the payload (TLV or JSON).
281 283 */
282   - Collection<LwM2mResource> resources = client.getNewResourcesForInstance(request.getVersionedId(), request.getValue(), this.config.getModelProvider(), this.converter);
  284 + Collection<LwM2mResource> resources = client.getNewResourcesForInstance(request.getVersionedId(), request.getValue(), modelProvider, this.converter);
283 285 if (resources.size() > 0) {
284 286 ContentFormat contentFormat = request.getObjectContentFormat() != null ? request.getObjectContentFormat() : ContentFormat.DEFAULT;
285 287 WriteRequest downlink = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resources);
... ...
... ... @@ -46,6 +46,7 @@ import org.thingsboard.server.common.data.device.data.lwm2m.ObjectAttributes;
46 46 import org.thingsboard.server.common.data.device.data.lwm2m.OtherConfiguration;
47 47 import org.thingsboard.server.common.data.device.data.lwm2m.TelemetryMappingConfiguration;
48 48 import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
  49 +import org.thingsboard.server.common.data.id.TenantId;
49 50 import org.thingsboard.server.common.data.ota.OtaPackageUtil;
50 51 import org.thingsboard.server.common.transport.TransportService;
51 52 import org.thingsboard.server.common.transport.TransportServiceCallback;
... ... @@ -57,6 +58,7 @@ import org.thingsboard.server.transport.lwm2m.server.LwM2mOtaConvert;
57 58 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
58 59 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper;
59 60 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
  61 +import org.thingsboard.server.transport.lwm2m.server.LwM2mVersionedModelProvider;
60 62 import org.thingsboard.server.transport.lwm2m.server.attributes.LwM2MAttributesService;
61 63 import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClientState;
62 64 import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClientStateException;
... ... @@ -139,8 +141,8 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
139 141 private final LwM2mTransportServerHelper helper;
140 142 private final TbLwM2MDtlsSessionStore sessionStore;
141 143 private final LwM2mClientContext clientContext;
142   - private final LwM2MRpcRequestHandler rpcHandler;
143 144 private final LwM2mDownlinkMsgHandler defaultLwM2MDownlinkMsgHandler;
  145 + private final LwM2mVersionedModelProvider modelProvider;
144 146
145 147 public DefaultLwM2MUplinkMsgHandler(TransportService transportService,
146 148 LwM2MTransportServerConfig config,
... ... @@ -150,9 +152,10 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
150 152 LwM2MSessionManager sessionManager,
151 153 @Lazy LwM2MOtaUpdateService otaService,
152 154 @Lazy LwM2MAttributesService attributesService,
153   - @Lazy LwM2MRpcRequestHandler rpcHandler,
154 155 @Lazy LwM2mDownlinkMsgHandler defaultLwM2MDownlinkMsgHandler,
155   - LwM2mTransportContext context, TbLwM2MDtlsSessionStore sessionStore) {
  156 + LwM2mTransportContext context,
  157 + TbLwM2MDtlsSessionStore sessionStore,
  158 + LwM2mVersionedModelProvider modelProvider) {
156 159 this.transportService = transportService;
157 160 this.sessionManager = sessionManager;
158 161 this.attributesService = attributesService;
... ... @@ -161,10 +164,10 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
161 164 this.helper = helper;
162 165 this.clientContext = clientContext;
163 166 this.logService = logService;
164   - this.rpcHandler = rpcHandler;
165 167 this.defaultLwM2MDownlinkMsgHandler = defaultLwM2MDownlinkMsgHandler;
166 168 this.context = context;
167 169 this.sessionStore = sessionStore;
  170 + this.modelProvider = modelProvider;
168 171 }
169 172
170 173 @PostConstruct
... ... @@ -309,7 +312,7 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
309 312 public void onUpdateValueAfterReadResponse(Registration registration, String path, ReadResponse response) {
310 313 if (response.getContent() != null) {
311 314 LwM2mClient lwM2MClient = clientContext.getClientByEndpoint(registration.getEndpoint());
312   - ObjectModel objectModelVersion = lwM2MClient.getObjectModel(path, this.config.getModelProvider());
  315 + ObjectModel objectModelVersion = lwM2MClient.getObjectModel(path, modelProvider);
313 316 if (objectModelVersion != null) {
314 317 if (response.getContent() instanceof LwM2mObject) {
315 318 LwM2mObject lwM2mObject = (LwM2mObject) response.getContent();
... ... @@ -388,15 +391,19 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
388 391 }
389 392
390 393 @Override
391   - public void onResourceUpdate(Optional<TransportProtos.ResourceUpdateMsg> resourceUpdateMsgOpt) {
392   - String idVer = resourceUpdateMsgOpt.get().getResourceKey();
393   - clientContext.getLwM2mClients().forEach(e -> e.updateResourceModel(idVer, this.config.getModelProvider()));
  394 + public void onResourceUpdate(TransportProtos.ResourceUpdateMsg resourceUpdateMsgOpt) {
  395 + String idVer = resourceUpdateMsgOpt.getResourceKey();
  396 + TenantId tenantId = new TenantId(new UUID(resourceUpdateMsgOpt.getTenantIdMSB(), resourceUpdateMsgOpt.getTenantIdLSB()));
  397 + modelProvider.evict(tenantId, idVer);
  398 + clientContext.getLwM2mClients().forEach(e -> e.updateResourceModel(idVer, modelProvider));
394 399 }
395 400
396 401 @Override
397   - public void onResourceDelete(Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt) {
398   - String pathIdVer = resourceDeleteMsgOpt.get().getResourceKey();
399   - clientContext.getLwM2mClients().forEach(e -> e.deleteResources(pathIdVer, this.config.getModelProvider()));
  402 + public void onResourceDelete(TransportProtos.ResourceDeleteMsg resourceDeleteMsgOpt) {
  403 + String pathIdVer = resourceDeleteMsgOpt.getResourceKey();
  404 + TenantId tenantId = new TenantId(new UUID(resourceDeleteMsgOpt.getTenantIdMSB(), resourceDeleteMsgOpt.getTenantIdLSB()));
  405 + modelProvider.evict(tenantId, pathIdVer);
  406 + clientContext.getLwM2mClients().forEach(e -> e.deleteResources(pathIdVer, modelProvider));
400 407 }
401 408
402 409 /**
... ... @@ -544,7 +551,7 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
544 551 */
545 552 private void updateResourcesValue(LwM2mClient lwM2MClient, LwM2mResource lwM2mResource, String path) {
546 553 Registration registration = lwM2MClient.getRegistration();
547   - if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.config.getModelProvider())) {
  554 + if (lwM2MClient.saveResourceValue(path, lwM2mResource, modelProvider)) {
548 555 if (path.equals(convertObjectIdToVersionedId(FW_NAME_ID, registration))) {
549 556 otaService.onCurrentFirmwareNameUpdate(lwM2MClient, (String) lwM2mResource.getValue());
550 557 } else if (path.equals(convertObjectIdToVersionedId(FW_3_VER_ID, registration))) {
... ...
... ... @@ -48,9 +48,9 @@ public interface LwM2mUplinkMsgHandler {
48 48
49 49 void onDeviceUpdate(TransportProtos.SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt);
50 50
51   - void onResourceUpdate(Optional<TransportProtos.ResourceUpdateMsg> resourceUpdateMsgOpt);
  51 + void onResourceUpdate(TransportProtos.ResourceUpdateMsg resourceUpdateMsgOpt);
52 52
53   - void onResourceDelete(Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt);
  53 + void onResourceDelete(TransportProtos.ResourceDeleteMsg resourceDeleteMsgOpt);
54 54
55 55 void onAwakeDev(Registration registration);
56 56
... ...
... ... @@ -56,7 +56,7 @@ public interface SessionMsgListener {
56 56
57 57 default void onDeviceDeleted(DeviceId deviceId) {}
58 58
59   - default void onResourceUpdate(Optional<TransportProtos.ResourceUpdateMsg> resourceUpdateMsgOpt) {}
  59 + default void onResourceUpdate(TransportProtos.ResourceUpdateMsg resourceUpdateMsgOpt) {}
60 60
61   - default void onResourceDelete(Optional<TransportProtos.ResourceDeleteMsg> resourceUpdateMsgOpt) {}
  61 + default void onResourceDelete(TransportProtos.ResourceDeleteMsg resourceUpdateMsgOpt) {}
62 62 }
... ...
... ... @@ -908,7 +908,7 @@ public class DefaultTransportService implements TransportService {
908 908 transportResourceCache.update(tenantId, resourceType, resourceId);
909 909 sessions.forEach((id, mdRez) -> {
910 910 log.warn("ResourceUpdate - [{}] [{}]", id, mdRez);
911   - transportCallbackExecutor.submit(() -> mdRez.getListener().onResourceUpdate(Optional.ofNullable(msg)));
  911 + transportCallbackExecutor.submit(() -> mdRez.getListener().onResourceUpdate(msg));
912 912 });
913 913
914 914 } else if (toSessionMsg.hasResourceDeleteMsg()) {
... ... @@ -919,7 +919,7 @@ public class DefaultTransportService implements TransportService {
919 919 transportResourceCache.evict(tenantId, resourceType, resourceId);
920 920 sessions.forEach((id, mdRez) -> {
921 921 log.warn("ResourceDelete - [{}] [{}]", id, mdRez);
922   - transportCallbackExecutor.submit(() -> mdRez.getListener().onResourceDelete(Optional.ofNullable(msg)));
  922 + transportCallbackExecutor.submit(() -> mdRez.getListener().onResourceDelete(msg));
923 923 });
924 924 } else {
925 925 //TODO: should we notify the device actor about missed session?
... ...