26 changed files with 593 additions and 35 deletions
@ -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(); |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue