Browse Source

Merge branch 'feature/edge-resource-support' of github.com:AndriiLandiak/thingsboard

pull/9545/head
Andrii Shvaika 3 years ago
parent
commit
2a4cabc2bc
  1. 7
      application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java
  2. 8
      application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java
  3. 8
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java
  4. 4
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java
  5. 57
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/ResourceMsgConstructor.java
  6. 49
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseResourceEdgeEventFetcher.java
  7. 34
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemResourcesEdgeEventFetcher.java
  8. 36
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantResourcesEdgeEventFetcher.java
  9. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java
  10. 12
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java
  11. 61
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/BaseResourceProcessor.java
  12. 101
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/ResourceEdgeProcessor.java
  13. 43
      application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java
  14. 3
      application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java
  15. 123
      application/src/test/java/org/thingsboard/server/edge/ResourceEdgeTest.java
  16. 6
      application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java
  17. 12
      application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java
  18. 3
      application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessorTest.java
  19. 2
      application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetProfileEdgeProcessorTest.java
  20. 3
      application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessorTest.java
  21. 3
      application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceProfileEdgeProcessorTest.java
  22. 4
      common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java
  23. 3
      common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventType.java
  24. 2
      common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java
  25. 15
      common/edge-api/src/main/proto/edge.proto
  26. 28
      dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java

7
application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java

@ -45,6 +45,7 @@ import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewEd
import org.thingsboard.server.service.edge.rpc.processor.ota.OtaPackageEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.queue.QueueEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.relation.RelationEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.resource.ResourceEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.rule.RuleChainEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.tenant.TenantEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.tenant.TenantProfileEdgeProcessor;
@ -122,6 +123,9 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
@Autowired
private RelationEdgeProcessor relationProcessor;
@Autowired
private ResourceEdgeProcessor resourceEdgeProcessor;
@Autowired
protected ApplicationEventPublisher eventPublisher;
@ -221,6 +225,9 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
case TENANT_PROFILE:
tenantProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case TB_RESOURCE:
resourceEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
default:
log.warn("[{}] Edge event type [{}] is not designed to be pushed to edge", tenantId, type);
}

8
application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java

