Commit 247941bcf74d936c4479bd2c8e383a5716640360
Committed by
Andrew Shvayka
1 parent
118a0671
fixed ObjectModel extra parsing and refactoring
Showing
11 changed files
with
90 additions
and
71 deletions
... | ... | @@ -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? | ... | ... |