From e46828ba96da5b1f721abc7a5085853ff949a31f Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Wed, 17 Jan 2024 13:50:20 +0200 Subject: [PATCH] Add image API to RestClient --- .../thingsboard/rest/client/RestClient.java | 124 ++++++++++++++++-- 1 file changed, 114 insertions(+), 10 deletions(-) diff --git a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java index d19726e2f1..f3a7ee77c7 100644 --- a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java +++ b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java @@ -18,6 +18,8 @@ package org.thingsboard.rest.client; import com.auth0.jwt.JWT; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.base.Strings; +import org.apache.commons.io.IOUtils; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.Resource; @@ -53,11 +55,13 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityViewInfo; import org.thingsboard.server.common.data.EventInfo; +import org.thingsboard.server.common.data.ImageExportData; import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.SystemInfo; +import org.thingsboard.server.common.data.TbImageDeleteResult; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; import org.thingsboard.server.common.data.Tenant; @@ -168,6 +172,7 @@ import org.thingsboard.server.common.data.widget.WidgetTypeInfo; import org.thingsboard.server.common.data.widget.WidgetsBundle; import java.io.Closeable; +import java.io.IOException; import java.net.URI; import java.util.Collections; import java.util.HashMap; @@ -3591,6 +3596,97 @@ public class RestClient implements Closeable { restTemplate.delete("/api/resource/{resourceId}", resourceId.getId().toString()); } + public TbResourceInfo getImageInfo(String type, String key) { + return restTemplate.getForObject(baseURL + "/api/images/{type}/{key}/info", TbResourceInfo.class, Map.of( + "type", type, + "key", key + )); + } + + public PageData getImages(PageLink pageLink, boolean includeSystemImages) { + Map params = new HashMap<>(); + addPageLinkToParam(params, pageLink); + params.put("includeSystemImages", String.valueOf(includeSystemImages)); + return restTemplate.exchange(baseURL + "/api/images?includeSystemImages={includeSystemImages}&" + getUrlParams(pageLink), + HttpMethod.GET, + HttpEntity.EMPTY, + new ParameterizedTypeReference>() {}, + params + ).getBody(); + } + + public TbResourceInfo uploadImage(String fileName, byte[] data, String contentType, String title) { + HttpEntity> request = createMultipartRequest(fileName, data, contentType, Map.of( + "title", Strings.nullToEmpty(title) + )); + return restTemplate.postForObject(baseURL + "/api/image", request, TbResourceInfo.class); + } + + public TbResourceInfo updateImage(String type, String key, String fileName, byte[] data, String contentType) { + HttpEntity> request = createMultipartRequest(fileName, data, contentType, Map.of()); + return restTemplate.exchange(baseURL + "/api/images/{type}/{key}", HttpMethod.PUT, request, TbResourceInfo.class, Map.of( + "type", type, + "key", key + )).getBody(); + } + + public TbResourceInfo updateImageInfo(String type, String key, TbResourceInfo request) { + return restTemplate.exchange(baseURL + "/api/images/{type}/{key}/info", HttpMethod.PUT, new HttpEntity<>(request), TbResourceInfo.class, Map.of( + "type", type, + "key", key + )).getBody(); + } + + public void updateImagePublicStatus(String type, String key, boolean isPublic) { + restTemplate.put(baseURL + "/api/images/{type}/{key}/public/{isPublic}", null, Map.of( + "type", type, + "key", key, + "isPublic", isPublic + )); + } + + public byte[] downloadImage(String type, String key) throws IOException { + Resource image = restTemplate.exchange(baseURL + "/api/images/{type}/{key}", HttpMethod.GET, null, Resource.class, Map.of( + "type", type, + "key", key + )).getBody(); + return IOUtils.toByteArray(image.getInputStream()); + } + + public byte[] downloadImagePreview(String type, String key) throws IOException { + Resource image = restTemplate.exchange(baseURL + "/api/images/{type}/{key}/preview", HttpMethod.GET, null, Resource.class, Map.of( + "type", type, + "key", key + )).getBody(); + return IOUtils.toByteArray(image.getInputStream()); + } + + public byte[] downloadPublicImage(String publicResourceKey) throws IOException { + Resource image = restTemplate.exchange(baseURL + "/api/images/public/{publicResourceKey}", HttpMethod.GET, null, Resource.class, Map.of( + "publicResourceKey", publicResourceKey + )).getBody(); + return IOUtils.toByteArray(image.getInputStream()); + } + + public ImageExportData exportImage(String type, String key) { + return restTemplate.getForObject(baseURL + "/api/images/{type}/{key}/export", ImageExportData.class, Map.of( + "type", type, + "key", key + )); + } + + public TbResourceInfo importImage(ImageExportData exportData) { + return restTemplate.exchange(baseURL + "/api/image/import", HttpMethod.PUT, new HttpEntity<>(exportData), TbResourceInfo.class).getBody(); + } + + public TbImageDeleteResult deleteImage(String type, String key, boolean force) { + return restTemplate.exchange(baseURL + "/api/images/{type}/{key}?force={force}", HttpMethod.DELETE, null, TbImageDeleteResult.class, Map.of( + "type", type, + "key", key, + "force", force + )).getBody(); + } + public ResponseEntity downloadOtaPackage(OtaPackageId otaPackageId) { Map params = new HashMap<>(); params.put("otaPackageId", otaPackageId.getId().toString()); @@ -3640,16 +3736,7 @@ public class RestClient implements Closeable { } public OtaPackageInfo saveOtaPackageData(OtaPackageId otaPackageId, String checkSum, ChecksumAlgorithm checksumAlgorithm, String fileName, byte[] fileBytes) throws Exception { - HttpHeaders header = new HttpHeaders(); - header.setContentType(MediaType.MULTIPART_FORM_DATA); - - MultiValueMap fileMap = new LinkedMultiValueMap<>(); - fileMap.add(HttpHeaders.CONTENT_DISPOSITION, "form-data; name=file; filename=" + fileName); - HttpEntity fileEntity = new HttpEntity<>(new ByteArrayResource(fileBytes), fileMap); - - MultiValueMap body = new LinkedMultiValueMap<>(); - body.add("file", fileEntity); - HttpEntity> requestEntity = new HttpEntity<>(body, header); + HttpEntity> requestEntity = createMultipartRequest(fileName, fileBytes, null, Collections.emptyMap()); Map params = new HashMap<>(); params.put("otaPackageId", otaPackageId.getId().toString()); @@ -3854,6 +3941,23 @@ public class RestClient implements Closeable { return listToString(list.stream().map(Enum::name).collect(Collectors.toList())); } + private HttpEntity> createMultipartRequest(String fileName, byte[] fileData, String fileContentType, Map otherParts) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + + MultiValueMap fileMap = new LinkedMultiValueMap<>(); + fileMap.add(HttpHeaders.CONTENT_DISPOSITION, "form-data; name=file; filename=" + fileName); + if (fileContentType != null) { + fileMap.add(HttpHeaders.CONTENT_TYPE, fileContentType); + } + HttpEntity fileEntity = new HttpEntity<>(new ByteArrayResource(fileData), fileMap); + + MultiValueMap body = new LinkedMultiValueMap<>(); + body.setAll(otherParts); + body.add("file", fileEntity); + return new HttpEntity<>(body, headers); + } + @Override public void close() { service.shutdown();