Images api: improvements

This commit is contained in:
ViacheslavKlimov 2023-11-17 13:36:33 +02:00
parent e6136148bb
commit 5cfdf7ad87
6 changed files with 34 additions and 35 deletions

View File

@ -30,14 +30,15 @@ import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo; import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.util.ImageUtils;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails; import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.dao.resource.ImageService; import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.dao.util.ImageUtils;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Base64; import java.util.Base64;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -58,10 +59,10 @@ public class ImagesUpdater {
@SneakyThrows @SneakyThrows
public void updateSystemImage(Path imageFile, Map<String, String> imageNames) { public void updateSystemImage(Path imageFile, Map<String, String> imageNames) {
String imageKey = imageFile.getFileName().toString(); String imageKey = imageFile.getParent().getFileName() + "." + imageFile.getFileName().toString(); // TODO: add subdir to image key
String imageName = imageNames.get(imageKey); String imageName = imageNames.get(imageKey);
if (imageName == null) { if (imageName == null) {
throw new IllegalArgumentException("Image name is missing for " + imageKey + ". Please add it to names.json file"); imageName = imageKey;
} }
byte[] imageData = Files.readAllBytes(imageFile); byte[] imageData = Files.readAllBytes(imageFile);
String mediaType = ImageUtils.fileExtensionToMediaType("image", StringUtils.substringAfterLast(imageKey, ".")); String mediaType = ImageUtils.fileExtensionToMediaType("image", StringUtils.substringAfterLast(imageKey, "."));
@ -203,17 +204,19 @@ public class ImagesUpdater {
String existingImageQuery) { String existingImageQuery) {
TbResourceInfo imageInfo = imageService.getImageInfoByTenantIdAndKey(tenantId, key); TbResourceInfo imageInfo = imageService.getImageInfoByTenantIdAndKey(tenantId, key);
if (imageInfo == null && !tenantId.isSysTenantId() && existingImageQuery != null) { if (imageInfo == null && !tenantId.isSysTenantId() && existingImageQuery != null) {
// TODO: need to search among tenant images too (custom widgets) List<TbResourceInfo> similarImages = imageService.findSimilarImagesByTenantIdAndKeyStartingWith(TenantId.SYS_TENANT_ID, imageData, existingImageQuery);
// List<TbResourceInfo> existingSystemImages = imageService.findByTenantIdAndDataAndKeyStartingWith(TenantId.SYS_TENANT_ID, imageData, existingImageQuery); if (similarImages.isEmpty()) {
// if (!existingSystemImages.isEmpty()) { similarImages = imageService.findSimilarImagesByTenantIdAndKeyStartingWith(tenantId, imageData, existingImageQuery);
// imageInfo = existingSystemImages.get(0); }
// if (existingSystemImages.size() > 1) { if (!similarImages.isEmpty()) {
// log.warn("Found more than one system image resources for key {}", existingImageQuery); imageInfo = similarImages.get(0);
// } if (similarImages.size() > 1) {
// String link = imageService.getImageLink(imageInfo); log.debug("Found more than one image resources for key {}: {}", existingImageQuery, similarImages);
// log.info("Using system image {} for {}", link, key); }
// return link; String link = imageInfo.getLink();
// } log.info("[{}] Using image {} for {}", tenantId, link, key);
return link;
}
} }
TbResource image; TbResource image;
if (imageInfo == null) { if (imageInfo == null) {
@ -224,7 +227,7 @@ public class ImagesUpdater {
} else if (tenantId.isSysTenantId()) { } else if (tenantId.isSysTenantId()) {
image = new TbResource(imageInfo); image = new TbResource(imageInfo);
} else { } else {
return imageService.getImageLink(imageInfo); return imageInfo.getLink();
} }
image.setTitle(name); image.setTitle(name);
image.setFileName(key); image.setFileName(key);
@ -235,7 +238,7 @@ public class ImagesUpdater {
TbResourceInfo savedImage = imageService.saveImage(image); TbResourceInfo savedImage = imageService.saveImage(image);
log.info("[{}] {} image '{}' ({})", tenantId, imageInfo == null ? "Created" : "Updated", log.info("[{}] {} image '{}' ({})", tenantId, imageInfo == null ? "Created" : "Updated",
image.getTitle(), image.getResourceKey()); image.getTitle(), image.getResourceKey());
return imageService.getImageLink(savedImage); return savedImage.getLink();
} }
private String getText(JsonNode jsonNode, String field) { private String getText(JsonNode jsonNode, String field) {

View File

@ -22,6 +22,8 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import java.util.List;
public interface ImageService { public interface ImageService {
TbResourceInfo saveImage(TbResource image) throws Exception; TbResourceInfo saveImage(TbResource image) throws Exception;
@ -40,6 +42,6 @@ public interface ImageService {
void deleteImage(TenantId tenantId, TbResourceId imageId); void deleteImage(TenantId tenantId, TbResourceId imageId);
String getImageLink(TbResourceInfo imageInfo); List<TbResourceInfo> findSimilarImagesByTenantIdAndKeyStartingWith(TenantId tenantId, byte[] data, String imageKeyStartingWith);
} }

View File

@ -60,6 +60,4 @@ public interface ResourceService extends EntityDaoService {
long sumDataSizeByTenantId(TenantId tenantId); long sumDataSizeByTenantId(TenantId tenantId);
List<TbResourceInfo> findByTenantIdAndDataAndKeyStartingWith(TenantId tenantId, byte[] data, String query);
} }

View File

@ -106,6 +106,14 @@ public class TbResourceInfo extends BaseData<TbResourceId> implements HasName, H
return title; return title;
} }
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public String getLink() {
if (resourceType == ResourceType.IMAGE) {
return "/api/images/" + (tenantId.isSysTenantId() ? "system" : "tenant") + "/" + resourceKey;
}
return null;
}
@JsonIgnore @JsonIgnore
public String getSearchText() { public String getSearchText() {
return searchText != null ? searchText : title; return searchText != null ? searchText : title;

View File

@ -20,7 +20,6 @@ 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.springframework.transaction.annotation.Transactional;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.RegexUtils; 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;
@ -35,6 +34,7 @@ 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.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -152,15 +152,9 @@ public class BaseImageService extends BaseResourceService implements ImageServic
} }
@Override @Override
public String getImageLink(TbResourceInfo imageInfo) { public List<TbResourceInfo> findSimilarImagesByTenantIdAndKeyStartingWith(TenantId tenantId, byte[] data, String imageKeyStartingWith) {
String link = "/api/images/"; String etag = calculateEtag(data);
if (imageInfo.getTenantId().isSysTenantId()) { return resourceInfoDao.findByTenantIdAndEtagAndKeyStartingWith(tenantId, etag, imageKeyStartingWith);
link += "system/";
} else {
link += "tenant/";
}
link += imageInfo.getResourceKey();
return link;
} }
} }

View File

@ -216,12 +216,6 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
return resourceDao.sumDataSizeByTenantId(tenantId); return resourceDao.sumDataSizeByTenantId(tenantId);
} }
@Override
public List<TbResourceInfo> findByTenantIdAndDataAndKeyStartingWith(TenantId tenantId, byte[] data, String query) {
String etag = calculateEtag(data);
return resourceInfoDao.findByTenantIdAndEtagAndKeyStartingWith(tenantId, etag, query);
}
protected String calculateEtag(byte[] data) { protected String calculateEtag(byte[] data) {
return Hashing.sha256().hashBytes(data).toString(); return Hashing.sha256().hashBytes(data).toString();
} }