@Override public String getStaticResourcePrefix(UrlMode urlMode) { // "{base url}/s/{lang?}/{build num}/{system counter}/_" // {lang} is optional return joinWithSlashWithoutEmpty( webResourceIntegration.getBaseUrl(urlMode), STATIC_RESOURCE_PREFIX, webResourceIntegration.getI18nStateHash(), webResourceIntegration.getSystemBuildNumber(), webResourceIntegration.getSystemCounter(), STATIC_RESOURCE_SUFFIX ); }
/** * @return if CDN is globally enabled. */ public boolean isCdnEnabled() { return null != integration.getCDNStrategy() && integration.getCDNStrategy().supportsCdn(); }
private Map<String, Object> cache() { return webResourceIntegration.getRequestCache(); } }
@Override protected WebResourceMapper create() throws Exception { if (integration.isCtCdnMappingEnabled()) { final Optional<PrebakeConfig> prebakeConfig = integration.getCDNStrategy() != null ? integration.getCDNStrategy().getPrebakeConfig() : Optional.empty(); if (prebakeConfig.isPresent()) { try { log.info("Creating DefaultWebResourceMapper"); return new DefaultWebResourceMapper(integration, new MappingParser(), prebakeConfig.get(), computeGlobalStateHash(), getCtCdnBaseUrl(), integration.getBaseUrl(UrlMode.RELATIVE)); } catch (FileNotFoundException e) { //no additional logging, it isn't an error return new NoOpWebResourceMapper(e); } catch (Exception e) { log.info("DefaultWebResourceMapper was not created properly. Pre-baked CT-CDN is disabled but will fall back to product's CDN Strategy, if any.", e); return new NoOpWebResourceMapper(e); } } else { log.info("Creating NoOpWebResourceMapper since PrebakeConfig is not present. Pre-baked CT-CDN is disabled but will fall back to product's CDN Strategy, if any."); return new NoOpWebResourceMapper(new Exception("PrebakeConfig not present")); } } else { log.info("Creating NoOpWebResourceMapper since WebResourceIntegration#isCtCdnMappingEnabled flag is disabled. Pre-baked CT-CDN is disabled but will fall back to product's CDN Strategy, if any."); return new NoOpWebResourceMapper(new Exception("CT-CDN is explicitly disabled by the product.")); } } };
public Map<String, String> getVariableMap(boolean addLegacyVars) { final Map<String, String> result = new LinkedHashMap<>(); final Map<String, Object> beanProperties = getLookAndFeelProperties(); for (Map.Entry<String, Object> entry : beanProperties.entrySet()) { final String name = entry.getKey(); final Object value = entry.getValue(); if (value instanceof String) { String stringValue = (String) value; result.put(name, stringValue); if (addLegacyVars) { result.put(name + "NoHash", StringUtils.strip(stringValue, "#")); } } } addFieldLabelWidthVariables(result, addLegacyVars); addGadgetColours(result); HttpServletRequest httpServletRequest = ExecutingHttpRequest.get(); if (httpServletRequest != null) { result.put("contextPath", httpServletRequest.getContextPath()); } result.put("systemBuildNumber", webResourceIntegration.getSystemBuildNumber()); result.put("systemCounter", webResourceIntegration.getSystemCounter()); return result; }
@Override public String getBaseUrl(UrlMode urlMode) { return webResourceIntegration.getBaseUrl(urlMode); } }
final String hash = config.computeGlobalStateHash(); final WebResourceMapper wrm = config.getWebResourceMapper(); final Optional<PrebakeConfig> prebakeConfig = webResourceIntegration.getCDNStrategy() != null ? webResourceIntegration.getCDNStrategy().getPrebakeConfig() : Optional.empty(); wrm.getClass().getName()); return ok(new Info( new Info.State(config.getCtCdnBaseUrl(), hash, webResourceIntegration.isCtCdnMappingEnabled()), new Info.PreBaker(config.isPreBakeEnabled()), new Info.PrebakeConfig(
@Override protected String create() { // This transform's only "variable" is the context path, and hence is not even variable since the // context path is already in the url path. Therefore we don't need to contribute anything additional // to the hash - this transform is a "constant" and other transformers / conditions don't apply to data // uri's or images. final String version = Config.getPluginVersionOrInstallTime(webResourceIntegration.getPluginAccessor().getPlugin(parameters.getPluginKey()), usePluginInstallTimeInsteadOfTheVersionForSnapshotPlugins); String resourcePrefix = PATH_SEPARATOR + AbstractFileServerServlet.SERVLET_PATH + PATH_SEPARATOR + AbstractFileServerServlet.RESOURCE_URL_PREFIX; String localRelativeUrl = webResourceUrlProvider.getStaticResourcePrefix(version, UrlMode.RELATIVE) + resourcePrefix + PATH_SEPARATOR + parameters.getPluginKey() + ":" + parameters.getModuleKey() + PATH_SEPARATOR; if (requestCdnUrl) { final CDNStrategy cdnStrategy = webResourceIntegration.getCDNStrategy(); if (cdnStrategy == null || !cdnStrategy.supportsCdn()) { // This will throw an exception if we have the CDN parameter in the URL, but // webResourceIntegration.getCdnStrategy() returns null. This situation will occur // if the cdn strategy is changed (eg via dark feature) between url-generation time and // resource-fetch time. In this situation, it is correct to throw an exception - the alternative // is to poison the CDN-side cache with a resource that has not been transformed to CDN. throw new CdnStrategyChangedException("CDN strategy has changed between url generation time and resource fetch time"); } return cdnResourceUrlTransformer.getResourceCdnPrefix(localRelativeUrl); } else { return localRelativeUrl; } } };
/** * @return directory where cache content would be stored as files. */ public File getCacheDirectory() { return integration.getTemporaryDirectory(); }
@Override public Dimensions computeDimensions() { List<String> locales = StreamSupport.stream(webResourceIntegration.getSupportedLocales().spliterator(), false) .map(LocaleUtils::serialize).collect(Collectors.toList()); return Dimensions.empty().andExactly(QUERY_KEY, locales); }
@Nonnull @Override public List<String> map(@Nonnull final String resourceUrl) { if (!webResourceIntegration.isCtCdnMappingEnabled()) { return Collections.emptyList(); } final List<String> mappedResources = this.mappings.getMappedResources(removeContext(resourceUrl)); if (!mappedResources.isEmpty()) { log.debug("Mapped resource {} to {}", resourceUrl, mappedResources); } else { log.debug("Cache miss for resource {}", resourceUrl); } return mappedResources.stream().map(this::joinBaseUrlSafely).collect(Collectors.toList()); }
private void addToUrl(UrlBuilder urlBuilder, String locale) { urlBuilder.addToQueryString(QUERY_KEY, locale); // We add webResourceIntegration.getI18nStateHash() to the key; // this value varies whenever any plugins that contribute to i18n (eg language // packs) are changed, but does not include current locale as it's already in the query string. urlBuilder.addToHash(HASH_KEY, webResourceIntegration.getI18nStateHash()); } }
/** * Much of this code is copied from * {@link com.atlassian.plugin.webresource.WebResourceUrlProvider} * method : getStaticPluginResourceUrl() * @param moduleKey the module key * @param resource the resource * @return the absolute url */ public String getResourceUrl(String moduleKey, String resource ){ ModuleDescriptor<?> module = pluginAccessor.getEnabledPluginModule(moduleKey); final PluginInformation pluginInfo = module.getPlugin().getPluginInformation(); final String pluginVersion = pluginInfo != null ? pluginInfo.getVersion() : UNKNOWN; final String baseUrl = applicationProperties.getBaseUrl(UrlMode.ABSOLUTE) + STATIC_PREFIX + webResourceIntegration.getSystemBuildNumber() + PATH_SEPARATOR + webResourceIntegration.getSystemCounter() + PATH_SEPARATOR + pluginVersion + STATIC_SUFFIX; return baseUrl + DOWNLOAD_RESOURCES_PREFIX + moduleKey + PATH_SEPARATOR + resource; }
@Override public String getBaseUrl() { return webResourceIntegration.getBaseUrl(); }
private ZipBundler createBundler() { String globalStateHash = config.computeGlobalStateHash(); File tmp = webResourceIntegration.getTemporaryDirectory(); Path outputFolder = Paths.get(tmp.getAbsolutePath(), globalStateHash); try { FileUtils.deleteDirectory(outputFolder.toFile()); boolean created = outputFolder.toFile().mkdirs(); if (!created) { String msg = String.format("Cannot create temporary folder '%s'", outputFolder.toString()); throw new PreBakeIOException(msg); } return new ZipBundler(globalStateHash, outputFolder); } catch (IOException e) { String msg = String.format("Cannot clean temporary folder '%s'", outputFolder.toString()); throw new PreBakeIOException(msg, e); } }
@Override public Dimensions computeDimensions() { List<String> locales = StreamSupport.stream(webResourceIntegration.getSupportedLocales().spliterator(), false) .map(LocaleUtils::serialize).collect(Collectors.toList()); return Dimensions.empty().andExactly(QUERY_KEY, locales) .product(soyFunctionSupplier.computeDimensions()); }
@Override public String getStaticResourcePrefix(String resourceCounter, UrlMode urlMode) { // "{base url}/s/{lang?}/{build num}/{system counter}/{resource counter}/_" // {lang} is optional return joinWithSlashWithoutEmpty( webResourceIntegration.getBaseUrl(urlMode), STATIC_RESOURCE_PREFIX, webResourceIntegration.getI18nStateHash(), webResourceIntegration.getSystemBuildNumber(), webResourceIntegration.getSystemCounter(), resourceCounter, STATIC_RESOURCE_SUFFIX ); }
@Override public Jsonable get() { return new JsonableString(webResourceIntegration.getBaseUrl(UrlMode.RELATIVE)); } }
@Override public void clearRequestLocal() { webResourceIntegration.getRequestCache().remove(REQUEST_CACHE_REQUIRED_RESOURCES); } }
@Override public void addToUrl(UrlBuilder urlBuilder) { if (webResourceIntegration.getCDNStrategy() != null && webResourceIntegration.getCDNStrategy().supportsCdn()) { addRelativeUrlQueryKey(urlBuilder); } }