@ -33,6 +33,7 @@ import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService;
import org.thingsboard.server.dao.resource.ResourceService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.dao.tenant.TenantProfileService;
@ -55,6 +56,7 @@ import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewEd
import org.thingsboard.server.service.edge.rpc.processor.ota.OtaPackageEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.queue.QueueEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.relation.RelationEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.resource.ResourceEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.rule.RuleChainEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.settings.AdminSettingsEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.telemetry.TelemetryEdgeProcessor;
@ -139,6 +141,9 @@ public class EdgeContextComponent {
@Autowired
private QueueService queueService;
@Autowired
private ResourceService resourceService;
@Autowired
private AlarmEdgeProcessor alarmProcessor;
@ -199,6 +204,9 @@ public class EdgeContextComponent {
@Autowired
private TenantProfileEdgeProcessor tenantProfileEdgeProcessor;
@Autowired
private ResourceEdgeProcessor resourceEdgeProcessor;
@Autowired
private EdgeMsgConstructor edgeMsgConstructor;

8
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java

@ -63,6 +63,7 @@ import org.thingsboard.server.gen.edge.v1.RelationRequestMsg;
import org.thingsboard.server.gen.edge.v1.RelationUpdateMsg;
import org.thingsboard.server.gen.edge.v1.RequestMsg;
import org.thingsboard.server.gen.edge.v1.RequestMsgType;
import org.thingsboard.server.gen.edge.v1.ResourceUpdateMsg;
import org.thingsboard.server.gen.edge.v1.ResponseMsg;
import org.thingsboard.server.gen.edge.v1.RuleChainMetadataRequestMsg;
import org.thingsboard.server.gen.edge.v1.SyncCompletedMsg;
@ -645,6 +646,8 @@ public final class EdgeGrpcSession implements Closeable {
return ctx.getAdminSettingsProcessor().convertAdminSettingsEventToDownlink(edgeEvent);
case OTA_PACKAGE:
return ctx.getOtaPackageEdgeProcessor().convertOtaPackageEventToDownlink(edgeEvent);
case TB_RESOURCE:
return ctx.getResourceEdgeProcessor().convertResourceEventToDownlink(edgeEvent);
case QUEUE:
return ctx.getQueueEdgeProcessor().convertQueueEventToDownlink(edgeEvent);
case TENANT:
@ -710,6 +713,11 @@ public final class EdgeGrpcSession implements Closeable {
result.add(ctx.getDashboardProcessor().processDashboardMsgFromEdge(edge.getTenantId(), edge, dashboardUpdateMsg));
}
}
if (uplinkMsg.getResourceUpdateMsgCount() > 0) {
for (ResourceUpdateMsg resourceUpdateMsg : uplinkMsg.getResourceUpdateMsgList()) {
result.add(ctx.getResourceEdgeProcessor().processResourceMsgFromEdge(edge.getTenantId(), edge, resourceUpdateMsg));
}
}
if (uplinkMsg.getRuleChainMetadataRequestMsgCount() > 0) {
for (RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg : uplinkMsg.getRuleChainMetadataRequestMsgList()) {
result.add(ctx.getEdgeRequestsService().processRuleChainMetadataRequestMsg(edge.getTenantId(), edge, ruleChainMetadataRequestMsg));

4
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java

@ -33,10 +33,12 @@ import org.thingsboard.server.service.edge.rpc.fetch.EntityViewsEdgeEventFetcher
import org.thingsboard.server.service.edge.rpc.fetch.OtaPackagesEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.QueuesEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.RuleChainsEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.SystemResourcesEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.SystemWidgetTypesEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.SystemWidgetsBundlesEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.TenantAdminUsersEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.TenantEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.TenantResourcesEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.TenantWidgetTypesEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.TenantWidgetsBundlesEdgeEventFetcher;
@ -77,6 +79,8 @@ public class EdgeSyncCursor {
fetchers.add(new SystemWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService()));
fetchers.add(new TenantWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService()));
fetchers.add(new OtaPackagesEdgeEventFetcher(ctx.getOtaPackageService()));
fetchers.add(new SystemResourcesEdgeEventFetcher(ctx.getResourceService()));
fetchers.add(new TenantResourcesEdgeEventFetcher(ctx.getResourceService()));
}
}

57
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/ResourceMsgConstructor.java

@ -0,0 +1,57 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.constructor;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.id.TbResourceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.gen.edge.v1.ResourceUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.queue.util.TbCoreComponent;
@Component
@TbCoreComponent
public class ResourceMsgConstructor {
public ResourceUpdateMsg constructResourceUpdatedMsg(UpdateMsgType msgType, TbResource tbResource) {
ResourceUpdateMsg.Builder builder = ResourceUpdateMsg.newBuilder()
.setMsgType(msgType)
.setIdMSB(tbResource.getId().getId().getMostSignificantBits())
.setIdLSB(tbResource.getId().getId().getLeastSignificantBits())
.setTitle(tbResource.getTitle())
.setResourceKey(tbResource.getResourceKey())
.setResourceType(tbResource.getResourceType().name())
.setFileName(tbResource.getFileName());
if (tbResource.getData() != null) {
builder.setData(tbResource.getData());
}
if (tbResource.getEtag() != null) {
builder.setEtag(tbResource.getEtag());
}
if (tbResource.getTenantId().equals(TenantId.SYS_TENANT_ID)) {
builder.setIsSystem(true);
}
return builder.build();
}
public ResourceUpdateMsg constructResourceDeleteMsg(TbResourceId tbResourceId) {
return ResourceUpdateMsg.newBuilder()
.setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE)
.setIdMSB(tbResourceId.getId().getMostSignificantBits())
.setIdLSB(tbResourceId.getId().getLeastSignificantBits()).build();
}
}

49
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseResourceEdgeEventFetcher.java

@ -0,0 +1,49 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.fetch;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.resource.ResourceService;
@Slf4j
@AllArgsConstructor
public abstract class BaseResourceEdgeEventFetcher extends BasePageableEdgeEventFetcher<TbResource> {
protected final ResourceService resourceService;
@Override
PageData<TbResource> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
return findTenantResources(tenantId, pageLink);
}
@Override
EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, TbResource tbResource) {
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.TB_RESOURCE,
EdgeEventActionType.ADDED, tbResource.getId(), null);
}
protected abstract PageData<TbResource> findTenantResources(TenantId tenantId, PageLink pageLink);
}

34
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemResourcesEdgeEventFetcher.java

