diff --git a/application/src/main/java/org/thingsboard/server/controller/ResourceController.java b/application/src/main/java/org/thingsboard/server/controller/ResourceController.java index b09e4e23b2..babe444ae7 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/ResourceController.java @@ -49,8 +49,10 @@ public class ResourceController extends BaseController { @ResponseBody public Resource saveResource(Resource resource) throws ThingsboardException { try { - resource.setTenantId(getCurrentUser().getTenantId()); - return checkNotNull(resourceService.saveResource(resource)); + resource.setTenantId(getTenantId()); + Resource savedResource = checkNotNull(resourceService.saveResource(resource)); + tbClusterService.onResourceChange(savedResource, null); + return savedResource; } catch (Exception e) { throw handleException(e); } @@ -61,7 +63,7 @@ public class ResourceController extends BaseController { @ResponseBody public List getResources(@RequestParam(required = false) boolean system) throws ThingsboardException { try { - return checkNotNull(resourceService.findByTenantId(system ? TenantId.SYS_TENANT_ID : getCurrentUser().getTenantId())); + return checkNotNull(resourceService.findResourcesByTenantId(system ? TenantId.SYS_TENANT_ID : getTenantId())); } catch (Exception e) { throw handleException(e); } @@ -70,13 +72,14 @@ public class ResourceController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource/{resourceType}/{resourceId}", method = RequestMethod.DELETE) @ResponseBody - public boolean deleteResource(@PathVariable("resourceType") ResourceType resourceType, - @PathVariable("resourceId") String resourceId) throws ThingsboardException { + public void deleteResource(@PathVariable("resourceType") ResourceType resourceType, + @PathVariable("resourceId") String resourceId) throws ThingsboardException { try { - return resourceService.deleteResource(getCurrentUser().getTenantId(), resourceType, resourceId); + Resource resource = checkNotNull(resourceService.getResource(getTenantId(), resourceType, resourceId)); + resourceService.deleteResource(getTenantId(), resourceType, resourceId); + tbClusterService.onResourceDeleted(resource, null); } catch (Exception e) { throw handleException(e); } } - } diff --git a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java index 5029a520e3..2fc832129f 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java +++ b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java @@ -24,7 +24,6 @@ import org.springframework.util.StringUtils; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate; import org.thingsboard.server.common.data.rule.RuleChain; @@ -206,7 +205,7 @@ public class InstallScripts { resource.setTenantId(TenantId.SYS_TENANT_ID); resource.setResourceType(ResourceType.LWM2M_MODEL); resource.setResourceId(path.getFileName().toString()); - resource.setValue(Files.readString(path)); + resource.setValue(Base64.getEncoder().encodeToString(Files.readAllBytes(path))); resourceService.saveResource(resource); } catch (Exception e) { log.error("Unable to load lwm2m model [{}]", path.toString()); @@ -220,7 +219,7 @@ public class InstallScripts { try { Resource resource = new Resource(); resource.setTenantId(TenantId.SYS_TENANT_ID); - resource.setResourceType(ResourceType.LWM2M_KEY_STORE); + resource.setResourceType(ResourceType.JKS); resource.setResourceId(jksPath.getFileName().toString()); resource.setValue(Base64.getEncoder().encodeToString(Files.readAllBytes(jksPath))); resourceService.saveResource(resource); diff --git a/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MModelsRepository.java b/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MModelsRepository.java index 5057893d5c..3db41fff8b 100644 --- a/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MModelsRepository.java +++ b/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MModelsRepository.java @@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigBootstrap; import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer; import org.thingsboard.server.dao.service.Validator; +import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; import java.math.BigInteger; @@ -61,6 +62,7 @@ import static org.thingsboard.server.dao.service.Validator.validateId; @Slf4j @Service +@TbLwM2mTransportComponent @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true') || '${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'") public class LwM2MModelsRepository { diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java index 133447022b..3405ab28d8 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java @@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; +import org.thingsboard.server.common.data.transport.resource.Resource; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.queue.ServiceType; @@ -247,6 +248,34 @@ public class DefaultTbClusterService implements TbClusterService { onEntityDelete(entity.getTenantId(), entity.getId(), entity.getName(), callback); } + @Override + public void onResourceChange(Resource resource, TbQueueCallback callback) { + TenantId tenantId = resource.getTenantId(); + log.trace("[{}][{}][{}] Processing change resource", tenantId, resource.getResourceType(), resource.getResourceId()); + TransportProtos.ResourceUpdateMsg resourceUpdateMsg = TransportProtos.ResourceUpdateMsg.newBuilder() + .setTenantIdMSB(tenantId.getId().getMostSignificantBits()) + .setTenantIdLSB(tenantId.getId().getLeastSignificantBits()) + .setResourceType(resource.getResourceType().name()) + .setResourceId(resource.getResourceId()) + .build(); + ToTransportMsg transportMsg = ToTransportMsg.newBuilder().setResourceUpdateMsg(resourceUpdateMsg).build(); + broadcast(transportMsg, callback); + } + + @Override + public void onResourceDeleted(Resource resource, TbQueueCallback callback) { + TenantId tenantId = resource.getTenantId(); + log.trace("[{}][{}][{}] Processing delete resource", tenantId, resource.getResourceType(), resource.getResourceId()); + TransportProtos.ResourceDeleteMsg resourceUpdateMsg = TransportProtos.ResourceDeleteMsg.newBuilder() + .setTenantIdMSB(tenantId.getId().getMostSignificantBits()) + .setTenantIdLSB(tenantId.getId().getLeastSignificantBits()) + .setResourceType(resource.getResourceType().name()) + .setResourceId(resource.getResourceId()) + .build(); + ToTransportMsg transportMsg = ToTransportMsg.newBuilder().setResourceDeleteMsg(resourceUpdateMsg).build(); + broadcast(transportMsg, callback); + } + public void onEntityChange(TenantId tenantId, EntityId entityid, T entity, TbQueueCallback callback) { String entityName = (entity instanceof HasName) ? ((HasName) entity).getName() : entity.getClass().getName(); log.trace("[{}][{}][{}] Processing [{}] change event", tenantId, entityid.getEntityType(), entityid.getId(), entityName); diff --git a/application/src/main/java/org/thingsboard/server/service/queue/TbClusterService.java b/application/src/main/java/org/thingsboard/server/service/queue/TbClusterService.java index 92401ea9c0..c1cafa3379 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/TbClusterService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/TbClusterService.java @@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; +import org.thingsboard.server.common.data.transport.resource.Resource; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.gen.transport.TransportProtos; @@ -71,4 +72,8 @@ public interface TbClusterService { void onDeviceChange(Device device, TbQueueCallback callback); void onDeviceDeleted(Device device, TbQueueCallback callback); + + void onResourceChange(Resource resource, TbQueueCallback callback); + + void onResourceDeleted(Resource resource, TbQueueCallback callback); } diff --git a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java index b157e0d0a7..ef6d87e4be 100644 --- a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java +++ b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java @@ -25,6 +25,7 @@ import com.google.protobuf.ByteString; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.ApiUsageState; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; @@ -41,6 +42,8 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; +import org.thingsboard.server.common.data.transport.resource.Resource; +import org.thingsboard.server.common.data.transport.resource.ResourceType; import org.thingsboard.server.common.msg.EncryptionUtil; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; @@ -53,14 +56,15 @@ import org.thingsboard.server.dao.device.provision.ProvisionFailedException; import org.thingsboard.server.dao.device.provision.ProvisionRequest; import org.thingsboard.server.dao.device.provision.ProvisionResponse; import org.thingsboard.server.dao.relation.RelationService; +import org.thingsboard.server.dao.resource.ResourceService; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; -import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayResponseMsg; +import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ProvisionResponseStatus; import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg; @@ -77,11 +81,14 @@ import org.thingsboard.server.service.profile.TbDeviceProfileCache; import org.thingsboard.server.service.queue.TbClusterService; import org.thingsboard.server.service.state.DeviceStateService; +import java.util.Collections; +import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; /** * Created by ashvayka on 05.10.18. @@ -104,6 +111,7 @@ public class DefaultTransportApiService implements TransportApiService { private final TbClusterService tbClusterService; private final DataDecodingEncodingService dataDecodingEncodingService; private final DeviceProvisionService deviceProvisionService; + private final ResourceService resourceService; private final ConcurrentMap deviceCreationLocks = new ConcurrentHashMap<>(); @@ -112,7 +120,7 @@ public class DefaultTransportApiService implements TransportApiService { RelationService relationService, DeviceCredentialsService deviceCredentialsService, DeviceStateService deviceStateService, DbCallbackExecutorService dbCallbackExecutorService, TbClusterService tbClusterService, DataDecodingEncodingService dataDecodingEncodingService, - DeviceProvisionService deviceProvisionService) { + DeviceProvisionService deviceProvisionService, ResourceService resourceService) { this.deviceProfileCache = deviceProfileCache; this.tenantProfileCache = tenantProfileCache; this.apiUsageStateService = apiUsageStateService; @@ -124,6 +132,7 @@ public class DefaultTransportApiService implements TransportApiService { this.tbClusterService = tbClusterService; this.dataDecodingEncodingService = dataDecodingEncodingService; this.deviceProvisionService = deviceProvisionService; + this.resourceService = resourceService; } @Override @@ -157,6 +166,9 @@ public class DefaultTransportApiService implements TransportApiService { } else if (transportApiRequestMsg.hasProvisionDeviceRequestMsg()) { return Futures.transform(handle(transportApiRequestMsg.getProvisionDeviceRequestMsg()), value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); + } else if (transportApiRequestMsg.hasResourcesRequestMsg()) { + return Futures.transform(handle(transportApiRequestMsg.getResourcesRequestMsg()), + value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); } return Futures.transform(getEmptyTransportApiResponseFuture(), value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor()); @@ -315,9 +327,9 @@ public class DefaultTransportApiService implements TransportApiService { return TransportApiResponseMsg.newBuilder().setProvisionDeviceResponseMsg(TransportProtos.ProvisionDeviceResponseMsg.newBuilder().setStatus(status).build()).build(); } TransportProtos.ProvisionDeviceResponseMsg.Builder provisionResponse = TransportProtos.ProvisionDeviceResponseMsg.newBuilder() - .setCredentialsType(TransportProtos.CredentialsType.valueOf(deviceCredentials.getCredentialsType().name())) - .setStatus(status); - switch (deviceCredentials.getCredentialsType()){ + .setCredentialsType(TransportProtos.CredentialsType.valueOf(deviceCredentials.getCredentialsType().name())) + .setStatus(status); + switch (deviceCredentials.getCredentialsType()) { case ACCESS_TOKEN: provisionResponse.setCredentialsValue(deviceCredentials.getCredentialsId()); break; @@ -353,6 +365,38 @@ public class DefaultTransportApiService implements TransportApiService { return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setEntityProfileResponseMsg(builder).build()); } + private ListenableFuture handle(GetResourcesRequestMsg requestMsg) { + TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); + TransportProtos.GetResourcesResponseMsg.Builder builder = TransportProtos.GetResourcesResponseMsg.newBuilder(); + String resourceType = requestMsg.getResourceType(); + String resourceId = requestMsg.getResourceId(); + + List resources; + + if (resourceType != null && resourceId != null) { + resources = Collections.singletonList(toProto( + resourceService.getResource(tenantId, ResourceType.valueOf(resourceType), resourceId))); + } else { + resources = resourceService.findResourcesByTenantId(tenantId) + .stream() + .map(this::toProto) + .collect(Collectors.toList()); + } + + builder.addAllResources(resources); + return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setResourcesResponseMsg(builder).build()); + } + + private TransportProtos.ResourceMsg toProto(Resource resource) { + return TransportProtos.ResourceMsg.newBuilder() + .setTenantIdMSB(resource.getTenantId().getId().getMostSignificantBits()) + .setTenantIdLSB(resource.getTenantId().getId().getLeastSignificantBits()) + .setResourceType(resource.getResourceType().name()) + .setResourceId(resource.getResourceId()) + .setValue(resource.getValue()) + .build(); + } + private ListenableFuture getDeviceInfo(DeviceId deviceId, DeviceCredentials credentials) { return Futures.transform(deviceService.findDeviceByIdAsync(TenantId.SYS_TENANT_ID, deviceId), device -> { if (device == null) { diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java index 99cf1ef87b..03b6976de8 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java @@ -27,7 +27,9 @@ public interface ResourceService { Resource getResource(TenantId tenantId, ResourceType resourceType, String resourceId); - boolean deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId); + List findResourcesByTenantId(TenantId tenantId); - List findByTenantId(TenantId tenantId); + void deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId); + + void deleteResourcesByTenantId(TenantId tenantId); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/transport/resource/ResourceType.java b/common/data/src/main/java/org/thingsboard/server/common/data/transport/resource/ResourceType.java index 2e12bbdda2..c43f1997da 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/transport/resource/ResourceType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/transport/resource/ResourceType.java @@ -16,5 +16,5 @@ package org.thingsboard.server.common.data.transport.resource; public enum ResourceType { - LWM2M_MODEL, LWM2M_KEY_STORE + LWM2M_MODEL, JKS, PKCS_12 } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/util/TbLwM2mTransportComponent.java b/common/queue/src/main/java/org/thingsboard/server/queue/util/TbLwM2mTransportComponent.java index 3bc4d494f2..638f9f6fb2 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/util/TbLwM2mTransportComponent.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/util/TbLwM2mTransportComponent.java @@ -21,6 +21,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) -@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") +@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true') || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") public @interface TbLwM2mTransportComponent { } diff --git a/common/queue/src/main/proto/queue.proto b/common/queue/src/main/proto/queue.proto index d5f440d808..42f6267d42 100644 --- a/common/queue/src/main/proto/queue.proto +++ b/common/queue/src/main/proto/queue.proto @@ -201,6 +201,25 @@ message LwM2MResponseMsg { LwM2MRegistrationResponseMsg registrationMsg = 1; } +message ResourceMsg { + int64 tenantIdMSB = 1; + int64 tenantIdLSB = 2; + string resourceType = 3; + string resourceId = 4; + string value = 5; +} + +message GetResourcesRequestMsg { + int64 tenantIdMSB = 1; + int64 tenantIdLSB = 2; + string resourceType = 3; + string resourceId = 4; +} + +message GetResourcesResponseMsg { + repeated ResourceMsg resources = 1; +} + message ValidateDeviceLwM2MCredentialsRequestMsg { string credentialsId = 1; } @@ -242,6 +261,20 @@ message EntityDeleteMsg { int64 entityIdLSB = 3; } +message ResourceUpdateMsg { + int64 tenantIdMSB = 1; + int64 tenantIdLSB = 2; + string resourceType = 3; + string resourceId = 4; +} + +message ResourceDeleteMsg { + int64 tenantIdMSB = 1; + int64 tenantIdLSB = 2; + string resourceType = 3; + string resourceId = 4; +} + message SessionCloseNotificationProto { string message = 1; } @@ -525,6 +558,7 @@ message TransportApiRequestMsg { ValidateBasicMqttCredRequestMsg validateBasicMqttCredRequestMsg = 6; ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7; ValidateDeviceLwM2MCredentialsRequestMsg validateDeviceLwM2MCredentialsRequestMsg = 8; + GetResourcesRequestMsg resourcesRequestMsg = 9; } /* Response from ThingsBoard Core Service to Transport Service */ @@ -534,6 +568,7 @@ message TransportApiResponseMsg { GetEntityProfileResponseMsg entityProfileResponseMsg = 3; ProvisionDeviceResponseMsg provisionDeviceResponseMsg = 4; LwM2MResponseMsg lwM2MResponseMsg = 6; + GetResourcesResponseMsg resourcesResponseMsg = 7; } /* Messages that are handled by ThingsBoard Core Service */ @@ -578,6 +613,8 @@ message ToTransportMsg { EntityDeleteMsg entityDeleteMsg = 9; ProvisionDeviceResponseMsg provisionResponse = 10; ToTransportUpdateCredentialsProto toTransportUpdateCredentialsNotification = 11; + ResourceUpdateMsg resourceUpdateMsg = 12; + ResourceDeleteMsg resourceDeleteMsg = 13; } message UsageStatsKVProto{ diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java index e642e7f7b2..ab728af00d 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java @@ -25,6 +25,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestM import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; +import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesRequestMsg; +import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.LwM2MRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.LwM2MResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; @@ -51,6 +53,8 @@ public interface TransportService { GetEntityProfileResponseMsg getEntityProfile(GetEntityProfileRequestMsg msg); + GetResourcesResponseMsg getResources(GetResourcesRequestMsg msg); + void process(DeviceTransportType transportType, ValidateDeviceTokenRequestMsg msg, TransportServiceCallback callback); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 473eeea42c..ed02f7016c 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -254,6 +254,18 @@ public class DefaultTransportService implements TransportService { } } + @Override + public TransportProtos.GetResourcesResponseMsg getResources(TransportProtos.GetResourcesRequestMsg msg) { + TbProtoQueueMsg protoMsg = + new TbProtoQueueMsg<>(UUID.randomUUID(), TransportProtos.TransportApiRequestMsg.newBuilder().setResourcesRequestMsg(msg).build()); + try { + TbProtoQueueMsg response = transportApiRequestTemplate.send(protoMsg).get(); + return response.getValue().getResourcesResponseMsg(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + @Override public void process(DeviceTransportType transportType, TransportProtos.ValidateDeviceTokenRequestMsg msg, TransportServiceCallback callback) { @@ -688,6 +700,10 @@ public class DefaultTransportService implements TransportService { } else if (EntityType.DEVICE.equals(entityType)) { rateLimitService.remove(new DeviceId(entityUuid)); } + } else if (toSessionMsg.hasResourceUpdateMsg()) { + //TODO: update resource cache + } else if (toSessionMsg.hasResourceDeleteMsg()) { + //TODO: remove resource from cache } else { //TODO: should we notify the device actor about missed session? log.debug("[{}] Missing session.", sessionId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index 84ce22eef1..55394c7266 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -24,6 +24,9 @@ import org.thingsboard.server.dao.exception.DataValidationException; import java.util.List; +import static org.thingsboard.server.dao.device.DeviceServiceImpl.INCORRECT_TENANT_ID; +import static org.thingsboard.server.dao.service.Validator.validateId; + @Service @Slf4j public class BaseResourceService implements ResourceService { @@ -49,18 +52,26 @@ public class BaseResourceService implements ResourceService { } @Override - public boolean deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId) { + public void deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId) { log.trace("Executing deleteResource [{}] [{}] [{}]", tenantId, resourceType, resourceId); validate(tenantId, resourceType, resourceId); - return resourceDao.deleteResource(tenantId, resourceType, resourceId); + resourceDao.deleteResource(tenantId, resourceType, resourceId); } @Override - public List findByTenantId(TenantId tenantId) { + public List findResourcesByTenantId(TenantId tenantId) { log.trace("Executing findByTenantId [{}]", tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); return resourceDao.findAllByTenantId(tenantId); } + @Override + public void deleteResourcesByTenantId(TenantId tenantId) { + log.trace("Executing deleteDevicesByTenantId, tenantId [{}]", tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + resourceDao.removeAllByTenantId(tenantId); + } + protected void validate(Resource resource) { if (resource == null) { throw new DataValidationException("Resource should be specified!"); @@ -79,12 +90,7 @@ public class BaseResourceService implements ResourceService { if (resourceId == null) { throw new DataValidationException("Resource id should be specified!"); } - validate(tenantId); + validateId(tenantId, "Incorrect tenantId "); } - protected void validate(TenantId tenantId) { - if (tenantId == null) { - throw new DataValidationException("Tenant id should be specified!"); - } - } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/ResourceDao.java b/dao/src/main/java/org/thingsboard/server/dao/resource/ResourceDao.java index f722423412..a053bc0c74 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/ResourceDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/ResourceDao.java @@ -27,7 +27,9 @@ public interface ResourceDao { Resource getResource(TenantId tenantId, ResourceType resourceType, String resourceId); - boolean deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId); + void deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId); List findAllByTenantId(TenantId tenantId); + + void removeAllByTenantId(TenantId tenantId); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/ResourceDaoImpl.java b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/ResourceDaoImpl.java index b11c14546a..0cf9fce980 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/ResourceDaoImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/ResourceDaoImpl.java @@ -56,18 +56,22 @@ public class ResourceDaoImpl implements ResourceDao { @Override @Transactional - public boolean deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId) { + public void deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId) { ResourceCompositeKey key = new ResourceCompositeKey(); key.setTenantId(tenantId.getId()); key.setResourceType(resourceType.name()); key.setResourceId(resourceId); resourceRepository.deleteById(key); - return resourceRepository.existsById(key); } @Override public List findAllByTenantId(TenantId tenantId) { - return DaoUtil.convertDataList(resourceRepository.findAllByTenantId(tenantId)); + return DaoUtil.convertDataList(resourceRepository.findAllByTenantId(tenantId.getId())); + } + + @Override + public void removeAllByTenantId(TenantId tenantId) { + resourceRepository.removeAllByTenantId(tenantId.getId()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/ResourceRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/ResourceRepository.java index d2d92b8b55..65927ce26e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/ResourceRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/ResourceRepository.java @@ -21,8 +21,11 @@ import org.thingsboard.server.dao.model.sql.ResourceCompositeKey; import org.thingsboard.server.dao.model.sql.ResourceEntity; import java.util.List; +import java.util.UUID; public interface ResourceRepository extends CrudRepository { - List findAllByTenantId(TenantId tenantId); + List findAllByTenantId(UUID tenantId); + + void removeAllByTenantId(UUID tenantId); }