diff --git a/commons-asset-core/pom.xml b/commons-asset-core/pom.xml
index e08416c..2076aed 100755
--- a/commons-asset-core/pom.xml
+++ b/commons-asset-core/pom.xml
@@ -88,6 +88,12 @@ SOFTWARE.
${thumbnailator.version}
+
+ com.squareup
+ pollexor
+ ${pollexor.version}
+
+
org.springframework.boot
diff --git a/commons-asset-core/src/main/java/io/rocketbase/commons/config/AssetConfiguration.java b/commons-asset-core/src/main/java/io/rocketbase/commons/config/AssetConfiguration.java
index 2c724bd..1cd1a86 100644
--- a/commons-asset-core/src/main/java/io/rocketbase/commons/config/AssetConfiguration.java
+++ b/commons-asset-core/src/main/java/io/rocketbase/commons/config/AssetConfiguration.java
@@ -2,6 +2,8 @@
import io.rocketbase.commons.service.FileStorageService;
import io.rocketbase.commons.service.MongoFileStorageService;
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -9,9 +11,22 @@
import javax.annotation.Resource;
+@Data
@Configuration
public class AssetConfiguration {
+ @Value("${asset.api.endpoint:/api/asset}")
+ private String apiEndpoint;
+
+ @Value("${asset.api.render:/get/asset}")
+ private String renderEndpoint;
+
+ @Value(value = "${asset.thumbor.host:http://localhost}")
+ private String thumborHost;
+
+ @Value(value = "${asset.thumbor.key:}")
+ private String thumborKey;
+
@Resource
private GridFsTemplate gridFsTemplate;
diff --git a/commons-asset-core/src/main/java/io/rocketbase/commons/controller/AssetController.java b/commons-asset-core/src/main/java/io/rocketbase/commons/controller/AssetController.java
index 0bb53ce..14c14cd 100644
--- a/commons-asset-core/src/main/java/io/rocketbase/commons/controller/AssetController.java
+++ b/commons-asset-core/src/main/java/io/rocketbase/commons/controller/AssetController.java
@@ -29,6 +29,7 @@
import javax.annotation.Resource;
import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
@@ -39,7 +40,7 @@
import java.util.concurrent.TimeUnit;
@RestController
-@RequestMapping("/api/asset")
+@RequestMapping("${asset.api.endpoint:/api/asset}")
@Slf4j
public class AssetController implements BaseController {
@@ -58,7 +59,8 @@ public class AssetController implements BaseController {
@RequestMapping(method = RequestMethod.POST)
public AssetRead handleFileUpload(@RequestParam("file") MultipartFile file,
- @RequestParam(value = "systemRefId", required = false) String systemRefId) {
+ @RequestParam(value = "systemRefId", required = false) String systemRefId,
+ HttpServletRequest request) {
if (file.isEmpty()) {
throw new EmptyFileException();
}
@@ -91,7 +93,7 @@ public AssetRead handleFileUpload(@RequestParam("file") MultipartFile file,
AssetEntity asset = saveAndUploadAsset(assetType, tempFile, originalFilename, null, size, systemRefId);
log.debug("uploaded file {} with id: {}, took: {} ms", originalFilename, asset.getId(), stopwatch.elapsed(TimeUnit.MILLISECONDS));
- return assetConverter.fromEntity(asset, getPreviewSizes(null));
+ return assetConverter.fromEntity(asset, getPreviewSizes(null), request);
} finally {
tempFile.delete();
}
@@ -102,14 +104,14 @@ public AssetRead handleFileUpload(@RequestParam("file") MultipartFile file,
}
@RequestMapping(method = RequestMethod.GET)
- public PageableResult findAll(@RequestParam(required = false) MultiValueMap params) {
+ public PageableResult findAll(@RequestParam(required = false) MultiValueMap params, HttpServletRequest request) {
Page pageResult = assetRepository.findAll(parsePageRequest(params));
- return PageableResult.contentPage(assetConverter.fromEntities(pageResult.getContent(), getPreviewSizes(params)), pageResult);
+ return PageableResult.contentPage(assetConverter.fromEntities(pageResult.getContent(), getPreviewSizes(params), request), pageResult);
}
@RequestMapping(value = "/{sid}", method = RequestMethod.GET)
- public AssetRead getAsset(@PathVariable("sid") String sid, @RequestParam(required = false) MultiValueMap params) {
- return assetConverter.fromEntity(assetRepository.getByIdOrSystemRefId(sid), getPreviewSizes(params));
+ public AssetRead getAsset(@PathVariable("sid") String sid, @RequestParam(required = false) MultiValueMap params, HttpServletRequest request) {
+ return assetConverter.fromEntity(assetRepository.getByIdOrSystemRefId(sid), getPreviewSizes(params), request);
}
/**
diff --git a/commons-asset-core/src/main/java/io/rocketbase/commons/controller/AssetRenderController.java b/commons-asset-core/src/main/java/io/rocketbase/commons/controller/AssetRenderController.java
index e69fbb9..36150af 100644
--- a/commons-asset-core/src/main/java/io/rocketbase/commons/controller/AssetRenderController.java
+++ b/commons-asset-core/src/main/java/io/rocketbase/commons/controller/AssetRenderController.java
@@ -20,7 +20,7 @@
import java.util.concurrent.TimeUnit;
@RestController
-@RequestMapping("/get/asset")
+@RequestMapping("${asset.api.render:/get/asset}")
@Slf4j
public class AssetRenderController implements BaseController {
diff --git a/commons-asset-core/src/main/java/io/rocketbase/commons/converter/AssetConverter.java b/commons-asset-core/src/main/java/io/rocketbase/commons/converter/AssetConverter.java
index 941fe41..1cc539e 100644
--- a/commons-asset-core/src/main/java/io/rocketbase/commons/converter/AssetConverter.java
+++ b/commons-asset-core/src/main/java/io/rocketbase/commons/converter/AssetConverter.java
@@ -1,21 +1,56 @@
package io.rocketbase.commons.converter;
+import com.squareup.pollexor.Thumbor;
+import io.rocketbase.commons.config.AssetConfiguration;
import io.rocketbase.commons.dto.asset.AssetMeta;
+import io.rocketbase.commons.dto.asset.AssetPreviews;
import io.rocketbase.commons.dto.asset.AssetRead;
import io.rocketbase.commons.dto.asset.PreviewSize;
import io.rocketbase.commons.model.AssetEntity;
+import io.rocketbase.commons.service.FileStorageService;
+import io.rocketbase.commons.service.MongoFileStorageService;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class AssetConverter {
- public AssetRead fromEntity(AssetEntity entity, List sizes) {
+ private AssetConfiguration assetConfiguration;
+
+ private FileStorageService fileStorageService;
+
+ private Thumbor thumbor;
+
+ private List defaultSizes = Arrays.asList(PreviewSize.S, PreviewSize.M, PreviewSize.L);
+
+ @Autowired
+ public AssetConverter(AssetConfiguration assetConfiguration, FileStorageService fileStorageService) {
+ this.assetConfiguration = assetConfiguration;
+ this.fileStorageService = fileStorageService;
+ }
+
+ private boolean useLocalEndpoint() {
+ return fileStorageService instanceof MongoFileStorageService;
+ }
+
+ public AssetRead fromEntity(AssetEntity entity, List sizes, HttpServletRequest request) {
if (entity == null) {
return null;
}
+ AssetPreviews assetPreviews = AssetPreviews.builder()
+ .previewMap(new HashMap<>())
+ .build();
+
+ ((sizes == null || sizes.isEmpty()) ? defaultSizes : sizes)
+ .forEach(s -> assetPreviews.getPreviewMap()
+ .put(s, getPreviewUrl(entity, s, request)));
+
return AssetRead.builderRead()
.id(entity.getId())
.systemRefId(entity.getSystemRefId())
@@ -28,14 +63,50 @@ public AssetRead fromEntity(AssetEntity entity, List sizes) {
.resolution(entity.getResolution())
.referenceUrl(entity.getReferenceUrl())
.build())
- .previews(null)
+ .previews(assetPreviews)
.build();
}
- public List fromEntities(List entities, List sizes) {
+ public List fromEntities(List entities, List sizes, HttpServletRequest request) {
if (entities == null) {
return null;
}
- return entities.stream().map(v -> fromEntity(v, sizes)).collect(Collectors.toList());
+ return entities.stream().map(v -> fromEntity(v, sizes, request)).collect(Collectors.toList());
+ }
+
+ private String getPreviewUrl(AssetEntity entity, PreviewSize size, HttpServletRequest request) {
+ if (useLocalEndpoint()) {
+ return getBaseUrl(request) + assetConfiguration.getRenderEndpoint() + "/" + entity.getId() + "/" + size.name().toLowerCase();
+ } else {
+ return getThumbor().buildImage(entity.getUrlPath())
+ .resize(size.getMaxWidth(), size.getMaxHeight())
+ .fitIn()
+ .toUrl();
+ }
+ }
+
+ private Thumbor getThumbor() {
+ if (thumbor == null) {
+ String thumborKey = assetConfiguration.getThumborKey();
+ if (thumborKey.isEmpty()) {
+ thumbor = Thumbor.create(assetConfiguration.getThumborHost());
+ } else {
+ thumbor = Thumbor.create(assetConfiguration.getThumborHost(), thumborKey);
+ }
+ }
+ return thumbor;
+ }
+
+ private String getBaseUrl(HttpServletRequest request) {
+ String result = request.getScheme() + "://" + request.getServerName();
+ int serverPort = request.getServerPort();
+ if (serverPort != 80 && serverPort != 443) {
+ result += ":" + serverPort;
+ }
+ result += request.getContextPath();
+ if (result.endsWith("/")) {
+ result = result.substring(0, result.length() - 1);
+ }
+ return result;
}
}
diff --git a/commons-asset-core/src/test/java/io/rocketbase/commons/converter/AssetConverterTest.java b/commons-asset-core/src/test/java/io/rocketbase/commons/converter/AssetConverterTest.java
new file mode 100644
index 0000000..6bd5111
--- /dev/null
+++ b/commons-asset-core/src/test/java/io/rocketbase/commons/converter/AssetConverterTest.java
@@ -0,0 +1,64 @@
+package io.rocketbase.commons.converter;
+
+import io.rocketbase.commons.config.AssetConfiguration;
+import io.rocketbase.commons.dto.asset.AssetRead;
+import io.rocketbase.commons.dto.asset.AssetType;
+import io.rocketbase.commons.dto.asset.PreviewSize;
+import io.rocketbase.commons.dto.asset.Resolution;
+import io.rocketbase.commons.model.AssetEntity;
+import io.rocketbase.commons.service.MongoFileStorageService;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.notNullValue;
+
+public class AssetConverterTest {
+
+ @Test
+ public void testFromEntityWithLocalRender() {
+ // given
+ AssetConfiguration config = new AssetConfiguration();
+ config.setApiEndpoint("/api/asset");
+ config.setRenderEndpoint("/get/asset");
+
+ HttpServletRequest mockedRequest = Mockito.mock(HttpServletRequest.class);
+ Mockito.when(mockedRequest.getScheme())
+ .thenReturn("http");
+ Mockito.when(mockedRequest.getServerName())
+ .thenReturn("localhost");
+ Mockito.when(mockedRequest.getServerPort())
+ .thenReturn(8080);
+ Mockito.when(mockedRequest.getContextPath())
+ .thenReturn("/");
+
+ String baseUrl = "http://localhost:8080" + config.getRenderEndpoint() + "/";
+
+ AssetConverter converter = new AssetConverter(config, new MongoFileStorageService(null));
+ // when
+ AssetRead assetRead = converter.fromEntity(AssetEntity.builder()
+ .id("1235678")
+ .urlPath("12345678")
+ .fileSize(1234L)
+ .created(LocalDateTime.now())
+ .originalFilename("originial.png")
+ .type(AssetType.PNG)
+ .systemRefId("123")
+ .resolution(new Resolution(100, 200))
+ .build(), Arrays.asList(PreviewSize.S, PreviewSize.M, PreviewSize.L), mockedRequest);
+
+ // then
+ assertThat(assetRead, notNullValue());
+ assertThat(assetRead.getPreviews(), notNullValue());
+ assertThat(assetRead.getPreviews().getPreviewMap().size(), equalTo(3));
+ assertThat(assetRead.getPreviews().getPreviewMap().get(PreviewSize.S), equalTo(baseUrl + assetRead.getId() + "/s"));
+ assertThat(assetRead.getPreviews().getPreviewMap().get(PreviewSize.M), equalTo(baseUrl + assetRead.getId() + "/m"));
+ assertThat(assetRead.getPreviews().getPreviewMap().get(PreviewSize.L), equalTo(baseUrl + assetRead.getId() + "/l"));
+
+ }
+}
\ No newline at end of file