From faa14056fa2104c7383e16f5b6d25d29d39cc87e Mon Sep 17 00:00:00 2001 From: Teo Sarca Date: Thu, 22 Jun 2017 23:17:28 +0300 Subject: [PATCH] Cache image endpoint https://github.com/metasfresh/metasfresh-webui-api/issues/470 --- src/main/java/de/metas/ui/web/cache/ETag.java | 6 +- .../web/cache/ETagResponseEntityBuilder.java | 12 +-- .../ui/web/upload/ImageRestController.java | 87 ++++++++++++++++--- 3 files changed, 85 insertions(+), 20 deletions(-) diff --git a/src/main/java/de/metas/ui/web/cache/ETag.java b/src/main/java/de/metas/ui/web/cache/ETag.java index 1b2f951f9..e2099a761 100644 --- a/src/main/java/de/metas/ui/web/cache/ETag.java +++ b/src/main/java/de/metas/ui/web/cache/ETag.java @@ -39,17 +39,17 @@ public static final ETag of(final int version) return new ETag(version, ImmutableMap.of()); } - public static final ETag of(final int version, final Map attributes) + public static final ETag of(final long version, final Map attributes) { return new ETag(version, ImmutableMap.copyOf(attributes)); } - private final int version; + private final long version; private final ImmutableMap attributes; private transient volatile String _etagString = null; // lazy - private ETag(final int version, final ImmutableMap attributes) + private ETag(final long version, final ImmutableMap attributes) { this.version = version; this.attributes = attributes; diff --git a/src/main/java/de/metas/ui/web/cache/ETagResponseEntityBuilder.java b/src/main/java/de/metas/ui/web/cache/ETagResponseEntityBuilder.java index f90a4104b..2cc1e1206 100644 --- a/src/main/java/de/metas/ui/web/cache/ETagResponseEntityBuilder.java +++ b/src/main/java/de/metas/ui/web/cache/ETagResponseEntityBuilder.java @@ -117,6 +117,11 @@ private ETag getETag() } public ResponseEntity toJson(final BiFunction toJsonMapper) + { + return toResponseEntity((responseBuilder, result) -> responseBuilder.body(toJsonMapper.apply(result, getJSONOptions()))); + } + + public ResponseEntity toResponseEntity(final BiFunction> toJsonMapper) { // Check ETag final String etag = getETag().toETagString(); @@ -128,12 +133,9 @@ public ResponseEntity toJson(final BiFunction getImage(@PathVariable final int imageId, - @RequestParam(name = "maxWidth", required = false, defaultValue = "-1") int maxWidth, - @RequestParam(name = "maxHeight", required = false, defaultValue = "-1") int maxHeight) + @RequestParam(name = "maxWidth", required = false, defaultValue = "-1") final int maxWidth, + @RequestParam(name = "maxHeight", required = false, defaultValue = "-1") final int maxHeight, + final WebRequest request) { userSession.assertLoggedIn(); + return ETagResponseEntityBuilder.ofETagAware(request, getWebuiImage(imageId, maxWidth, maxHeight)) + .includeLanguageInETag() + .cacheMaxAge(userSession.getHttpCacheMaxAge()) + .jsonOptions(() -> newJSONOptions()) + .toResponseEntity((responseBuilder, webuiImage) -> responseBuilder + .contentType(MediaType.parseMediaType(webuiImage.getContentType())) + .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + webuiImage.getImageName() + "\"") + .body(webuiImage.getImageData())); + } + + private WebuiImage getWebuiImage(final int imageId, final int maxWidth, final int maxHeight) + { if (imageId <= 0) { throw new IllegalArgumentException("Invalid image id"); @@ -125,16 +150,54 @@ public ResponseEntity getImage(@PathVariable final int imageId, throw new EntityNotFoundException("Image id not found: " + imageId); } - final String imageName = adImage.getName(); - final String contentType = adImage.getContentType(); - final byte[] imageData = adImage.getScaledImageData(maxWidth, maxHeight); + return WebuiImage.of(adImage, maxWidth, maxHeight); + } - final HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.parseMediaType(contentType)); - headers.set(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + imageName + "\""); - headers.setCacheControl("must-revalidate, post-check=0, pre-check=0"); - final ResponseEntity response = new ResponseEntity(imageData, headers, HttpStatus.OK); - return response; + private static final class WebuiImage implements ETagAware + { + public static final WebuiImage of(final MImage adImage, final int maxWidth, final int maxHeight) + { + return new WebuiImage(adImage, maxWidth, maxHeight); + } + + private final MImage adImage; + private final int maxWidth; + private final int maxHeight; + private final ETag etag; + + private WebuiImage(@NonNull final MImage adImage, final int maxWidth, final int maxHeight) + { + this.adImage = adImage; + this.maxWidth = maxWidth > 0 ? maxWidth : 0; + this.maxHeight = maxHeight > 0 ? maxHeight : 0; + + etag = ETag.of(adImage.getUpdated().getTime(), ImmutableMap. builder() + .put("maxWidth", String.valueOf(maxWidth)) + .put("maxHeight", String.valueOf(maxHeight)) + .put("imageId", String.valueOf(adImage.getAD_Image_ID())) + .build()); + } + + @Override + public ETag getETag() + { + return etag; + } + + public String getImageName() + { + return adImage.getName(); + } + + public String getContentType() + { + return adImage.getContentType(); + } + + public byte[] getImageData() + { + return adImage.getScaledImageData(maxWidth, maxHeight); + } } }