From bb66aa5a312362d9d964b1fa540854cf33106ece Mon Sep 17 00:00:00 2001 From: Will Price Date: Fri, 29 Sep 2017 13:37:26 +0200 Subject: [PATCH] More efficient processing for non published assets, including allowing versioning - see issue #75 --- .../common/api/localization/Localization.java | 9 +++++++- .../interceptor/StaticContentInterceptor.java | 17 +++++++++++--- .../localization/LocalizationFactoryImpl.java | 5 +++- .../impl/localization/LocalizationImpl.java | 23 +++++++++++++++++-- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/dxa-framework/dxa-common-api/src/main/java/com/sdl/webapp/common/api/localization/Localization.java b/dxa-framework/dxa-common-api/src/main/java/com/sdl/webapp/common/api/localization/Localization.java index 76f071ea5..0d88a0725 100644 --- a/dxa-framework/dxa-common-api/src/main/java/com/sdl/webapp/common/api/localization/Localization.java +++ b/dxa-framework/dxa-common-api/src/main/java/com/sdl/webapp/common/api/localization/Localization.java @@ -32,6 +32,14 @@ public interface Localization { */ boolean isStaticContent(String url); + /** + * Determines if the specified URL refers to static content within the webapp + * + * @return {@code true} if the specified URL refers to static content within the webapp, {@code false} otherwise. + * @param url a {@link java.lang.String} object. + */ + boolean isNonPublishedAsset(String url); + /** *

isDefault.

* @@ -120,5 +128,4 @@ public interface Localization { */ List getDataFormats(); - } diff --git a/dxa-framework/dxa-common-impl/src/main/java/com/sdl/webapp/common/impl/interceptor/StaticContentInterceptor.java b/dxa-framework/dxa-common-impl/src/main/java/com/sdl/webapp/common/impl/interceptor/StaticContentInterceptor.java index bbfc114f7..bdeaf5d0e 100644 --- a/dxa-framework/dxa-common-impl/src/main/java/com/sdl/webapp/common/impl/interceptor/StaticContentInterceptor.java +++ b/dxa-framework/dxa-common-impl/src/main/java/com/sdl/webapp/common/impl/interceptor/StaticContentInterceptor.java @@ -8,6 +8,7 @@ import com.sdl.webapp.common.api.localization.Localization; import com.sdl.webapp.common.util.MimeUtils; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.joda.time.Hours; import org.joda.time.Weeks; import org.slf4j.Logger; @@ -27,6 +28,7 @@ import java.io.OutputStream; import java.lang.management.ManagementFactory; import java.net.URL; +import java.util.regex.Pattern; /** * Static content interceptor. This interceptor checks if the request is for static content, and if it is, it sends @@ -38,6 +40,7 @@ public class StaticContentInterceptor extends HandlerInterceptorAdapter { private static final Logger LOG = LoggerFactory.getLogger(StaticContentInterceptor.class); private static final String CACHE_CONTROL_WEEK = "public, max-age=" + Weeks.ONE.toStandardSeconds().getSeconds(); private static final String CACHE_CONTROL_HOUR = "public, max-age=" + Hours.ONE.toStandardSeconds().getSeconds(); + private static final Pattern SYSTEM_VERSION_PATTERN = Pattern.compile("/system/v\\d+\\.\\d+/"); @Autowired private ContentProvider contentProvider; @@ -89,9 +92,10 @@ private static void fallbackForContentProvider(ServletServerHttpRequest req, Str /** * {@inheritDoc} + * @throws IOException */ @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException { + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException { final String requestPath = webRequestContext.getRequestPath(); LOG.trace("preHandle: {}", requestPath); @@ -103,12 +107,16 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons final ServletServerHttpResponse res = new ServletServerHttpResponse(response); try { + if (localization.isNonPublishedAsset(requestPath)) + { + fallbackForContentProvider(req, removeVersionNumber(requestPath), res); + } StaticContentItem staticContentItem = null; try { staticContentItem = contentProvider.getStaticContent(requestPath, localization.getId(), localization.getPath()); } catch (StaticContentNotFoundException e) { - fallbackForContentProvider(req, requestPath, res); + fallbackForContentProvider(req, removeVersionNumber(requestPath), res); } if (staticContentItem != null) { @@ -131,7 +139,10 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons res.close(); return false; } - return true; } + + protected static String removeVersionNumber(String path) { + return SYSTEM_VERSION_PATTERN.matcher(path).replaceFirst("/system/"); + } } diff --git a/dxa-framework/dxa-common-impl/src/main/java/com/sdl/webapp/common/impl/localization/LocalizationFactoryImpl.java b/dxa-framework/dxa-common-impl/src/main/java/com/sdl/webapp/common/impl/localization/LocalizationFactoryImpl.java index d4d7635f9..2c587bc2f 100644 --- a/dxa-framework/dxa-common-impl/src/main/java/com/sdl/webapp/common/impl/localization/LocalizationFactoryImpl.java +++ b/dxa-framework/dxa-common-impl/src/main/java/com/sdl/webapp/common/impl/localization/LocalizationFactoryImpl.java @@ -125,14 +125,16 @@ private boolean loadVersionFromProperties(String id, String path, LocalizationIm return false; } builder.setVersion(assetsVersion); + builder.setHtmlDesignPublished(false); return true; -} + } private boolean loadVersionFromBroker(String id, String path, LocalizationImpl.Builder builder) throws LocalizationFactoryException { try { StaticContentItem item = contentProvider.getStaticContent(VERSION_PATH, id, path); try (final InputStream in = item.getContent()) { builder.setVersion(objectMapper.readTree(in).get("version").asText()); + builder.setHtmlDesignPublished(true); return true; } } catch (StaticContentNotFoundException e) { @@ -153,6 +155,7 @@ private boolean loadVersionFromWebapp(String id, String path, LocalizationImpl.B try (final InputStream in = new FileInputStream(file)) { builder.setVersion(objectMapper.readTree(in).get("version").asText()); + builder.setHtmlDesignPublished(false); return true; } catch (IOException e) { throw new LocalizationFactoryException("Exception while reading configuration of localization: [" + id + diff --git a/dxa-framework/dxa-common-impl/src/main/java/com/sdl/webapp/common/impl/localization/LocalizationImpl.java b/dxa-framework/dxa-common-impl/src/main/java/com/sdl/webapp/common/impl/localization/LocalizationImpl.java index 8e8f83716..33c864ea0 100644 --- a/dxa-framework/dxa-common-impl/src/main/java/com/sdl/webapp/common/impl/localization/LocalizationImpl.java +++ b/dxa-framework/dxa-common-impl/src/main/java/com/sdl/webapp/common/impl/localization/LocalizationImpl.java @@ -41,6 +41,9 @@ public class LocalizationImpl implements Localization { @Getter private final String version; + @Getter + private final boolean isHtmlDesignPublished; + @Getter private final List siteLocalizations; @@ -67,7 +70,7 @@ private LocalizationImpl(Builder builder) { this.default_ = builder.default_; this.staging = builder.staging; this.version = builder.version; - + this.isHtmlDesignPublished = builder.htmlDesignPublished; this.siteLocalizations = builder.siteLocalizationsBuilder.build(); this.configuration = builder.configurationBuilder.build(); this.resources = builder.resourcesBuilder.build(); @@ -96,11 +99,21 @@ public boolean isStaticContent(String url) { if (url.startsWith(mediaRoot)) { return true; } - final String p = path.equals("/") ? url : url.substring(path.length()); return p.equals(FAVICON_PATH) || SYSTEM_ASSETS_PATTERN.matcher(p).matches(); } + /** + * {@inheritDoc} + */ + @Override + public boolean isNonPublishedAsset(String url) { + if (!this.isHtmlDesignPublished && SYSTEM_ASSETS_PATTERN.matcher(url).matches()){ + return true; + } + return false; + } + /** * {@inheritDoc} */ @@ -173,6 +186,7 @@ public static final class Builder { private boolean default_; private boolean staging; private String version; + private boolean htmlDesignPublished; private Builder() { } @@ -207,6 +221,11 @@ public Builder setVersion(String version) { return this; } + public Builder setHtmlDesignPublished(boolean htmlDesignPublished) { + this.htmlDesignPublished = htmlDesignPublished; + return this; + } + public Builder addSiteLocalizations(Iterable siteLocalizations) { this.siteLocalizationsBuilder.addAll(siteLocalizations); return this;