Unique image resource key based on index
This commit is contained in:
parent
2b9eab0150
commit
e7aabe80a4
@ -125,7 +125,8 @@ public class ImageController extends BaseController {
|
|||||||
TenantId tenantId = getTenantId();
|
TenantId tenantId = getTenantId();
|
||||||
TbResourceInfo imageInfo = checkImageInfo(type, key, Operation.READ);
|
TbResourceInfo imageInfo = checkImageInfo(type, key, Operation.READ);
|
||||||
ImageDescriptor descriptor = imageInfo.getDescriptor(ImageDescriptor.class);
|
ImageDescriptor descriptor = imageInfo.getDescriptor(ImageDescriptor.class);
|
||||||
return downloadIfChanged(etag, imageInfo, descriptor, () -> imageService.getImageData(tenantId, imageInfo.getId()));
|
return downloadIfChanged(etag, descriptor, imageInfo.getFileName(),
|
||||||
|
() -> imageService.getImageData(tenantId, imageInfo.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
|
||||||
@ -136,7 +137,8 @@ public class ImageController extends BaseController {
|
|||||||
TenantId tenantId = getTenantId();
|
TenantId tenantId = getTenantId();
|
||||||
TbResourceInfo imageInfo = checkImageInfo(type, key, Operation.READ);
|
TbResourceInfo imageInfo = checkImageInfo(type, key, Operation.READ);
|
||||||
ImageDescriptor descriptor = imageInfo.getDescriptor(ImageDescriptor.class);
|
ImageDescriptor descriptor = imageInfo.getDescriptor(ImageDescriptor.class);
|
||||||
return downloadIfChanged(etag, imageInfo, descriptor.getPreviewDescriptor(), () -> imageService.getImagePreview(tenantId, imageInfo.getId()));
|
return downloadIfChanged(etag, descriptor.getPreviewDescriptor(), imageInfo.getFileName(),
|
||||||
|
() -> imageService.getImagePreview(tenantId, imageInfo.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
||||||
@ -176,24 +178,22 @@ public class ImageController extends BaseController {
|
|||||||
tbImageService.delete(imageInfo, getCurrentUser());
|
tbImageService.delete(imageInfo, getCurrentUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<ByteArrayResource> downloadIfChanged(String etag, TbResourceInfo imageInfo, ImageDescriptor imageDescriptor,
|
private ResponseEntity<ByteArrayResource> downloadIfChanged(String actualEtag, ImageDescriptor imageDescriptor,
|
||||||
Supplier<byte[]> dataSupplier) {
|
String fileName, Supplier<byte[]> dataSupplier) {
|
||||||
if (etag != null) {
|
if (imageDescriptor.getEtag().equals(actualEtag)) {
|
||||||
if (etag.equals(imageInfo.getEtag())) {
|
return ResponseEntity.status(HttpStatus.NOT_MODIFIED)
|
||||||
return ResponseEntity.status(HttpStatus.NOT_MODIFIED)
|
.eTag(actualEtag)
|
||||||
.eTag(etag)
|
.build();
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] data = dataSupplier.get();
|
byte[] data = dataSupplier.get();
|
||||||
return ResponseEntity.ok()
|
return ResponseEntity.ok()
|
||||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + imageInfo.getFileName())
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName)
|
||||||
.header("x-filename", imageInfo.getFileName())
|
.header("x-filename", fileName)
|
||||||
.contentLength(data.length)
|
.contentLength(data.length)
|
||||||
.header("Content-Type", imageDescriptor.getMediaType())
|
.header("Content-Type", imageDescriptor.getMediaType())
|
||||||
.cacheControl(CacheControl.noCache())
|
.cacheControl(CacheControl.noCache())
|
||||||
.eTag(imageInfo.getEtag())
|
.eTag(imageDescriptor.getEtag())
|
||||||
.body(new ByteArrayResource(data));
|
.body(new ByteArrayResource(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,6 @@ public class DefaultTbImageService extends AbstractTbEntityService implements Tb
|
|||||||
public TbResourceInfo save(TbResource image, User user) throws Exception {
|
public TbResourceInfo save(TbResource image, User user) throws Exception {
|
||||||
ActionType actionType = image.getId() == null ? ActionType.ADDED : ActionType.UPDATED;
|
ActionType actionType = image.getId() == null ? ActionType.ADDED : ActionType.UPDATED;
|
||||||
TenantId tenantId = image.getTenantId();
|
TenantId tenantId = image.getTenantId();
|
||||||
image.setResourceKey(image.getFileName()); // TODO: generate unique resource key file_name+idx
|
|
||||||
try {
|
try {
|
||||||
TbResourceInfo savedImage = imageService.saveImage(image);
|
TbResourceInfo savedImage = imageService.saveImage(image);
|
||||||
notificationEntityService.logEntityAction(tenantId, savedImage.getId(), savedImage, actionType, user);
|
notificationEntityService.logEntityAction(tenantId, savedImage.getId(), savedImage, actionType, user);
|
||||||
|
|||||||
@ -25,5 +25,6 @@ public class ImageDescriptor {
|
|||||||
private int width;
|
private int width;
|
||||||
private int height;
|
private int height;
|
||||||
private long size;
|
private long size;
|
||||||
|
private String etag;
|
||||||
private ImageDescriptor previewDescriptor;
|
private ImageDescriptor previewDescriptor;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import lombok.AccessLevel;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.util.function.UnaryOperator;
|
import java.util.function.UnaryOperator;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
@ -37,4 +38,14 @@ public class RegexUtils {
|
|||||||
return pattern.matcher(input).matches();
|
return pattern.matcher(input).matches();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getMatch(String input, Pattern pattern, int group) {
|
||||||
|
Matcher matcher = pattern.matcher(input);
|
||||||
|
if (matcher.find()) {
|
||||||
|
try {
|
||||||
|
return matcher.group(group);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,9 +16,12 @@
|
|||||||
package org.thingsboard.server.dao.resource;
|
package org.thingsboard.server.dao.resource;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.thingsboard.common.util.JacksonUtil;
|
import org.thingsboard.common.util.JacksonUtil;
|
||||||
|
import org.thingsboard.common.util.RegexUtils;
|
||||||
import org.thingsboard.server.common.data.ImageDescriptor;
|
import org.thingsboard.server.common.data.ImageDescriptor;
|
||||||
import org.thingsboard.server.common.data.ResourceType;
|
import org.thingsboard.server.common.data.ResourceType;
|
||||||
import org.thingsboard.server.common.data.TbResource;
|
import org.thingsboard.server.common.data.TbResource;
|
||||||
@ -32,7 +35,9 @@ import org.thingsboard.server.dao.service.validator.ResourceDataValidator;
|
|||||||
import org.thingsboard.server.dao.util.ImageUtils;
|
import org.thingsboard.server.dao.util.ImageUtils;
|
||||||
import org.thingsboard.server.dao.util.ImageUtils.ProcessedImage;
|
import org.thingsboard.server.dao.util.ImageUtils.ProcessedImage;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -42,17 +47,22 @@ public class BaseImageService extends BaseResourceService implements ImageServic
|
|||||||
super(resourceDao, resourceInfoDao, resourceValidator);
|
super(resourceDao, resourceInfoDao, resourceValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public TbResourceInfo saveImage(TbResource image) throws Exception {
|
public TbResourceInfo saveImage(TbResource image) throws Exception {
|
||||||
|
if (image.getId() == null) {
|
||||||
|
image.setResourceKey(getUniqueKey(image.getTenantId(), image.getFileName()));
|
||||||
|
}
|
||||||
resourceValidator.validate(image, TbResourceInfo::getTenantId);
|
resourceValidator.validate(image, TbResourceInfo::getTenantId);
|
||||||
|
|
||||||
ImageDescriptor descriptor = image.getDescriptor(ImageDescriptor.class);
|
ImageDescriptor descriptor = image.getDescriptor(ImageDescriptor.class);
|
||||||
Pair<ImageDescriptor, byte[]> result = processImage(image.getData(), descriptor);
|
Pair<ImageDescriptor, byte[]> result = processImage(image.getData(), descriptor);
|
||||||
image.setDescriptor(JacksonUtil.valueToTree(result.getLeft()));
|
descriptor = result.getLeft();
|
||||||
|
image.setEtag(descriptor.getEtag());
|
||||||
|
image.setDescriptor(JacksonUtil.valueToTree(descriptor));
|
||||||
image.setPreview(result.getRight());
|
image.setPreview(result.getRight());
|
||||||
|
|
||||||
image = saveResource(image, false);
|
return new TbResourceInfo(doSaveResource(image));
|
||||||
return new TbResourceInfo(image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pair<ImageDescriptor, byte[]> processImage(byte[] data, ImageDescriptor descriptor) throws Exception {
|
private Pair<ImageDescriptor, byte[]> processImage(byte[] data, ImageDescriptor descriptor) throws Exception {
|
||||||
@ -62,17 +72,42 @@ public class BaseImageService extends BaseResourceService implements ImageServic
|
|||||||
descriptor.setWidth(image.getWidth());
|
descriptor.setWidth(image.getWidth());
|
||||||
descriptor.setHeight(image.getHeight());
|
descriptor.setHeight(image.getHeight());
|
||||||
descriptor.setSize(image.getSize());
|
descriptor.setSize(image.getSize());
|
||||||
|
descriptor.setEtag(calculateEtag(data));
|
||||||
|
|
||||||
ImageDescriptor previewDescriptor = new ImageDescriptor();
|
ImageDescriptor previewDescriptor = new ImageDescriptor();
|
||||||
previewDescriptor.setWidth(preview.getWidth());
|
previewDescriptor.setWidth(preview.getWidth());
|
||||||
previewDescriptor.setHeight(preview.getHeight());
|
previewDescriptor.setHeight(preview.getHeight());
|
||||||
previewDescriptor.setMediaType(preview.getMediaType());
|
previewDescriptor.setMediaType(preview.getMediaType());
|
||||||
previewDescriptor.setSize(preview.getSize());
|
previewDescriptor.setSize(preview.getSize());
|
||||||
|
previewDescriptor.setEtag(preview.getData() != null ? calculateEtag(preview.getData()) : descriptor.getEtag());
|
||||||
descriptor.setPreviewDescriptor(previewDescriptor);
|
descriptor.setPreviewDescriptor(previewDescriptor);
|
||||||
|
|
||||||
return Pair.of(descriptor, preview.getData());
|
return Pair.of(descriptor, preview.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getUniqueKey(TenantId tenantId, String filename) {
|
||||||
|
if (!resourceInfoDao.existsByTenantIdAndResourceTypeAndResourceKey(tenantId, ResourceType.IMAGE, filename)) {
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
String basename = StringUtils.substringBeforeLast(filename, ".");
|
||||||
|
String extension = StringUtils.substringAfterLast(filename, ".");
|
||||||
|
|
||||||
|
Pattern similarImagesPattern = Pattern.compile(
|
||||||
|
Pattern.quote(basename) + "_(\\d+)\\.?" + Pattern.quote(extension)
|
||||||
|
);
|
||||||
|
int maxImageIdx = resourceInfoDao.findKeysByTenantIdAndResourceTypeAndResourceKeyStartingWith(
|
||||||
|
tenantId, ResourceType.IMAGE, basename + "_").stream()
|
||||||
|
.map(key -> RegexUtils.getMatch(key, similarImagesPattern, 1))
|
||||||
|
.filter(Objects::nonNull).mapToInt(Integer::parseInt)
|
||||||
|
.max().orElse(0);
|
||||||
|
String uniqueKey = basename + "_" + (maxImageIdx + 1);
|
||||||
|
if (!extension.isEmpty()) {
|
||||||
|
uniqueKey += "." + extension;
|
||||||
|
}
|
||||||
|
return uniqueKey;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TbResourceInfo saveImageInfo(TbResourceInfo imageInfo) {
|
public TbResourceInfo saveImageInfo(TbResourceInfo imageInfo) {
|
||||||
return saveResource(new TbResource(imageInfo));
|
return saveResource(new TbResource(imageInfo));
|
||||||
|
|||||||
@ -67,11 +67,19 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
|
|||||||
if (doValidate) {
|
if (doValidate) {
|
||||||
resourceValidator.validate(resource, TbResourceInfo::getTenantId);
|
resourceValidator.validate(resource, TbResourceInfo::getTenantId);
|
||||||
}
|
}
|
||||||
TenantId tenantId = resource.getTenantId();
|
|
||||||
TbResourceId resourceId = resource.getId();
|
|
||||||
if (resource.getData() != null) {
|
if (resource.getData() != null) {
|
||||||
resource.setEtag(calculateEtag(resource.getData()));
|
resource.setEtag(calculateEtag(resource.getData()));
|
||||||
}
|
}
|
||||||
|
return doSaveResource(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TbResource saveResource(TbResource resource) {
|
||||||
|
return saveResource(resource, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TbResource doSaveResource(TbResource resource) {
|
||||||
|
TenantId tenantId = resource.getTenantId();
|
||||||
try {
|
try {
|
||||||
TbResource saved;
|
TbResource saved;
|
||||||
if (resource.getData() != null) {
|
if (resource.getData() != null) {
|
||||||
@ -80,12 +88,12 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
|
|||||||
TbResourceInfo resourceInfo = saveResourceInfo(resource);
|
TbResourceInfo resourceInfo = saveResourceInfo(resource);
|
||||||
saved = new TbResource(resourceInfo);
|
saved = new TbResource(resourceInfo);
|
||||||
}
|
}
|
||||||
publishEvictEvent(new ResourceInfoEvictEvent(tenantId, resourceId));
|
publishEvictEvent(new ResourceInfoEvictEvent(tenantId, resource.getId()));
|
||||||
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(saved.getTenantId())
|
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(saved.getTenantId())
|
||||||
.entityId(saved.getId()).added(resourceId == null).build());
|
.entityId(saved.getId()).added(resource.getId() == null).build());
|
||||||
return saved;
|
return saved;
|
||||||
} catch (Exception t) {
|
} catch (Exception t) {
|
||||||
publishEvictEvent(new ResourceInfoEvictEvent(tenantId, resourceId));
|
publishEvictEvent(new ResourceInfoEvictEvent(tenantId, resource.getId()));
|
||||||
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null);
|
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null);
|
||||||
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("resource_unq_key")) {
|
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("resource_unq_key")) {
|
||||||
String field = ResourceType.LWM2M_MODEL.equals(resource.getResourceType()) ? "resourceKey" : "fileName";
|
String field = ResourceType.LWM2M_MODEL.equals(resource.getResourceType()) ? "resourceKey" : "fileName";
|
||||||
@ -96,11 +104,6 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TbResource saveResource(TbResource resource) {
|
|
||||||
return saveResource(resource, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private TbResourceInfo saveResourceInfo(TbResource resource) {
|
private TbResourceInfo saveResourceInfo(TbResource resource) {
|
||||||
return resourceInfoDao.save(resource.getTenantId(), new TbResourceInfo(resource));
|
return resourceInfoDao.save(resource.getTenantId(), new TbResourceInfo(resource));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,10 @@ public interface TbResourceInfoDao extends Dao<TbResourceInfo> {
|
|||||||
|
|
||||||
TbResourceInfo findByTenantIdAndKey(TenantId tenantId, ResourceType resourceType, String resourceKey);
|
TbResourceInfo findByTenantIdAndKey(TenantId tenantId, ResourceType resourceType, String resourceKey);
|
||||||
|
|
||||||
|
boolean existsByTenantIdAndResourceTypeAndResourceKey(TenantId tenantId, ResourceType resourceType, String resourceKey);
|
||||||
|
|
||||||
|
List<String> findKeysByTenantIdAndResourceTypeAndResourceKeyStartingWith(TenantId tenantId, ResourceType resourceType, String resourceKeyQuery);
|
||||||
|
|
||||||
List<TbResourceInfo> findByTenantIdAndEtagAndKeyStartingWith(TenantId tenantId, String etag, String query);
|
List<TbResourceInfo> findByTenantIdAndEtagAndKeyStartingWith(TenantId tenantId, String etag, String query);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,10 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.dao.service.validator;
|
package org.thingsboard.server.dao.service.validator;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.thingsboard.server.common.data.StringUtils;
|
|
||||||
import org.thingsboard.server.common.data.TbResource;
|
import org.thingsboard.server.common.data.TbResource;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
@ -95,6 +95,9 @@ public class ResourceDataValidator extends DataValidator<TbResource> {
|
|||||||
if (StringUtils.isEmpty(resource.getFileName())) {
|
if (StringUtils.isEmpty(resource.getFileName())) {
|
||||||
throw new DataValidationException("Resource file name should be specified!");
|
throw new DataValidationException("Resource file name should be specified!");
|
||||||
}
|
}
|
||||||
|
if (StringUtils.containsAny(resource.getFileName(), "/", "\\")) {
|
||||||
|
throw new DataValidationException("File name contains forbidden symbols");
|
||||||
|
}
|
||||||
if (StringUtils.isEmpty(resource.getResourceKey())) {
|
if (StringUtils.isEmpty(resource.getResourceKey())) {
|
||||||
throw new DataValidationException("Resource key should be specified!");
|
throw new DataValidationException("Resource key should be specified!");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,6 +82,16 @@ public class JpaTbResourceInfoDao extends JpaAbstractDao<TbResourceInfoEntity, T
|
|||||||
return DaoUtil.getData(resourceInfoRepository.findByTenantIdAndResourceTypeAndResourceKey(tenantId.getId(), resourceType.name(), resourceKey));
|
return DaoUtil.getData(resourceInfoRepository.findByTenantIdAndResourceTypeAndResourceKey(tenantId.getId(), resourceType.name(), resourceKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean existsByTenantIdAndResourceTypeAndResourceKey(TenantId tenantId, ResourceType resourceType, String resourceKey) {
|
||||||
|
return resourceInfoRepository.existsByTenantIdAndResourceTypeAndResourceKey(tenantId.getId(), resourceType.name(), resourceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> findKeysByTenantIdAndResourceTypeAndResourceKeyStartingWith(TenantId tenantId, ResourceType resourceType, String resourceKeyQuery) {
|
||||||
|
return resourceInfoRepository.findKeysByTenantIdAndResourceTypeAndResourceKeyStartingWith(tenantId.getId(), resourceType.name(), resourceKeyQuery);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TbResourceInfo> findByTenantIdAndEtagAndKeyStartingWith(TenantId tenantId, String etag, String query) {
|
public List<TbResourceInfo> findByTenantIdAndEtagAndKeyStartingWith(TenantId tenantId, String etag, String query) {
|
||||||
return DaoUtil.convertDataList(resourceInfoRepository.findByTenantIdAndHashCodeAndResourceKeyStartingWith(tenantId.getId(), etag, query));
|
return DaoUtil.convertDataList(resourceInfoRepository.findByTenantIdAndHashCodeAndResourceKeyStartingWith(tenantId.getId(), etag, query));
|
||||||
|
|||||||
@ -22,7 +22,6 @@ import org.springframework.data.jpa.repository.Query;
|
|||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
import org.thingsboard.server.dao.model.sql.TbResourceInfoEntity;
|
import org.thingsboard.server.dao.model.sql.TbResourceInfoEntity;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -55,6 +54,14 @@ public interface TbResourceInfoRepository extends JpaRepository<TbResourceInfoEn
|
|||||||
|
|
||||||
TbResourceInfoEntity findByTenantIdAndResourceTypeAndResourceKey(UUID tenantId, String resourceType, String resourceKey);
|
TbResourceInfoEntity findByTenantIdAndResourceTypeAndResourceKey(UUID tenantId, String resourceType, String resourceKey);
|
||||||
|
|
||||||
|
boolean existsByTenantIdAndResourceTypeAndResourceKey(UUID tenantId, String resourceType, String resourceKey);
|
||||||
|
|
||||||
|
@Query(value = "SELECT r.resource_key FROM resource r WHERE r.tenant_id = :tenantId AND r.resource_type = :resourceType " +
|
||||||
|
"AND starts_with(r.resource_key, :resourceKeyStartsWith)", nativeQuery = true)
|
||||||
|
List<String> findKeysByTenantIdAndResourceTypeAndResourceKeyStartingWith(@Param("tenantId") UUID tenantId,
|
||||||
|
@Param("resourceType") String resourceType,
|
||||||
|
@Param("resourceKeyStartsWith") String resourceKeyStartsWith);
|
||||||
|
|
||||||
List<TbResourceInfoEntity> findByTenantIdAndHashCodeAndResourceKeyStartingWith(UUID tenantId, String hashCode, String query);
|
List<TbResourceInfoEntity> findByTenantIdAndHashCodeAndResourceKeyStartingWith(UUID tenantId, String hashCode, String query);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user