@ -0,0 +1,34 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.fetch;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.resource.ResourceService;
public class SystemResourcesEdgeEventFetcher extends BaseResourceEdgeEventFetcher {
public SystemResourcesEdgeEventFetcher(ResourceService resourceService) {
super(resourceService);
}
@Override
protected PageData<TbResource> findTenantResources(TenantId tenantId, PageLink pageLink) {
return resourceService.findAllTenantResources(TenantId.SYS_TENANT_ID, pageLink);
}
}

36
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantResourcesEdgeEventFetcher.java

@ -0,0 +1,36 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.fetch;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.resource.ResourceService;
@Slf4j
public class TenantResourcesEdgeEventFetcher extends BaseResourceEdgeEventFetcher {
public TenantResourcesEdgeEventFetcher(ResourceService resourceService) {
super(resourceService);
}
@Override
protected PageData<TbResource> findTenantResources(TenantId tenantId, PageLink pageLink) {
return resourceService.findAllTenantResources(tenantId, pageLink);
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetsBundlesEdgeEventFetcher.java

@ -28,6 +28,7 @@ public class TenantWidgetsBundlesEdgeEventFetcher extends BaseWidgetsBundlesEdge
public TenantWidgetsBundlesEdgeEventFetcher(WidgetsBundleService widgetsBundleService) {
super(widgetsBundleService);
}
@Override
protected PageData<WidgetsBundle> findWidgetsBundles(TenantId tenantId, PageLink pageLink) {
return widgetsBundleService.findTenantWidgetsBundlesByTenantId(tenantId, pageLink);

12
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java

@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.edge.Edge;
@ -74,6 +75,7 @@ import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.resource.ResourceService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.tenant.TenantProfileService;
@ -103,6 +105,7 @@ import org.thingsboard.server.service.edge.rpc.constructor.OtaPackageMsgConstruc
import org.thingsboard.server.service.edge.rpc.constructor.QueueMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.RelationMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.RuleChainMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.ResourceMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.TenantMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.TenantProfileMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.UserMsgConstructor;
@ -215,6 +218,9 @@ public abstract class BaseEdgeProcessor {
@Autowired
protected PartitionService partitionService;
@Autowired
protected ResourceService resourceService;
@Autowired
@Lazy
protected TbQueueProducerProvider producerProvider;
@ -237,6 +243,9 @@ public abstract class BaseEdgeProcessor {
@Autowired
protected DataValidator<EntityView> entityViewValidator;
@Autowired
protected DataValidator<TbResource> resourceValidator;
@Autowired
protected EdgeMsgConstructor edgeMsgConstructor;
@ -297,6 +306,9 @@ public abstract class BaseEdgeProcessor {
@Autowired
protected QueueMsgConstructor queueMsgConstructor;
@Autowired
protected ResourceMsgConstructor resourceMsgConstructor;
@Autowired
protected EdgeSynchronizationManager edgeSynchronizationManager;

61
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/BaseResourceProcessor.java

@ -0,0 +1,61 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.processor.resource;
import com.datastax.oss.driver.api.core.uuid.Uuids;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.id.TbResourceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.gen.edge.v1.ResourceUpdateMsg;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@Slf4j
public abstract class BaseResourceProcessor extends BaseEdgeProcessor {
protected void saveOrUpdateTbResource(TenantId tenantId, TbResourceId tbResourceId, ResourceUpdateMsg resourceUpdateMsg) {
try {
boolean created = false;
TbResource resource = resourceService.findResourceById(tenantId, tbResourceId);
if (resource == null) {
resource = new TbResource();
if (resourceUpdateMsg.getIsSystem()) {
resource.setTenantId(TenantId.SYS_TENANT_ID);
} else {
resource.setTenantId(tenantId);
}
resource.setCreatedTime(Uuids.unixTimestamp(tbResourceId.getId()));
created = true;
}
resource.setTitle(resourceUpdateMsg.getTitle());
resource.setResourceKey(resourceUpdateMsg.getResourceKey());
resource.setResourceType(ResourceType.valueOf(resourceUpdateMsg.getResourceType()));
resource.setFileName(resourceUpdateMsg.getFileName());
resource.setData(resourceUpdateMsg.hasData() ? resourceUpdateMsg.getData() : null);
resource.setEtag(resourceUpdateMsg.hasEtag() ? resourceUpdateMsg.getEtag() : null);
resourceValidator.validate(resource, TbResourceInfo::getTenantId);
if (created) {
resource.setId(tbResourceId);
}
resourceService.saveResource(resource, false);
} catch (Exception e) {
log.error("[{}] Failed to process resource update msg [{}]", tenantId, resourceUpdateMsg, e);
throw e;
}
}
}

101
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/ResourceEdgeProcessor.java

@ -0,0 +1,101 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.processor.resource;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.TbResourceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.ResourceUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.queue.util.TbCoreComponent;
import java.util.UUID;
@Component
@Slf4j
@TbCoreComponent
public class ResourceEdgeProcessor extends BaseResourceProcessor {
public ListenableFuture<Void> processResourceMsgFromEdge(TenantId tenantId, Edge edge, ResourceUpdateMsg resourceUpdateMsg) {
TbResourceId tbResourceId = new TbResourceId(new UUID(resourceUpdateMsg.getIdMSB(), resourceUpdateMsg.getIdLSB()));
try {
edgeSynchronizationManager.getEdgeId().set(edge.getId());
switch (resourceUpdateMsg.getMsgType()) {
case ENTITY_CREATED_RPC_MESSAGE:
case ENTITY_UPDATED_RPC_MESSAGE:
super.saveOrUpdateTbResource(tenantId, tbResourceId, resourceUpdateMsg);
break;
case ENTITY_DELETED_RPC_MESSAGE:
TbResource tbResourceToDelete = resourceService.findResourceById(tenantId, tbResourceId);
if (tbResourceToDelete != null) {
resourceService.deleteResource(tenantId, tbResourceId);
}
break;
case UNRECOGNIZED:
return handleUnsupportedMsgType(resourceUpdateMsg.getMsgType());
}
} catch (DataValidationException e) {
if (e.getMessage().contains("files size limit is exhausted")) {
log.warn("[{}] Resource data size has been exhausted {}", tenantId, resourceUpdateMsg, e);
return Futures.immediateFuture(null);
} else {
return Futures.immediateFailedFuture(e);
}
} finally {
edgeSynchronizationManager.getEdgeId().remove();
}
return Futures.immediateFuture(null);
}
public DownlinkMsg convertResourceEventToDownlink(EdgeEvent edgeEvent) {
TbResourceId tbResourceId = new TbResourceId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
TbResource tbResource = resourceService.findResourceById(edgeEvent.getTenantId(), tbResourceId);
if (tbResource != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
ResourceUpdateMsg resourceUpdateMsg =
resourceMsgConstructor.constructResourceUpdatedMsg(msgType, tbResource);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addResourceUpdateMsg(resourceUpdateMsg)
.build();
}
break;
case DELETED:
ResourceUpdateMsg resourceUpdateMsg =
resourceMsgConstructor.constructResourceDeleteMsg(tbResourceId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addResourceUpdateMsg(resourceUpdateMsg)
.build();
break;
}
return downlinkMsg;
}
}

43
application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java

@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.JsonNode;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.http.HttpHeaders;
@ -39,7 +38,6 @@ import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DaoSqlTest;
@ -105,9 +103,9 @@ public class TbResourceControllerTest extends AbstractControllerTest {
TbResource savedResource = save(resource);
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedResource, savedResource.getId(), savedResource.getId(),
testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(savedResource, savedResource.getId(), savedResource.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED);
ActionType.ADDED, ActionType.ADDED);
Assert.assertNotNull(savedResource);
Assert.assertNotNull(savedResource.getId());
@ -125,9 +123,9 @@ public class TbResourceControllerTest extends AbstractControllerTest {
TbResource foundResource = doGet("/api/resource/" + savedResource.getId().getId().toString(), TbResource.class);
Assert.assertEquals(foundResource.getTitle(), savedResource.getTitle());
testNotifyEntityOneTimeMsgToEdgeServiceNever(foundResource, foundResource.getId(), foundResource.getId(),
testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(foundResource, foundResource.getId(), foundResource.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.UPDATED);
ActionType.UPDATED, ActionType.UPDATED);
}
@Test
@ -157,7 +155,7 @@ public class TbResourceControllerTest extends AbstractControllerTest {
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData(TEST_DATA);
TbResource savedResource = save(resource);
TbResource savedResource = save(resource);
loginDifferentTenant();
@ -209,9 +207,9 @@ public class TbResourceControllerTest extends AbstractControllerTest {
.andExpect(status().isOk());
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedResource, savedResource.getId(), savedResource.getId(),
testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(savedResource, savedResource.getId(), savedResource.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.DELETED, resourceIdStr);
ActionType.DELETED, ActionType.DELETED, resourceIdStr);
doGet("/api/resource/" + savedResource.getId().getId().toString())
.andExpect(status().isNotFound())
@ -240,7 +238,7 @@ public class TbResourceControllerTest extends AbstractControllerTest {
doDelete("/api/resource/" + resourceIdStr)
.andExpect(status().isBadRequest())
.andExpect(statusReason(containsString("Following widget types uses current resource: ["
+ widgetType .getName()+ "]")));
+ widgetType.getName() + "]")));
}
@Test
@ -271,9 +269,9 @@ public class TbResourceControllerTest extends AbstractControllerTest {
}
} while (pageData.hasNext());
testNotifyManyEntityManyTimeMsgToEdgeServiceNever(new TbResource(), new TbResource(),
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new TbResource(), new TbResource(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, cntEntity);
ActionType.ADDED, cntEntity, cntEntity, cntEntity);
Collections.sort(resources, idComparator);
Collections.sort(loadedResources, idComparator);
@ -319,9 +317,9 @@ public class TbResourceControllerTest extends AbstractControllerTest {
}
} while (pageData.hasNext());
testNotifyManyEntityManyTimeMsgToEdgeServiceNever(new TbResource(), new TbResource(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, jksCntEntity + lwm2mCntEntity);
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new TbResource(), new TbResource(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED,
jksCntEntity + lwm2mCntEntity, jksCntEntity + lwm2mCntEntity, jksCntEntity + lwm2mCntEntity);
Collections.sort(resources, idComparator);
Collections.sort(loadedResources, idComparator);
@ -368,9 +366,9 @@ public class TbResourceControllerTest extends AbstractControllerTest {
.andExpect(status().isOk());
}
testNotifyManyEntityManyTimeMsgToEdgeServiceNeverAdditionalInfoAny(new TbResource(), new TbResource(),
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(new TbResource(), new TbResource(),
resources.get(0).getTenantId(), null, null, SYS_ADMIN_EMAIL,
ActionType.DELETED, cntEntity, 1);
ActionType.DELETED, ActionType.DELETED, cntEntity, cntEntity, 1);
pageLink = new PageLink(27);
loadedResources.clear();
@ -441,9 +439,9 @@ public class TbResourceControllerTest extends AbstractControllerTest {
.andExpect(status().isOk());
}
testNotifyManyEntityManyTimeMsgToEdgeServiceNeverAdditionalInfoAny(new TbResource(), new TbResource(),
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(new TbResource(), new TbResource(),
jksResources.get(0).getTenantId(), null, null, SYS_ADMIN_EMAIL,
ActionType.DELETED, cntEntity, 1);
ActionType.DELETED, ActionType.DELETED, cntEntity, cntEntity, 1);
pageLink = new PageLink(27);
loadedResources.clear();
@ -535,9 +533,9 @@ public class TbResourceControllerTest extends AbstractControllerTest {
TbResource savedResource = save(resource);
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedResource, savedResource.getId(), savedResource.getId(),
testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(savedResource, savedResource.getId(), savedResource.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED);
ActionType.ADDED, ActionType.ADDED);
ResultActions resultActions = doGet("/api/resource/js/" + savedResource.getId().getId().toString() + "/download")
.andExpect(status().isOk());
@ -617,6 +615,7 @@ public class TbResourceControllerTest extends AbstractControllerTest {
}
private TbResource save(TbResource tbResource) throws Exception {
return doPostWithTypedResponse("/api/resource", tbResource, new TypeReference<>(){});
return doPostWithTypedResponse("/api/resource", tbResource, new TypeReference<>() {
});
}
}

3
application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.edge;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.protobuf.InvalidProtocolBufferException;
@ -387,7 +386,7 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
Assert.assertEquals(expectedRuleChainUUID, ruleChainUUID);
}
private void validateAdminSettings() throws JsonProcessingException {
private void validateAdminSettings() {
List<AdminSettingsUpdateMsg> adminSettingsUpdateMsgs = edgeImitator.findAllMessagesByType(AdminSettingsUpdateMsg.class);
Assert.assertEquals(4, adminSettingsUpdateMsgs.size());

123
application/src/test/java/org/thingsboard/server/edge/ResourceEdgeTest.java

File diff suppressed because one or more lines are too long

6
application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java

@ -45,6 +45,7 @@ import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg;
import org.thingsboard.server.gen.edge.v1.OtaPackageUpdateMsg;
import org.thingsboard.server.gen.edge.v1.QueueUpdateMsg;
import org.thingsboard.server.gen.edge.v1.RelationUpdateMsg;
import org.thingsboard.server.gen.edge.v1.ResourceUpdateMsg;
import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg;
import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg;
import org.thingsboard.server.gen.edge.v1.TenantProfileUpdateMsg;
@ -303,6 +304,11 @@ public class EdgeImitator {
result.add(saveDownlinkMsg(tenantProfileUpdateMsg));
}
}
if (downlinkMsg.getResourceUpdateMsgCount() > 0) {
for (ResourceUpdateMsg resourceUpdateMsg : downlinkMsg.getResourceUpdateMsgList()) {
result.add(saveDownlinkMsg(resourceUpdateMsg));
}
}
if (downlinkMsg.hasEdgeConfiguration()) {
result.add(saveDownlinkMsg(downlinkMsg.getEdgeConfiguration()));
}

12
application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java

@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.edge.EdgeEvent;
@ -47,6 +48,7 @@ import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.resource.ResourceService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.tenant.TenantProfileService;
@ -72,6 +74,7 @@ import org.thingsboard.server.service.edge.rpc.constructor.EntityViewMsgConstruc
import org.thingsboard.server.service.edge.rpc.constructor.OtaPackageMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.QueueMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.RelationMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.ResourceMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.RuleChainMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.TenantMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.TenantProfileMsgConstructor;
@ -174,6 +177,9 @@ public abstract class BaseEdgeProcessorTest {
@MockBean
protected PartitionService partitionService;
@MockBean
protected ResourceService resourceService;
@MockBean
@Lazy
protected TbQueueProducerProvider producerProvider;
@ -196,6 +202,9 @@ public abstract class BaseEdgeProcessorTest {
@MockBean
protected DataValidator<EntityView> entityViewValidator;
@MockBean
protected DataValidator<TbResource> resourceValidator;
@MockBean
protected EdgeMsgConstructor edgeMsgConstructor;
@ -256,6 +265,9 @@ public abstract class BaseEdgeProcessorTest {
@MockBean
protected QueueMsgConstructor queueMsgConstructor;
@MockBean
protected ResourceMsgConstructor resourceMsgConstructor;
@MockBean
protected EdgeSynchronizationManager edgeSynchronizationManager;

3
application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessorTest.java

@ -40,5 +40,4 @@ class AssetEdgeProcessorTest extends AbstractAssetProcessorTest {
verify(downlinkMsg, expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB);
}
}
}

2
application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetProfileEdgeProcessorTest.java

@ -40,4 +40,4 @@ class AssetProfileEdgeProcessorTest extends AbstractAssetProcessorTest{
verify(downlinkMsg, expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB);
}
}
}

3
application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessorTest.java

@ -39,5 +39,4 @@ class DeviceEdgeProcessorTest extends AbstractDeviceProcessorTest {
verify(downlinkMsg, expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB);
}
}
}

