Version control support for resources
This commit is contained in:
parent
6eadef0d68
commit
72ae6eb708
@ -30,5 +30,6 @@ $$;
|
||||
ALTER TABLE resource
|
||||
ADD COLUMN IF NOT EXISTS descriptor varchar,
|
||||
ADD COLUMN IF NOT EXISTS preview bytea;
|
||||
ALTER TABLE resource ADD COLUMN IF NOT EXISTS external_id uuid
|
||||
|
||||
-- RESOURCES UPDATE END
|
||||
|
||||
@ -35,7 +35,6 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.server.common.data.ImageDescriptor;
|
||||
import org.thingsboard.server.common.data.ResourceType;
|
||||
import org.thingsboard.server.common.data.TbResource;
|
||||
@ -88,7 +87,7 @@ public class ImageController extends BaseController {
|
||||
image.setResourceType(ResourceType.IMAGE);
|
||||
ImageDescriptor descriptor = new ImageDescriptor();
|
||||
descriptor.setMediaType(file.getContentType());
|
||||
image.setDescriptor(JacksonUtil.valueToTree(descriptor));
|
||||
image.setDescriptorValue(descriptor);
|
||||
image.setData(file.getBytes());
|
||||
return tbImageService.save(image, user);
|
||||
}
|
||||
@ -99,11 +98,12 @@ public class ImageController extends BaseController {
|
||||
@PathVariable String key,
|
||||
@RequestPart MultipartFile file) throws Exception {
|
||||
TbResourceInfo imageInfo = checkImageInfo(type, key, Operation.WRITE);
|
||||
ImageDescriptor descriptor = imageInfo.getDescriptor(ImageDescriptor.class);
|
||||
|
||||
TbResource image = new TbResource(imageInfo);
|
||||
image.setData(file.getBytes());
|
||||
image.updateDescriptor(ImageDescriptor.class, descriptor -> {
|
||||
descriptor.setMediaType(file.getContentType());
|
||||
return descriptor;
|
||||
});
|
||||
return tbImageService.save(image, getCurrentUser());
|
||||
}
|
||||
|
||||
|
||||
@ -53,6 +53,7 @@ import org.thingsboard.server.service.security.permission.Operation;
|
||||
import org.thingsboard.server.service.security.permission.Resource;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -226,6 +227,30 @@ public class TbResourceController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "Get All Resource Infos (getAllResources)",
|
||||
notes = "Returns a page of Resource Info objects owned by tenant. " +
|
||||
PAGE_DATA_PARAMETERS + RESOURCE_INFO_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH,
|
||||
produces = "application/json")
|
||||
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
|
||||
@GetMapping(value = "/resource/tenant")
|
||||
public PageData<TbResourceInfo> getTenantResources(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
|
||||
@RequestParam int pageSize,
|
||||
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
|
||||
@RequestParam int page,
|
||||
@ApiParam(value = RESOURCE_TEXT_SEARCH_DESCRIPTION)
|
||||
@RequestParam(required = false) String textSearch,
|
||||
@ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES)
|
||||
@RequestParam(required = false) String sortProperty,
|
||||
@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
|
||||
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
|
||||
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
|
||||
TbResourceInfoFilter filter = TbResourceInfoFilter.builder()
|
||||
.tenantId(getTenantId())
|
||||
.resourceTypes(EnumSet.allOf(ResourceType.class))
|
||||
.build();
|
||||
return checkNotNull(resourceService.findTenantResourcesByTenantId(filter, pageLink));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "Get LwM2M Objects (getLwm2mListObjectsPage)",
|
||||
notes = "Returns a page of LwM2M objects parsed from Resources with type 'LWM2M_MODEL' owned by tenant or sysadmin. " +
|
||||
PAGE_DATA_PARAMETERS + LWM2M_OBJECT_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH,
|
||||
|
||||
@ -118,6 +118,16 @@ public class DefaultExportableEntitiesService implements ExportableEntitiesServi
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <I extends EntityId> PageData<I> findEntitiesIdsByTenantId(TenantId tenantId, EntityType entityType, PageLink pageLink) {
|
||||
ExportableEntityDao<I, ?> dao = getExportableEntityDao(entityType);
|
||||
if (dao != null) {
|
||||
return dao.findIdsByTenantId(tenantId.getId(), pageLink);
|
||||
} else {
|
||||
return new PageData<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <I extends EntityId> I getExternalIdByInternal(I internalId) {
|
||||
ExportableEntityDao<I, ?> dao = getExportableEntityDao(internalId.getEntityType());
|
||||
|
||||
@ -35,6 +35,8 @@ public interface ExportableEntitiesService {
|
||||
|
||||
<E extends ExportableEntity<I>, I extends EntityId> PageData<E> findEntitiesByTenantId(TenantId tenantId, EntityType entityType, PageLink pageLink);
|
||||
|
||||
<I extends EntityId> PageData<I> findEntitiesIdsByTenantId(TenantId tenantId, EntityType entityType, PageLink pageLink);
|
||||
|
||||
<I extends EntityId> I getExternalIdByInternal(I internalId);
|
||||
|
||||
<I extends EntityId> void removeById(TenantId tenantId, I id);
|
||||
|
||||
@ -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.sync.ie.exporting.impl;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.TbResource;
|
||||
import org.thingsboard.server.common.data.id.TbResourceId;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Service
|
||||
@TbCoreComponent
|
||||
public class ResourceExportService extends BaseEntityExportService<TbResourceId, TbResource, EntityExportData<TbResource>> {
|
||||
|
||||
@Override
|
||||
public Set<EntityType> getSupportedEntityTypes() {
|
||||
return Set.of(EntityType.TB_RESOURCE);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* 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.sync.ie.importing.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.TbResource;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
|
||||
import org.thingsboard.server.common.data.id.TbResourceId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.dao.resource.ResourceService;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||
|
||||
@Service
|
||||
@TbCoreComponent
|
||||
@RequiredArgsConstructor
|
||||
public class ResourceImportService extends BaseEntityImportService<TbResourceId, TbResource, EntityExportData<TbResource>> {
|
||||
|
||||
private final ResourceService resourceService;
|
||||
|
||||
@Override
|
||||
protected void setOwner(TenantId tenantId, TbResource resource, IdProvider idProvider) {
|
||||
resource.setTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TbResource prepare(EntitiesImportCtx ctx, TbResource resource, TbResource oldResource, EntityExportData<TbResource> exportData, IdProvider idProvider) {
|
||||
return resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TbResource findExistingEntity(EntitiesImportCtx ctx, TbResource resource, IdProvider idProvider) {
|
||||
TbResource existingResource = super.findExistingEntity(ctx, resource, idProvider);
|
||||
if (existingResource == null && ctx.isFindExistingByName()) {
|
||||
existingResource = resourceService.findResourceByTenantIdAndKey(ctx.getTenantId(), resource.getResourceType(), resource.getResourceKey());
|
||||
}
|
||||
return existingResource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean compare(EntitiesImportCtx ctx, EntityExportData<TbResource> exportData, TbResource prepared, TbResource existing) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TbResource deepCopy(TbResource resource) {
|
||||
return new TbResource(resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TbResource saveOrUpdate(EntitiesImportCtx ctx, TbResource resource, EntityExportData<TbResource> exportData, IdProvider idProvider) {
|
||||
return resourceService.saveResource(resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEntitySaved(User user, TbResource savedResource, TbResource oldResource) throws ThingsboardException {
|
||||
super.onEntitySaved(user, savedResource, oldResource);
|
||||
clusterService.onResourceChange(savedResource, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getEntityType() {
|
||||
return EntityType.TB_RESOURCE;
|
||||
}
|
||||
|
||||
}
|
||||
@ -20,13 +20,9 @@ import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.id.WidgetTypeId;
|
||||
import org.thingsboard.server.common.data.id.WidgetsBundleId;
|
||||
import org.thingsboard.server.common.data.sync.ie.WidgetTypeExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.WidgetsBundleExportData;
|
||||
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
|
||||
import org.thingsboard.server.common.data.widget.WidgetsBundle;
|
||||
import org.thingsboard.server.dao.widget.WidgetTypeService;
|
||||
import org.thingsboard.server.dao.widget.WidgetsBundleService;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||
|
||||
|
||||
@ -208,10 +208,10 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
}
|
||||
|
||||
if (config.isAllEntities()) {
|
||||
DaoUtil.processInBatches(pageLink -> exportableEntitiesService.findEntitiesByTenantId(ctx.getTenantId(), entityType, pageLink)
|
||||
, 100, entity -> {
|
||||
DaoUtil.processInBatches(pageLink -> exportableEntitiesService.findEntitiesIdsByTenantId(ctx.getTenantId(), entityType, pageLink),
|
||||
100, entityId -> {
|
||||
try {
|
||||
ctx.add(saveEntityData(ctx, entity.getId()));
|
||||
ctx.add(saveEntityData(ctx, entityId));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ public interface ResourceService extends EntityDaoService {
|
||||
|
||||
TbResource saveResource(TbResource resource, boolean doValidate);
|
||||
|
||||
TbResource findResourceByTenantIdAndKey(TenantId tenantId, ResourceType resourceType, String resourceId);
|
||||
TbResource findResourceByTenantIdAndKey(TenantId tenantId, ResourceType resourceType, String resourceKey);
|
||||
|
||||
TbResource findResourceById(TenantId tenantId, TbResourceId resourceId);
|
||||
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
package org.thingsboard.server.common.data;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonSetter;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
@ -34,10 +33,8 @@ public class TbResource extends TbResourceInfo {
|
||||
|
||||
private static final long serialVersionUID = 7379609705527272306L;
|
||||
|
||||
@JsonIgnore
|
||||
private byte[] data;
|
||||
|
||||
@JsonIgnore
|
||||
private byte[] preview;
|
||||
|
||||
public TbResource() {
|
||||
|
||||
@ -19,7 +19,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
@ -30,11 +29,13 @@ import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.validation.Length;
|
||||
import org.thingsboard.server.common.data.validation.NoXss;
|
||||
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
@ApiModel
|
||||
@Slf4j
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class TbResourceInfo extends BaseData<TbResourceId> implements HasName, HasTenantId {
|
||||
public class TbResourceInfo extends BaseData<TbResourceId> implements HasName, HasTenantId, ExportableEntity<TbResourceId> {
|
||||
|
||||
private static final long serialVersionUID = 7282664529021651736L;
|
||||
|
||||
@ -52,15 +53,17 @@ public class TbResourceInfo extends BaseData<TbResourceId> implements HasName, H
|
||||
private String resourceKey;
|
||||
@ApiModelProperty(position = 7, value = "Resource search text.", example = "19_1.0:binaryappdatacontainer", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
|
||||
private String searchText;
|
||||
|
||||
@ApiModelProperty(position = 8, value = "Resource etag.", example = "33a64df551425fcc55e4d42a148795d9f25f89d4", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
|
||||
private String etag;
|
||||
@NoXss
|
||||
@Length(fieldName = "file name")
|
||||
@ApiModelProperty(position = 9, value = "Resource file name.", example = "19.xml", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
|
||||
private String fileName;
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
private JsonNode descriptor;
|
||||
|
||||
private TbResourceId externalId;
|
||||
|
||||
public TbResourceInfo() {
|
||||
super();
|
||||
}
|
||||
@ -78,7 +81,8 @@ public class TbResourceInfo extends BaseData<TbResourceId> implements HasName, H
|
||||
this.searchText = resourceInfo.searchText;
|
||||
this.etag = resourceInfo.etag;
|
||||
this.fileName = resourceInfo.fileName;
|
||||
this.descriptor = resourceInfo.descriptor;
|
||||
this.descriptor = resourceInfo.descriptor != null ? resourceInfo.descriptor.deepCopy() : null;
|
||||
this.externalId = resourceInfo.externalId;
|
||||
}
|
||||
|
||||
@ApiModelProperty(position = 1, value = "JSON object with the Resource Id. " +
|
||||
@ -97,7 +101,7 @@ public class TbResourceInfo extends BaseData<TbResourceId> implements HasName, H
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonIgnore
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
public String getName() {
|
||||
return title;
|
||||
}
|
||||
@ -107,9 +111,19 @@ public class TbResourceInfo extends BaseData<TbResourceId> implements HasName, H
|
||||
return searchText != null ? searchText : title;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public <T> T getDescriptor(Class<T> type) throws JsonProcessingException {
|
||||
return descriptor != null ? mapper.treeToValue(descriptor, type) : null;
|
||||
}
|
||||
|
||||
public <T> void updateDescriptor(Class<T> type, UnaryOperator<T> updater) throws JsonProcessingException {
|
||||
T descriptor = getDescriptor(type);
|
||||
descriptor = updater.apply(descriptor);
|
||||
setDescriptorValue(descriptor);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void setDescriptorValue(Object value) {
|
||||
this.descriptor = value != null ? mapper.valueToTree(value) : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -25,6 +25,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.notification.rule.NotificationRule;
|
||||
@ -56,7 +57,8 @@ import java.lang.annotation.Target;
|
||||
@Type(name = "WIDGET_TYPE", value = WidgetTypeDetails.class),
|
||||
@Type(name = "NOTIFICATION_TEMPLATE", value = NotificationTemplate.class),
|
||||
@Type(name = "NOTIFICATION_TARGET", value = NotificationTarget.class),
|
||||
@Type(name = "NOTIFICATION_RULE", value = NotificationRule.class)
|
||||
@Type(name = "NOTIFICATION_RULE", value = NotificationRule.class),
|
||||
@Type(name = "TB_RESOURCE", value = TbResource.class)
|
||||
})
|
||||
@JsonIgnoreProperties(value = {"tenantId", "createdTime"}, ignoreUnknown = true)
|
||||
public @interface JsonTbEntity {
|
||||
|
||||
@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.page.PageLink;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface ExportableEntityDao<I extends EntityId, T extends ExportableEntity<?>> extends Dao<T> {
|
||||
public interface ExportableEntityDao<I extends EntityId, T extends ExportableEntity<I>> extends Dao<T> {
|
||||
|
||||
T findByTenantIdAndExternalId(UUID tenantId, UUID externalId);
|
||||
|
||||
@ -30,6 +30,10 @@ public interface ExportableEntityDao<I extends EntityId, T extends ExportableEnt
|
||||
|
||||
PageData<T> findByTenantId(UUID tenantId, PageLink pageLink);
|
||||
|
||||
default PageData<I> findIdsByTenantId(UUID tenantId, PageLink pageLink) {
|
||||
return findByTenantId(tenantId, pageLink).mapData(ExportableEntity::getId);
|
||||
}
|
||||
|
||||
I getExternalIdByInternal(I internalId);
|
||||
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EXTERNAL_ID_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_DATA_COLUMN;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_DESCRIPTOR_COLUMN;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_ETAG_COLUMN;
|
||||
@ -82,6 +83,9 @@ public class TbResourceEntity extends BaseSqlEntity<TbResource> {
|
||||
@Column(name = RESOURCE_PREVIEW_COLUMN)
|
||||
private byte[] preview;
|
||||
|
||||
@Column(name = EXTERNAL_ID_PROPERTY)
|
||||
private UUID externalId;
|
||||
|
||||
public TbResourceEntity() {
|
||||
}
|
||||
|
||||
@ -102,6 +106,7 @@ public class TbResourceEntity extends BaseSqlEntity<TbResource> {
|
||||
this.etag = resource.getEtag();
|
||||
this.descriptor = resource.getDescriptor();
|
||||
this.preview = resource.getPreview();
|
||||
this.externalId = getUuid(resource.getExternalId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -118,6 +123,7 @@ public class TbResourceEntity extends BaseSqlEntity<TbResource> {
|
||||
resource.setEtag(etag);
|
||||
resource.setDescriptor(descriptor);
|
||||
resource.setPreview(preview);
|
||||
resource.setExternalId(getEntityId(externalId, TbResourceId::new));
|
||||
return resource;
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EXTERNAL_ID_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_DESCRIPTOR_COLUMN;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_ETAG_COLUMN;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_FILE_NAME_COLUMN;
|
||||
@ -75,6 +76,9 @@ public class TbResourceInfoEntity extends BaseSqlEntity<TbResourceInfo> implemen
|
||||
@Column(name = RESOURCE_DESCRIPTOR_COLUMN)
|
||||
private JsonNode descriptor;
|
||||
|
||||
@Column(name = EXTERNAL_ID_PROPERTY)
|
||||
private UUID externalId;
|
||||
|
||||
public TbResourceInfoEntity() {
|
||||
}
|
||||
|
||||
@ -91,6 +95,7 @@ public class TbResourceInfoEntity extends BaseSqlEntity<TbResourceInfo> implemen
|
||||
this.hashCode = resource.getEtag();
|
||||
this.fileName = resource.getFileName();
|
||||
this.descriptor = resource.getDescriptor();
|
||||
this.externalId = getUuid(resource.getExternalId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -105,6 +110,7 @@ public class TbResourceInfoEntity extends BaseSqlEntity<TbResourceInfo> implemen
|
||||
resource.setEtag(hashCode);
|
||||
resource.setFileName(fileName);
|
||||
resource.setDescriptor(descriptor);
|
||||
resource.setExternalId(getEntityId(externalId, TbResourceId::new));
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ public class BaseImageService extends BaseResourceService implements ImageServic
|
||||
Pair<ImageDescriptor, byte[]> result = processImage(image.getData(), descriptor);
|
||||
descriptor = result.getLeft();
|
||||
image.setEtag(descriptor.getEtag());
|
||||
image.setDescriptor(JacksonUtil.valueToTree(descriptor));
|
||||
image.setDescriptorValue(descriptor);
|
||||
image.setPreview(result.getRight());
|
||||
|
||||
return new TbResourceInfo(doSaveResource(image));
|
||||
|
||||
@ -96,8 +96,7 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
|
||||
publishEvictEvent(new ResourceInfoEvictEvent(tenantId, resource.getId()));
|
||||
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null);
|
||||
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("resource_unq_key")) {
|
||||
String field = ResourceType.LWM2M_MODEL.equals(resource.getResourceType()) ? "resourceKey" : "fileName";
|
||||
throw new DataValidationException("Resource with such " + field + " already exists!");
|
||||
throw new DataValidationException("Resource with such key already exists!");
|
||||
} else {
|
||||
throw t;
|
||||
}
|
||||
@ -202,6 +201,11 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
|
||||
return Optional.ofNullable(findResourceInfoById(tenantId, new TbResourceId(entityId.getId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteEntity(TenantId tenantId, EntityId id) {
|
||||
deleteResource(tenantId, (TbResourceId) id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getEntityType() {
|
||||
return EntityType.TB_RESOURCE;
|
||||
|
||||
@ -22,11 +22,12 @@ 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.Dao;
|
||||
import org.thingsboard.server.dao.ExportableEntityDao;
|
||||
import org.thingsboard.server.dao.TenantEntityWithDataDao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TbResourceDao extends Dao<TbResource>, TenantEntityWithDataDao {
|
||||
public interface TbResourceDao extends Dao<TbResource>, TenantEntityWithDataDao, ExportableEntityDao<TbResourceId, TbResource> {
|
||||
|
||||
TbResource findResourceByTenantIdAndKey(TenantId tenantId, ResourceType resourceType, String resourceId);
|
||||
|
||||
|
||||
@ -109,6 +109,27 @@ public class JpaTbResourceDao extends JpaAbstractDao<TbResourceEntity, TbResourc
|
||||
return resourceRepository.sumDataSizeByTenantId(tenantId.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TbResource findByTenantIdAndExternalId(UUID tenantId, UUID externalId) {
|
||||
return DaoUtil.getData(resourceRepository.findByTenantIdAndExternalId(tenantId, externalId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageData<TbResource> findByTenantId(UUID tenantId, PageLink pageLink) {
|
||||
return findAllByTenantId(TenantId.fromUUID(tenantId), pageLink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageData<TbResourceId> findIdsByTenantId(UUID tenantId, PageLink pageLink) {
|
||||
return DaoUtil.pageToPageData(resourceRepository.findIdsByTenantId(tenantId, DaoUtil.toPageable(pageLink))
|
||||
.map(TbResourceId::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TbResourceId getExternalIdByInternal(TbResourceId internalId) {
|
||||
return DaoUtil.toEntityId(resourceRepository.getExternalIdByInternal(internalId.getId()), TbResourceId::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getEntityType() {
|
||||
return EntityType.TB_RESOURCE;
|
||||
|
||||
@ -20,12 +20,13 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.thingsboard.server.dao.ExportableEntityRepository;
|
||||
import org.thingsboard.server.dao.model.sql.TbResourceEntity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface TbResourceRepository extends JpaRepository<TbResourceEntity, UUID> {
|
||||
public interface TbResourceRepository extends JpaRepository<TbResourceEntity, UUID> , ExportableEntityRepository<TbResourceEntity> {
|
||||
|
||||
TbResourceEntity findByTenantIdAndResourceTypeAndResourceKey(UUID tenantId, String resourceType, String resourceKey);
|
||||
|
||||
@ -87,4 +88,10 @@ public interface TbResourceRepository extends JpaRepository<TbResourceEntity, UU
|
||||
@Query(value = "SELECT COALESCE(preview, data) FROM resource WHERE id = :id", nativeQuery = true)
|
||||
byte[] getPreviewById(@Param("id") UUID id);
|
||||
|
||||
@Query("SELECT externalId FROM TbResourceInfoEntity WHERE id = :id")
|
||||
UUID getExternalIdByInternal(@Param("id") UUID internalId);
|
||||
|
||||
@Query("SELECT id FROM TbResourceInfoEntity WHERE tenantId = :tenantId")
|
||||
Page<UUID> findIdsByTenantId(@Param("tenantId") UUID tenantId, Pageable pageable);
|
||||
|
||||
}
|
||||
|
||||
@ -204,6 +204,12 @@ public class JpaWidgetTypeDao extends JpaAbstractDao<WidgetTypeDetailsEntity, Wi
|
||||
DaoUtil.toPageable(pageLink)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageData<WidgetTypeId> findIdsByTenantId(UUID tenantId, PageLink pageLink) {
|
||||
return DaoUtil.pageToPageData(widgetTypeRepository.findIdsByTenantId(tenantId, DaoUtil.toPageable(pageLink))
|
||||
.map(WidgetTypeId::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WidgetTypeId getExternalIdByInternal(WidgetTypeId internalId) {
|
||||
return Optional.ofNullable(widgetTypeRepository.getExternalIdById(internalId.getId()))
|
||||
|
||||
@ -76,7 +76,10 @@ public interface WidgetTypeRepository extends JpaRepository<WidgetTypeDetailsEnt
|
||||
@Query("SELECT externalId FROM WidgetTypeDetailsEntity WHERE id = :id")
|
||||
UUID getExternalIdById(@Param("id") UUID id);
|
||||
|
||||
@Query("SELECT id FROM WidgetTypeEntity")
|
||||
@Query("SELECT id FROM WidgetTypeDetailsEntity")
|
||||
Page<UUID> findAllIds(Pageable pageable);
|
||||
|
||||
@Query("SELECT id FROM WidgetTypeDetailsEntity WHERE tenantId = :tenantId")
|
||||
Page<UUID> findIdsByTenantId(@Param("tenantId") UUID tenantId, Pageable pageable);
|
||||
|
||||
}
|
||||
|
||||
@ -718,6 +718,7 @@ CREATE TABLE IF NOT EXISTS resource (
|
||||
etag varchar,
|
||||
descriptor varchar,
|
||||
preview bytea,
|
||||
external_id uuid,
|
||||
CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key)
|
||||
);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user