Commit 43fe84a2840cfb25d6b36ffe9ef73ce9473ef71f

Authored by Yevhen Bondarenko
Committed by GitHub
1 parent e2dd5b96

created TransportResourceCache (#4232)

* created TransportResourceCache

* return resource by sysadmin if not found by tenant in DefaultTransportApiService
Showing 19 changed files with 227 additions and 84 deletions
@@ -27,8 +27,8 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; @@ -27,8 +27,8 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
27 import org.thingsboard.server.common.data.id.TenantId; 27 import org.thingsboard.server.common.data.id.TenantId;
28 import org.thingsboard.server.common.data.page.PageData; 28 import org.thingsboard.server.common.data.page.PageData;
29 import org.thingsboard.server.common.data.page.PageLink; 29 import org.thingsboard.server.common.data.page.PageLink;
30 -import org.thingsboard.server.common.data.transport.resource.Resource;  
31 -import org.thingsboard.server.common.data.transport.resource.ResourceType; 30 +import org.thingsboard.server.common.data.Resource;
  31 +import org.thingsboard.server.common.data.ResourceType;
32 import org.thingsboard.server.dao.resource.ResourceService; 32 import org.thingsboard.server.dao.resource.ResourceService;
33 import org.thingsboard.server.queue.util.TbCoreComponent; 33 import org.thingsboard.server.queue.util.TbCoreComponent;
34 34
@@ -28,8 +28,8 @@ import org.thingsboard.server.common.data.id.TenantId; @@ -28,8 +28,8 @@ import org.thingsboard.server.common.data.id.TenantId;
28 import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate; 28 import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate;
29 import org.thingsboard.server.common.data.rule.RuleChain; 29 import org.thingsboard.server.common.data.rule.RuleChain;
30 import org.thingsboard.server.common.data.rule.RuleChainMetaData; 30 import org.thingsboard.server.common.data.rule.RuleChainMetaData;
31 -import org.thingsboard.server.common.data.transport.resource.Resource;  
32 -import org.thingsboard.server.common.data.transport.resource.ResourceType; 31 +import org.thingsboard.server.common.data.Resource;
  32 +import org.thingsboard.server.common.data.ResourceType;
33 import org.thingsboard.server.common.data.widget.WidgetType; 33 import org.thingsboard.server.common.data.widget.WidgetType;
34 import org.thingsboard.server.common.data.widget.WidgetsBundle; 34 import org.thingsboard.server.common.data.widget.WidgetsBundle;
35 import org.thingsboard.server.dao.dashboard.DashboardService; 35 import org.thingsboard.server.dao.dashboard.DashboardService;
@@ -34,7 +34,7 @@ import org.thingsboard.server.common.data.id.EntityId; @@ -34,7 +34,7 @@ import org.thingsboard.server.common.data.id.EntityId;
34 import org.thingsboard.server.common.data.id.RuleChainId; 34 import org.thingsboard.server.common.data.id.RuleChainId;
35 import org.thingsboard.server.common.data.id.TenantId; 35 import org.thingsboard.server.common.data.id.TenantId;
36 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; 36 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
37 -import org.thingsboard.server.common.data.transport.resource.Resource; 37 +import org.thingsboard.server.common.data.Resource;
38 import org.thingsboard.server.common.msg.TbMsg; 38 import org.thingsboard.server.common.msg.TbMsg;
39 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; 39 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
40 import org.thingsboard.server.common.msg.queue.ServiceType; 40 import org.thingsboard.server.common.msg.queue.ServiceType;
@@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.TenantProfile; @@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.TenantProfile;
24 import org.thingsboard.server.common.data.id.EntityId; 24 import org.thingsboard.server.common.data.id.EntityId;
25 import org.thingsboard.server.common.data.id.TenantId; 25 import org.thingsboard.server.common.data.id.TenantId;
26 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; 26 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
27 -import org.thingsboard.server.common.data.transport.resource.Resource; 27 +import org.thingsboard.server.common.data.Resource;
28 import org.thingsboard.server.common.msg.TbMsg; 28 import org.thingsboard.server.common.msg.TbMsg;
29 import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; 29 import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
30 import org.thingsboard.server.gen.transport.TransportProtos; 30 import org.thingsboard.server.gen.transport.TransportProtos;
@@ -39,12 +39,11 @@ import org.thingsboard.server.common.data.id.CustomerId; @@ -39,12 +39,11 @@ import org.thingsboard.server.common.data.id.CustomerId;
39 import org.thingsboard.server.common.data.id.DeviceId; 39 import org.thingsboard.server.common.data.id.DeviceId;
40 import org.thingsboard.server.common.data.id.DeviceProfileId; 40 import org.thingsboard.server.common.data.id.DeviceProfileId;
41 import org.thingsboard.server.common.data.id.TenantId; 41 import org.thingsboard.server.common.data.id.TenantId;
42 -import org.thingsboard.server.common.data.page.PageLink;  
43 import org.thingsboard.server.common.data.relation.EntityRelation; 42 import org.thingsboard.server.common.data.relation.EntityRelation;
44 import org.thingsboard.server.common.data.security.DeviceCredentials; 43 import org.thingsboard.server.common.data.security.DeviceCredentials;
45 import org.thingsboard.server.common.data.security.DeviceCredentialsType; 44 import org.thingsboard.server.common.data.security.DeviceCredentialsType;
46 -import org.thingsboard.server.common.data.transport.resource.Resource;  
47 -import org.thingsboard.server.common.data.transport.resource.ResourceType; 45 +import org.thingsboard.server.common.data.Resource;
  46 +import org.thingsboard.server.common.data.ResourceType;
48 import org.thingsboard.server.common.msg.EncryptionUtil; 47 import org.thingsboard.server.common.msg.EncryptionUtil;
49 import org.thingsboard.server.common.msg.TbMsg; 48 import org.thingsboard.server.common.msg.TbMsg;
50 import org.thingsboard.server.common.msg.TbMsgDataType; 49 import org.thingsboard.server.common.msg.TbMsgDataType;
@@ -65,7 +64,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequ @@ -65,7 +64,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequ
65 import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg; 64 import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg;
66 import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; 65 import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg;
67 import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayResponseMsg; 66 import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayResponseMsg;
68 -import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesRequestMsg; 67 +import org.thingsboard.server.gen.transport.TransportProtos.GetResourceRequestMsg;
69 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; 68 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg;
70 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionResponseStatus; 69 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionResponseStatus;
71 import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg; 70 import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg;
@@ -82,14 +81,11 @@ import org.thingsboard.server.service.profile.TbDeviceProfileCache; @@ -82,14 +81,11 @@ import org.thingsboard.server.service.profile.TbDeviceProfileCache;
82 import org.thingsboard.server.service.queue.TbClusterService; 81 import org.thingsboard.server.service.queue.TbClusterService;
83 import org.thingsboard.server.service.state.DeviceStateService; 82 import org.thingsboard.server.service.state.DeviceStateService;
84 83
85 -import java.util.Collections;  
86 -import java.util.List;  
87 import java.util.UUID; 84 import java.util.UUID;
88 import java.util.concurrent.ConcurrentHashMap; 85 import java.util.concurrent.ConcurrentHashMap;
89 import java.util.concurrent.ConcurrentMap; 86 import java.util.concurrent.ConcurrentMap;
90 import java.util.concurrent.locks.Lock; 87 import java.util.concurrent.locks.Lock;
91 import java.util.concurrent.locks.ReentrantLock; 88 import java.util.concurrent.locks.ReentrantLock;
92 -import java.util.stream.Collectors;  
93 89
94 /** 90 /**
95 * Created by ashvayka on 05.10.18. 91 * Created by ashvayka on 05.10.18.
@@ -167,8 +163,8 @@ public class DefaultTransportApiService implements TransportApiService { @@ -167,8 +163,8 @@ public class DefaultTransportApiService implements TransportApiService {
167 } else if (transportApiRequestMsg.hasProvisionDeviceRequestMsg()) { 163 } else if (transportApiRequestMsg.hasProvisionDeviceRequestMsg()) {
168 return Futures.transform(handle(transportApiRequestMsg.getProvisionDeviceRequestMsg()), 164 return Futures.transform(handle(transportApiRequestMsg.getProvisionDeviceRequestMsg()),
169 value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); 165 value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor());
170 - } else if (transportApiRequestMsg.hasResourcesRequestMsg()) {  
171 - return Futures.transform(handle(transportApiRequestMsg.getResourcesRequestMsg()), 166 + } else if (transportApiRequestMsg.hasResourceRequestMsg()) {
  167 + return Futures.transform(handle(transportApiRequestMsg.getResourceRequestMsg()),
172 value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); 168 value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor());
173 } 169 }
174 return Futures.transform(getEmptyTransportApiResponseFuture(), 170 return Futures.transform(getEmptyTransportApiResponseFuture(),
@@ -366,38 +362,22 @@ public class DefaultTransportApiService implements TransportApiService { @@ -366,38 +362,22 @@ public class DefaultTransportApiService implements TransportApiService {
366 return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setEntityProfileResponseMsg(builder).build()); 362 return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setEntityProfileResponseMsg(builder).build());
367 } 363 }
368 364
369 - private ListenableFuture<TransportApiResponseMsg> handle(GetResourcesRequestMsg requestMsg) { 365 + private ListenableFuture<TransportApiResponseMsg> handle(GetResourceRequestMsg requestMsg) {
370 TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); 366 TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB()));
371 - TransportProtos.GetResourcesResponseMsg.Builder builder = TransportProtos.GetResourcesResponseMsg.newBuilder();  
372 - String resourceType = requestMsg.getResourceType(); 367 + ResourceType resourceType = ResourceType.valueOf(requestMsg.getResourceType());
373 String resourceId = requestMsg.getResourceId(); 368 String resourceId = requestMsg.getResourceId();
  369 + TransportProtos.GetResourceResponseMsg.Builder builder = TransportProtos.GetResourceResponseMsg.newBuilder();
  370 + Resource resource = resourceService.getResource(tenantId, resourceType, resourceId);
374 371
375 - List<TransportProtos.ResourceMsg> resources;  
376 -  
377 - if (resourceType != null && resourceId != null) {  
378 - resources = Collections.singletonList(toProto(  
379 - resourceService.getResource(tenantId, ResourceType.valueOf(resourceType), resourceId)));  
380 - } else {  
381 - //TODO: add page link params to request proto if need or remove this  
382 - resources = resourceService.findResourcesByTenantId(tenantId, new PageLink(100))  
383 - .getData()  
384 - .stream()  
385 - .map(this::toProto)  
386 - .collect(Collectors.toList()); 372 + if (resource == null && !tenantId.equals(TenantId.SYS_TENANT_ID)) {
  373 + resource = resourceService.getResource(TenantId.SYS_TENANT_ID, resourceType, resourceId);
387 } 374 }
388 375
389 - builder.addAllResources(resources);  
390 - return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setResourcesResponseMsg(builder).build());  
391 - } 376 + if (resource != null) {
  377 + builder.setResource(ByteString.copyFrom(dataDecodingEncodingService.encode(resource)));
  378 + }
392 379
393 - private TransportProtos.ResourceMsg toProto(Resource resource) {  
394 - return TransportProtos.ResourceMsg.newBuilder()  
395 - .setTenantIdMSB(resource.getTenantId().getId().getMostSignificantBits())  
396 - .setTenantIdLSB(resource.getTenantId().getId().getLeastSignificantBits())  
397 - .setResourceType(resource.getResourceType().name())  
398 - .setResourceId(resource.getResourceId())  
399 - .setValue(resource.getValue())  
400 - .build(); 380 + return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setResourceResponseMsg(builder).build());
401 } 381 }
402 382
403 private ListenableFuture<TransportApiResponseMsg> getDeviceInfo(DeviceId deviceId, DeviceCredentials credentials) { 383 private ListenableFuture<TransportApiResponseMsg> getDeviceInfo(DeviceId deviceId, DeviceCredentials credentials) {
@@ -18,8 +18,8 @@ package org.thingsboard.server.dao.resource; @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.resource;
18 import org.thingsboard.server.common.data.id.TenantId; 18 import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.common.data.page.PageData; 19 import org.thingsboard.server.common.data.page.PageData;
20 import org.thingsboard.server.common.data.page.PageLink; 20 import org.thingsboard.server.common.data.page.PageLink;
21 -import org.thingsboard.server.common.data.transport.resource.Resource;  
22 -import org.thingsboard.server.common.data.transport.resource.ResourceType; 21 +import org.thingsboard.server.common.data.Resource;
  22 +import org.thingsboard.server.common.data.ResourceType;
23 23
24 24
25 public interface ResourceService { 25 public interface ResourceService {
common/data/src/main/java/org/thingsboard/server/common/data/Resource.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/transport/resource/Resource.java
@@ -13,14 +13,18 @@ @@ -13,14 +13,18 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.common.data.transport.resource; 16 +package org.thingsboard.server.common.data;
17 17
18 import lombok.Data; 18 import lombok.Data;
19 -import org.thingsboard.server.common.data.HasTenantId;  
20 import org.thingsboard.server.common.data.id.TenantId; 19 import org.thingsboard.server.common.data.id.TenantId;
21 20
  21 +import java.io.Serializable;
  22 +
22 @Data 23 @Data
23 -public class Resource implements HasTenantId { 24 +public class Resource implements HasTenantId, Serializable {
  25 +
  26 + private static final long serialVersionUID = 7379609705527272306L;
  27 +
24 private TenantId tenantId; 28 private TenantId tenantId;
25 private ResourceType resourceType; 29 private ResourceType resourceType;
26 private String resourceId; 30 private String resourceId;
common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/transport/resource/ResourceType.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.common.data.transport.resource; 16 +package org.thingsboard.server.common.data;
17 17
18 public enum ResourceType { 18 public enum ResourceType {
19 LWM2M_MODEL, JKS, PKCS_12 19 LWM2M_MODEL, JKS, PKCS_12
@@ -201,23 +201,15 @@ message LwM2MResponseMsg { @@ -201,23 +201,15 @@ message LwM2MResponseMsg {
201 LwM2MRegistrationResponseMsg registrationMsg = 1; 201 LwM2MRegistrationResponseMsg registrationMsg = 1;
202 } 202 }
203 203
204 -message ResourceMsg { 204 +message GetResourceRequestMsg {
205 int64 tenantIdMSB = 1; 205 int64 tenantIdMSB = 1;
206 int64 tenantIdLSB = 2; 206 int64 tenantIdLSB = 2;
207 string resourceType = 3; 207 string resourceType = 3;
208 string resourceId = 4; 208 string resourceId = 4;
209 - string value = 5;  
210 } 209 }
211 210
212 -message GetResourcesRequestMsg {  
213 - int64 tenantIdMSB = 1;  
214 - int64 tenantIdLSB = 2;  
215 - string resourceType = 3;  
216 - string resourceId = 4;  
217 -}  
218 -  
219 -message GetResourcesResponseMsg {  
220 - repeated ResourceMsg resources = 1; 211 +message GetResourceResponseMsg {
  212 + bytes resource = 1;
221 } 213 }
222 214
223 message ValidateDeviceLwM2MCredentialsRequestMsg { 215 message ValidateDeviceLwM2MCredentialsRequestMsg {
@@ -558,7 +550,7 @@ message TransportApiRequestMsg { @@ -558,7 +550,7 @@ message TransportApiRequestMsg {
558 ValidateBasicMqttCredRequestMsg validateBasicMqttCredRequestMsg = 6; 550 ValidateBasicMqttCredRequestMsg validateBasicMqttCredRequestMsg = 6;
559 ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7; 551 ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7;
560 ValidateDeviceLwM2MCredentialsRequestMsg validateDeviceLwM2MCredentialsRequestMsg = 8; 552 ValidateDeviceLwM2MCredentialsRequestMsg validateDeviceLwM2MCredentialsRequestMsg = 8;
561 - GetResourcesRequestMsg resourcesRequestMsg = 9; 553 + GetResourceRequestMsg resourceRequestMsg = 9;
562 } 554 }
563 555
564 /* Response from ThingsBoard Core Service to Transport Service */ 556 /* Response from ThingsBoard Core Service to Transport Service */
@@ -568,7 +560,7 @@ message TransportApiResponseMsg { @@ -568,7 +560,7 @@ message TransportApiResponseMsg {
568 GetEntityProfileResponseMsg entityProfileResponseMsg = 3; 560 GetEntityProfileResponseMsg entityProfileResponseMsg = 3;
569 ProvisionDeviceResponseMsg provisionDeviceResponseMsg = 4; 561 ProvisionDeviceResponseMsg provisionDeviceResponseMsg = 4;
570 LwM2MResponseMsg lwM2MResponseMsg = 6; 562 LwM2MResponseMsg lwM2MResponseMsg = 6;
571 - GetResourcesResponseMsg resourcesResponseMsg = 7; 563 + GetResourceResponseMsg resourceResponseMsg = 7;
572 } 564 }
573 565
574 /* Messages that are handled by ThingsBoard Core Service */ 566 /* Messages that are handled by ThingsBoard Core Service */
  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.transport;
  17 +
  18 +import org.thingsboard.server.common.data.id.TenantId;
  19 +import org.thingsboard.server.common.data.Resource;
  20 +import org.thingsboard.server.common.data.ResourceType;
  21 +
  22 +public interface TransportResourceCache {
  23 +
  24 + Resource get(TenantId tenantId, ResourceType resourceType, String resourceId);
  25 +
  26 + void update(TenantId tenantId, ResourceType resourceType, String resourceI);
  27 +
  28 + void evict(TenantId tenantId, ResourceType resourceType, String resourceId);
  29 +}
@@ -25,8 +25,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestM @@ -25,8 +25,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestM
25 import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg; 25 import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg;
26 import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg; 26 import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg;
27 import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; 27 import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg;
28 -import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesRequestMsg;  
29 -import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesResponseMsg; 28 +import org.thingsboard.server.gen.transport.TransportProtos.GetResourceRequestMsg;
  29 +import org.thingsboard.server.gen.transport.TransportProtos.GetResourceResponseMsg;
30 import org.thingsboard.server.gen.transport.TransportProtos.LwM2MRequestMsg; 30 import org.thingsboard.server.gen.transport.TransportProtos.LwM2MRequestMsg;
31 import org.thingsboard.server.gen.transport.TransportProtos.LwM2MResponseMsg; 31 import org.thingsboard.server.gen.transport.TransportProtos.LwM2MResponseMsg;
32 import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; 32 import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg;
@@ -53,7 +53,7 @@ public interface TransportService { @@ -53,7 +53,7 @@ public interface TransportService {
53 53
54 GetEntityProfileResponseMsg getEntityProfile(GetEntityProfileRequestMsg msg); 54 GetEntityProfileResponseMsg getEntityProfile(GetEntityProfileRequestMsg msg);
55 55
56 - GetResourcesResponseMsg getResources(GetResourcesRequestMsg msg); 56 + GetResourceResponseMsg getResource(GetResourceRequestMsg msg);
57 57
58 void process(DeviceTransportType transportType, ValidateDeviceTokenRequestMsg msg, 58 void process(DeviceTransportType transportType, ValidateDeviceTokenRequestMsg msg,
59 TransportServiceCallback<ValidateDeviceCredentialsResponse> callback); 59 TransportServiceCallback<ValidateDeviceCredentialsResponse> callback);
  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.transport.service;
  17 +
  18 +import lombok.Data;
  19 +import lombok.extern.slf4j.Slf4j;
  20 +import org.springframework.context.annotation.Lazy;
  21 +import org.springframework.stereotype.Component;
  22 +import org.thingsboard.server.common.data.id.TenantId;
  23 +import org.thingsboard.server.common.data.Resource;
  24 +import org.thingsboard.server.common.data.ResourceType;
  25 +import org.thingsboard.server.common.transport.TransportResourceCache;
  26 +import org.thingsboard.server.common.transport.TransportService;
  27 +import org.thingsboard.server.common.transport.util.DataDecodingEncodingService;
  28 +import org.thingsboard.server.gen.transport.TransportProtos;
  29 +import org.thingsboard.server.queue.util.TbTransportComponent;
  30 +
  31 +import java.util.Optional;
  32 +import java.util.Set;
  33 +import java.util.UUID;
  34 +import java.util.concurrent.ConcurrentHashMap;
  35 +import java.util.concurrent.ConcurrentMap;
  36 +import java.util.concurrent.locks.Lock;
  37 +import java.util.concurrent.locks.ReentrantLock;
  38 +
  39 +@Slf4j
  40 +@Component
  41 +@TbTransportComponent
  42 +public class DefaultTransportResourceCache implements TransportResourceCache {
  43 +
  44 + private final Lock resourceFetchLock = new ReentrantLock();
  45 + private final ConcurrentMap<ResourceKey, Resource> resources = new ConcurrentHashMap<>();
  46 + private final Set<ResourceKey> keys = ConcurrentHashMap.newKeySet();
  47 + private final DataDecodingEncodingService dataDecodingEncodingService;
  48 + private final TransportService transportService;
  49 +
  50 + public DefaultTransportResourceCache(DataDecodingEncodingService dataDecodingEncodingService, @Lazy TransportService transportService) {
  51 + this.dataDecodingEncodingService = dataDecodingEncodingService;
  52 + this.transportService = transportService;
  53 + }
  54 +
  55 + @Override
  56 + public Resource get(TenantId tenantId, ResourceType resourceType, String resourceId) {
  57 + ResourceKey resourceKey = new ResourceKey(tenantId, resourceType, resourceId);
  58 + Resource resource;
  59 +
  60 + if (keys.contains(resourceKey)) {
  61 + resource = resources.get(resourceKey);
  62 + if (resource == null) {
  63 + resource = resources.get(resourceKey.getSystemKey());
  64 + }
  65 + } else {
  66 + resourceFetchLock.lock();
  67 + try {
  68 + if (keys.contains(resourceKey)) {
  69 + resource = resources.get(resourceKey);
  70 + if (resource == null) {
  71 + resource = resources.get(resourceKey.getSystemKey());
  72 + }
  73 + } else {
  74 + resource = fetchResource(resourceKey);
  75 + keys.add(resourceKey);
  76 + }
  77 + } finally {
  78 + resourceFetchLock.unlock();
  79 + }
  80 + }
  81 +
  82 + return resource;
  83 + }
  84 +
  85 + private Resource fetchResource(ResourceKey resourceKey) {
  86 + UUID tenantId = resourceKey.getTenantId().getId();
  87 + TransportProtos.GetResourceRequestMsg.Builder builder = TransportProtos.GetResourceRequestMsg.newBuilder();
  88 + builder
  89 + .setTenantIdLSB(tenantId.getLeastSignificantBits())
  90 + .setTenantIdMSB(tenantId.getMostSignificantBits())
  91 + .setResourceType(resourceKey.resourceType.name())
  92 + .setResourceId(resourceKey.resourceId);
  93 + TransportProtos.GetResourceResponseMsg responseMsg = transportService.getResource(builder.build());
  94 +
  95 + Optional<Resource> optionalResource = dataDecodingEncodingService.decode(responseMsg.getResource().toByteArray());
  96 + if (optionalResource.isPresent()) {
  97 + Resource resource = optionalResource.get();
  98 + resources.put(new ResourceKey(resource.getTenantId(), resource.getResourceType(), resource.getResourceId()), resource);
  99 + return resource;
  100 + }
  101 +
  102 + return null;
  103 + }
  104 +
  105 + @Override
  106 + public void update(TenantId tenantId, ResourceType resourceType, String resourceId) {
  107 + ResourceKey resourceKey = new ResourceKey(tenantId, resourceType, resourceId);
  108 + if (keys.contains(resourceKey) || resources.containsKey(resourceKey)) {
  109 + fetchResource(resourceKey);
  110 + }
  111 + }
  112 +
  113 + @Override
  114 + public void evict(TenantId tenantId, ResourceType resourceType, String resourceId) {
  115 + ResourceKey resourceKey = new ResourceKey(tenantId, resourceType, resourceId);
  116 + keys.remove(resourceKey);
  117 + resources.remove(resourceKey);
  118 + }
  119 +
  120 + @Data
  121 + private static class ResourceKey {
  122 + private final TenantId tenantId;
  123 + private final ResourceType resourceType;
  124 + private final String resourceId;
  125 +
  126 + public ResourceKey getSystemKey() {
  127 + return new ResourceKey(TenantId.SYS_TENANT_ID, resourceType, resourceId);
  128 + }
  129 + }
  130 +}
@@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.id.DeviceProfileId;
37 import org.thingsboard.server.common.data.id.RuleChainId; 37 import org.thingsboard.server.common.data.id.RuleChainId;
38 import org.thingsboard.server.common.data.id.TenantId; 38 import org.thingsboard.server.common.data.id.TenantId;
39 import org.thingsboard.server.common.data.id.TenantProfileId; 39 import org.thingsboard.server.common.data.id.TenantProfileId;
  40 +import org.thingsboard.server.common.data.ResourceType;
40 import org.thingsboard.server.common.msg.TbMsg; 41 import org.thingsboard.server.common.msg.TbMsg;
41 import org.thingsboard.server.common.msg.TbMsgMetaData; 42 import org.thingsboard.server.common.msg.TbMsgMetaData;
42 import org.thingsboard.server.common.msg.queue.ServiceQueue; 43 import org.thingsboard.server.common.msg.queue.ServiceQueue;
@@ -49,6 +50,7 @@ import org.thingsboard.server.common.stats.StatsFactory; @@ -49,6 +50,7 @@ import org.thingsboard.server.common.stats.StatsFactory;
49 import org.thingsboard.server.common.stats.StatsType; 50 import org.thingsboard.server.common.stats.StatsType;
50 import org.thingsboard.server.common.transport.SessionMsgListener; 51 import org.thingsboard.server.common.transport.SessionMsgListener;
51 import org.thingsboard.server.common.transport.TransportDeviceProfileCache; 52 import org.thingsboard.server.common.transport.TransportDeviceProfileCache;
  53 +import org.thingsboard.server.common.transport.TransportResourceCache;
52 import org.thingsboard.server.common.transport.TransportService; 54 import org.thingsboard.server.common.transport.TransportService;
53 import org.thingsboard.server.common.transport.TransportServiceCallback; 55 import org.thingsboard.server.common.transport.TransportServiceCallback;
54 import org.thingsboard.server.common.transport.TransportTenantProfileCache; 56 import org.thingsboard.server.common.transport.TransportTenantProfileCache;
@@ -61,7 +63,6 @@ import org.thingsboard.server.common.transport.util.JsonUtils; @@ -61,7 +63,6 @@ import org.thingsboard.server.common.transport.util.JsonUtils;
61 import org.thingsboard.server.gen.transport.TransportProtos; 63 import org.thingsboard.server.gen.transport.TransportProtos;
62 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; 64 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg;
63 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; 65 import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg;
64 -import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;  
65 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 66 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
66 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; 67 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
67 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; 68 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -131,6 +132,7 @@ public class DefaultTransportService implements TransportService { @@ -131,6 +132,7 @@ public class DefaultTransportService implements TransportService {
131 private final TransportRateLimitService rateLimitService; 132 private final TransportRateLimitService rateLimitService;
132 private final DataDecodingEncodingService dataDecodingEncodingService; 133 private final DataDecodingEncodingService dataDecodingEncodingService;
133 private final SchedulerComponent scheduler; 134 private final SchedulerComponent scheduler;
  135 + private final TransportResourceCache transportResourceCache;
134 136
135 protected TbQueueRequestTemplate<TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> transportApiRequestTemplate; 137 protected TbQueueRequestTemplate<TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> transportApiRequestTemplate;
136 protected TbQueueProducer<TbProtoQueueMsg<ToRuleEngineMsg>> ruleEngineMsgProducer; 138 protected TbQueueProducer<TbProtoQueueMsg<ToRuleEngineMsg>> ruleEngineMsgProducer;
@@ -157,7 +159,7 @@ public class DefaultTransportService implements TransportService { @@ -157,7 +159,7 @@ public class DefaultTransportService implements TransportService {
157 TransportDeviceProfileCache deviceProfileCache, 159 TransportDeviceProfileCache deviceProfileCache,
158 TransportTenantProfileCache tenantProfileCache, 160 TransportTenantProfileCache tenantProfileCache,
159 TbApiUsageClient apiUsageClient, TransportRateLimitService rateLimitService, 161 TbApiUsageClient apiUsageClient, TransportRateLimitService rateLimitService,
160 - DataDecodingEncodingService dataDecodingEncodingService, SchedulerComponent scheduler) { 162 + DataDecodingEncodingService dataDecodingEncodingService, SchedulerComponent scheduler, TransportResourceCache transportResourceCache) {
161 this.serviceInfoProvider = serviceInfoProvider; 163 this.serviceInfoProvider = serviceInfoProvider;
162 this.queueProvider = queueProvider; 164 this.queueProvider = queueProvider;
163 this.producerProvider = producerProvider; 165 this.producerProvider = producerProvider;
@@ -169,6 +171,7 @@ public class DefaultTransportService implements TransportService { @@ -169,6 +171,7 @@ public class DefaultTransportService implements TransportService {
169 this.rateLimitService = rateLimitService; 171 this.rateLimitService = rateLimitService;
170 this.dataDecodingEncodingService = dataDecodingEncodingService; 172 this.dataDecodingEncodingService = dataDecodingEncodingService;
171 this.scheduler = scheduler; 173 this.scheduler = scheduler;
  174 + this.transportResourceCache = transportResourceCache;
172 } 175 }
173 176
174 @PostConstruct 177 @PostConstruct
@@ -255,12 +258,12 @@ public class DefaultTransportService implements TransportService { @@ -255,12 +258,12 @@ public class DefaultTransportService implements TransportService {
255 } 258 }
256 259
257 @Override 260 @Override
258 - public TransportProtos.GetResourcesResponseMsg getResources(TransportProtos.GetResourcesRequestMsg msg) { 261 + public TransportProtos.GetResourceResponseMsg getResource(TransportProtos.GetResourceRequestMsg msg) {
259 TbProtoQueueMsg<TransportProtos.TransportApiRequestMsg> protoMsg = 262 TbProtoQueueMsg<TransportProtos.TransportApiRequestMsg> protoMsg =
260 - new TbProtoQueueMsg<>(UUID.randomUUID(), TransportProtos.TransportApiRequestMsg.newBuilder().setResourcesRequestMsg(msg).build()); 263 + new TbProtoQueueMsg<>(UUID.randomUUID(), TransportProtos.TransportApiRequestMsg.newBuilder().setResourceRequestMsg(msg).build());
261 try { 264 try {
262 TbProtoQueueMsg<TransportApiResponseMsg> response = transportApiRequestTemplate.send(protoMsg).get(); 265 TbProtoQueueMsg<TransportApiResponseMsg> response = transportApiRequestTemplate.send(protoMsg).get();
263 - return response.getValue().getResourcesResponseMsg(); 266 + return response.getValue().getResourceResponseMsg();
264 } catch (InterruptedException | ExecutionException e) { 267 } catch (InterruptedException | ExecutionException e) {
265 throw new RuntimeException(e); 268 throw new RuntimeException(e);
266 } 269 }
@@ -701,9 +704,17 @@ public class DefaultTransportService implements TransportService { @@ -701,9 +704,17 @@ public class DefaultTransportService implements TransportService {
701 rateLimitService.remove(new DeviceId(entityUuid)); 704 rateLimitService.remove(new DeviceId(entityUuid));
702 } 705 }
703 } else if (toSessionMsg.hasResourceUpdateMsg()) { 706 } else if (toSessionMsg.hasResourceUpdateMsg()) {
704 - //TODO: update resource cache 707 + TransportProtos.ResourceUpdateMsg msg = toSessionMsg.getResourceUpdateMsg();
  708 + TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB()));
  709 + ResourceType resourceType = ResourceType.valueOf(msg.getResourceType());
  710 + String resourceId = msg.getResourceId();
  711 + transportResourceCache.update(tenantId, resourceType, resourceId);
705 } else if (toSessionMsg.hasResourceDeleteMsg()) { 712 } else if (toSessionMsg.hasResourceDeleteMsg()) {
706 - //TODO: remove resource from cache 713 + TransportProtos.ResourceDeleteMsg msg = toSessionMsg.getResourceDeleteMsg();
  714 + TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB()));
  715 + ResourceType resourceType = ResourceType.valueOf(msg.getResourceType());
  716 + String resourceId = msg.getResourceId();
  717 + transportResourceCache.evict(tenantId, resourceType, resourceId);
707 } else { 718 } else {
708 //TODO: should we notify the device actor about missed session? 719 //TODO: should we notify the device actor about missed session?
709 log.debug("[{}] Missing session.", sessionId); 720 log.debug("[{}] Missing session.", sessionId);
@@ -18,8 +18,6 @@ package org.thingsboard.server.common.transport.util; @@ -18,8 +18,6 @@ package org.thingsboard.server.common.transport.util;
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.nustaq.serialization.FSTConfiguration; 19 import org.nustaq.serialization.FSTConfiguration;
20 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
21 -import org.thingsboard.server.common.msg.TbActorMsg;  
22 -import org.thingsboard.server.common.transport.util.DataDecodingEncodingService;  
23 21
24 import java.util.Optional; 22 import java.util.Optional;
25 23
@@ -33,8 +31,8 @@ public class ProtoWithFSTService implements DataDecodingEncodingService { @@ -33,8 +31,8 @@ public class ProtoWithFSTService implements DataDecodingEncodingService {
33 public <T> Optional<T> decode(byte[] byteArray) { 31 public <T> Optional<T> decode(byte[] byteArray) {
34 try { 32 try {
35 @SuppressWarnings("unchecked") 33 @SuppressWarnings("unchecked")
36 - T msg = (T) config.asObject(byteArray);  
37 - return Optional.of(msg); 34 + T msg = byteArray != null && byteArray.length > 0 ? (T) config.asObject(byteArray) : null;
  35 + return Optional.ofNullable(msg);
38 } catch (IllegalArgumentException e) { 36 } catch (IllegalArgumentException e) {
39 log.error("Error during deserialization message, [{}]", e.getMessage()); 37 log.error("Error during deserialization message, [{}]", e.getMessage());
40 return Optional.empty(); 38 return Optional.empty();
@@ -18,8 +18,7 @@ package org.thingsboard.server.dao.model.sql; @@ -18,8 +18,7 @@ package org.thingsboard.server.dao.model.sql;
18 import lombok.AllArgsConstructor; 18 import lombok.AllArgsConstructor;
19 import lombok.Data; 19 import lombok.Data;
20 import lombok.NoArgsConstructor; 20 import lombok.NoArgsConstructor;
21 -import org.thingsboard.server.common.data.relation.EntityRelation;  
22 -import org.thingsboard.server.common.data.transport.resource.Resource; 21 +import org.thingsboard.server.common.data.Resource;
23 22
24 import javax.persistence.Transient; 23 import javax.persistence.Transient;
25 import java.io.Serializable; 24 import java.io.Serializable;
@@ -17,8 +17,8 @@ package org.thingsboard.server.dao.model.sql; @@ -17,8 +17,8 @@ package org.thingsboard.server.dao.model.sql;
17 17
18 import lombok.Data; 18 import lombok.Data;
19 import org.thingsboard.server.common.data.id.TenantId; 19 import org.thingsboard.server.common.data.id.TenantId;
20 -import org.thingsboard.server.common.data.transport.resource.Resource;  
21 -import org.thingsboard.server.common.data.transport.resource.ResourceType; 20 +import org.thingsboard.server.common.data.Resource;
  21 +import org.thingsboard.server.common.data.ResourceType;
22 import org.thingsboard.server.dao.model.ToData; 22 import org.thingsboard.server.dao.model.ToData;
23 23
24 import javax.persistence.Column; 24 import javax.persistence.Column;
@@ -20,8 +20,8 @@ import org.springframework.stereotype.Service; @@ -20,8 +20,8 @@ import org.springframework.stereotype.Service;
20 import org.thingsboard.server.common.data.id.TenantId; 20 import org.thingsboard.server.common.data.id.TenantId;
21 import org.thingsboard.server.common.data.page.PageData; 21 import org.thingsboard.server.common.data.page.PageData;
22 import org.thingsboard.server.common.data.page.PageLink; 22 import org.thingsboard.server.common.data.page.PageLink;
23 -import org.thingsboard.server.common.data.transport.resource.Resource;  
24 -import org.thingsboard.server.common.data.transport.resource.ResourceType; 23 +import org.thingsboard.server.common.data.Resource;
  24 +import org.thingsboard.server.common.data.ResourceType;
25 import org.thingsboard.server.dao.exception.DataValidationException; 25 import org.thingsboard.server.dao.exception.DataValidationException;
26 26
27 import static org.thingsboard.server.dao.device.DeviceServiceImpl.INCORRECT_TENANT_ID; 27 import static org.thingsboard.server.dao.device.DeviceServiceImpl.INCORRECT_TENANT_ID;
@@ -18,8 +18,8 @@ package org.thingsboard.server.dao.resource; @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.resource;
18 import org.thingsboard.server.common.data.id.TenantId; 18 import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.common.data.page.PageData; 19 import org.thingsboard.server.common.data.page.PageData;
20 import org.thingsboard.server.common.data.page.PageLink; 20 import org.thingsboard.server.common.data.page.PageLink;
21 -import org.thingsboard.server.common.data.transport.resource.Resource;  
22 -import org.thingsboard.server.common.data.transport.resource.ResourceType; 21 +import org.thingsboard.server.common.data.Resource;
  22 +import org.thingsboard.server.common.data.ResourceType;
23 23
24 public interface ResourceDao { 24 public interface ResourceDao {
25 25
@@ -21,8 +21,8 @@ import org.springframework.transaction.annotation.Transactional; @@ -21,8 +21,8 @@ import org.springframework.transaction.annotation.Transactional;
21 import org.thingsboard.server.common.data.id.TenantId; 21 import org.thingsboard.server.common.data.id.TenantId;
22 import org.thingsboard.server.common.data.page.PageData; 22 import org.thingsboard.server.common.data.page.PageData;
23 import org.thingsboard.server.common.data.page.PageLink; 23 import org.thingsboard.server.common.data.page.PageLink;
24 -import org.thingsboard.server.common.data.transport.resource.Resource;  
25 -import org.thingsboard.server.common.data.transport.resource.ResourceType; 24 +import org.thingsboard.server.common.data.Resource;
  25 +import org.thingsboard.server.common.data.ResourceType;
26 import org.thingsboard.server.dao.DaoUtil; 26 import org.thingsboard.server.dao.DaoUtil;
27 import org.thingsboard.server.dao.model.sql.ResourceCompositeKey; 27 import org.thingsboard.server.dao.model.sql.ResourceCompositeKey;
28 import org.thingsboard.server.dao.model.sql.ResourceEntity; 28 import org.thingsboard.server.dao.model.sql.ResourceEntity;