3
application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceProfileEdgeProcessorTest.java

@ -41,5 +41,4 @@ class DeviceProfileEdgeProcessorTest extends AbstractDeviceProcessorTest {
verify(downlinkMsg, expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB);
}
}
}

4
common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java

@ -32,12 +32,16 @@ public interface ResourceService extends EntityDaoService {
TbResource saveResource(TbResource resource);
TbResource saveResource(TbResource resource, boolean doValidate);
TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId);
TbResource findResourceById(TenantId tenantId, TbResourceId resourceId);
TbResourceInfo findResourceInfoById(TenantId tenantId, TbResourceId resourceId);
PageData<TbResource> findAllTenantResources(TenantId tenantId, PageLink pageLink);
ListenableFuture<TbResourceInfo> findResourceInfoByIdAsync(TenantId tenantId, TbResourceId resourceId);
PageData<TbResourceInfo> findAllTenantResourcesByTenantId(TbResourceInfoFilter filter, PageLink pageLink);

3
common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventType.java

@ -39,7 +39,8 @@ public enum EdgeEventType {
WIDGET_TYPE(true, EntityType.WIDGET_TYPE),
ADMIN_SETTINGS(true, null),
OTA_PACKAGE(true, EntityType.OTA_PACKAGE),
QUEUE(true, EntityType.QUEUE);
QUEUE(true, EntityType.QUEUE),
TB_RESOURCE(true, EntityType.TB_RESOURCE);
private final boolean allEdgesRelated;

2
common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java

@ -143,6 +143,8 @@ public class EntityIdFactory {
return new EdgeId(uuid);
case QUEUE:
return new QueueId(uuid);
case TB_RESOURCE:
return new TbResourceId(uuid);
}
throw new IllegalArgumentException("EdgeEventType " + edgeEventType + " is not supported!");
}

15
common/edge-api/src/main/proto/edge.proto

@ -424,6 +424,19 @@ message TenantProfileUpdateMsg {
bytes profileDataBytes = 8;
}
message ResourceUpdateMsg {
UpdateMsgType msgType = 1;
int64 idMSB = 2;
int64 idLSB = 3;
string title = 4;
string resourceType = 5;
string resourceKey = 6;
string fileName = 7;
optional string data = 8;
optional string etag = 9;
bool isSystem = 10;
}
message RuleChainMetadataRequestMsg {
int64 ruleChainIdMSB = 1;
int64 ruleChainIdLSB = 2;
@ -575,6 +588,7 @@ message UplinkMsg {
repeated EntityViewUpdateMsg entityViewUpdateMsg = 18;
repeated AssetProfileUpdateMsg assetProfileUpdateMsg = 19;
repeated DeviceProfileUpdateMsg deviceProfileUpdateMsg = 20;
repeated ResourceUpdateMsg resourceUpdateMsg = 21;
}
message UplinkResponseMsg {
@ -617,5 +631,6 @@ message DownlinkMsg {
EdgeConfiguration edgeConfiguration = 25;
repeated TenantUpdateMsg tenantUpdateMsg = 26;
repeated TenantProfileUpdateMsg tenantProfileUpdateMsg = 27;
repeated ResourceUpdateMsg resourceUpdateMsg = 28;
}

28
dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java

@ -21,10 +21,9 @@ import lombok.extern.slf4j.Slf4j;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.event.TransactionalEventListener;
import org.thingsboard.server.cache.device.DeviceCacheKey;
import org.thingsboard.server.cache.resourceInfo.ResourceInfoCacheKey;
import org.thingsboard.server.cache.resourceInfo.ResourceInfoEvictEvent;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.cache.resourceInfo.ResourceInfoCacheKey;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo;
@ -36,6 +35,8 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.entity.AbstractCachedEntityService;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover;
@ -59,10 +60,23 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
@Override
public TbResource saveResource(TbResource resource) {
resourceValidator.validate(resource, TbResourceInfo::getTenantId);
return doSaveResource(resource, true);
}
@Override
public TbResource saveResource(TbResource resource, boolean doValidate) {
return doSaveResource(resource, doValidate);
}
private TbResource doSaveResource(TbResource resource, boolean doValidate) {
if (doValidate) {
resourceValidator.validate(resource, TbResourceInfo::getTenantId);
}
try {
TbResource saved = resourceDao.save(resource.getTenantId(), resource);
publishEvictEvent(new ResourceInfoEvictEvent(resource.getTenantId(), resource.getId()));
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(saved.getTenantId())
.entityId(saved.getId()).added(resource.getId() == null).build());
return saved;
} catch (Exception t) {
publishEvictEvent(new ResourceInfoEvictEvent(resource.getTenantId(), resource.getId()));
@ -111,6 +125,7 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
Validator.validateId(resourceId, INCORRECT_RESOURCE_ID + resourceId);
resourceValidator.validateDelete(tenantId, resourceId);
resourceDao.removeById(tenantId, resourceId.getId());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(resourceId).build());
}
@Override
@ -136,6 +151,13 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
return resourceDao.findResourcesByTenantIdAndResourceType(tenantId, resourceType, objectIds, null);
}
@Override
public PageData<TbResource> findAllTenantResources(TenantId tenantId, PageLink pageLink) {
log.trace("Executing findAllTenantResources [{}][{}]", tenantId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
return resourceDao.findAllByTenantId(tenantId, pageLink);
}
@Override
public PageData<TbResource> findTenantResourcesByResourceTypeAndPageLink(TenantId tenantId, ResourceType resourceType, PageLink pageLink) {
log.trace("Executing findTenantResourcesByResourceTypeAndPageLink [{}][{}][{}]", tenantId, resourceType, pageLink);

Loading…
Cancel
Save