/atlassian-plugins-webresource-rest/src/main/java/com/atlassian/webresource/plugin/rest/one/zero/CrossTenantCdnResource.java
Java | 195 lines | 155 code | 23 blank | 17 comment | 3 complexity | f6be975b407432ff9d8d2aec20029b74 MD5 | raw file
- package com.atlassian.webresource.plugin.rest.one.zero;
- import com.atlassian.plugin.webresource.PluginResourceLocator;
- import com.atlassian.plugin.webresource.WebResourceIntegration;
- import com.atlassian.plugin.webresource.cdn.mapper.Mapping;
- import com.atlassian.plugin.webresource.cdn.mapper.WebResourceMapper;
- import com.atlassian.plugin.webresource.impl.config.Config;
- import com.atlassian.plugin.webresource.prebake.PrebakeConfig;
- import com.atlassian.plugins.rest.common.security.AnonymousAllowed;
- import org.apache.commons.lang3.exception.ExceptionUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import javax.ws.rs.DefaultValue;
- import javax.ws.rs.GET;
- import javax.ws.rs.PUT;
- import javax.ws.rs.Path;
- import javax.ws.rs.Produces;
- import javax.ws.rs.QueryParam;
- import javax.ws.rs.core.MediaType;
- import javax.ws.rs.core.Response;
- import java.util.List;
- import java.util.Map;
- import java.util.Optional;
- import java.util.function.Supplier;
- import java.util.stream.Collectors;
- import java.util.stream.StreamSupport;
- import static javax.ws.rs.core.Response.ok;
- import static javax.ws.rs.core.Response.status;
- /**
- * REST end-point providing CT-CDN diagnostics.
- *
- * @since v3.5.7
- */
- @AnonymousAllowed
- @Path("ct-cdn")
- public class CrossTenantCdnResource {
- private static final Logger log = LoggerFactory.getLogger(CrossTenantCdnResource.class);
- private final WebResourceIntegration webResourceIntegration;
- private final Config config;
- @SuppressWarnings("deprecation")
- public CrossTenantCdnResource(
- final WebResourceIntegration webResourceIntegration,
- final PluginResourceLocator pluginResourceLocator) {
- this.webResourceIntegration = webResourceIntegration;
- this.config = pluginResourceLocator.temporaryWayToGetGlobalsDoNotUseIt().getConfig();
- }
- /**
- * Returns a JSON with information about the current status of CT-CDN.
- *
- * @param includeMappings Includes the full loaded mappings in the JSON when true.
- */
- @Path("status")
- @GET
- @Produces({MediaType.APPLICATION_JSON})
- public Response healthInfo(@QueryParam("includeMappings") @DefaultValue("true") final boolean includeMappings) {
- log.debug("Collection general info about CT-CDN");
- final String hash = config.computeGlobalStateHash();
- final WebResourceMapper wrm = config.getWebResourceMapper();
- final Optional<PrebakeConfig> prebakeConfig = webResourceIntegration.getCDNStrategy() != null ?
- webResourceIntegration.getCDNStrategy().getPrebakeConfig() : Optional.empty();
- final Map<String, List<String>> simpleMappings = StreamSupport
- .stream(wrm.mappings().all().spliterator(), false)
- .collect(Collectors.toMap(Mapping::originalResource, Mapping::mappedResources));
- final Info.WebResourceMapper wrmInfo = new Info.WebResourceMapper(
- includeMappings ? simpleMappings : null,
- simpleMappings.size(),
- simpleMappings.values().stream().mapToInt(List::size).sum(),
- wrm.getClass().getName());
- return ok(new Info(
- new Info.State(config.getCtCdnBaseUrl(), hash, webResourceIntegration.isCtCdnMappingEnabled()),
- new Info.PreBaker(config.isPreBakeEnabled()),
- new Info.PrebakeConfig(
- prebakeConfig.map(PrebakeConfig::getPattern).orElse("[EMPTY]"),
- prebakeConfig.map(pc -> pc.getMappingLocation(hash).getAbsolutePath()).orElse("[EMPTY]"),
- prebakeConfig.map(pc -> pc.getMappingLocation(hash).exists()).orElse(false)),
- wrmInfo
- )).build();
- }
- /**
- * Tries to reload mappings using the current configuration.
- * It was not design for production but testing and diagnostic purposes.
- * An error is returned if CT-CDN is disabled by the product through {@link PrebakeConfig}.
- *
- * @return Result of the reload, including the stack trace in case of error.
- */
- @Path("mappings")
- @PUT
- @Produces({MediaType.APPLICATION_JSON})
- public final Response reloadMappings() {
- return whenPreBakeIsEnabled(() -> {
- log.info("Trying to reload WebResourceMapper");
- try {
- config.reloadWebResourceMapper();
- return ok(new ReloadStatus("Mappings were reloaded",
- config.getWebResourceMapper().mappings().size(), null)).build();
- } catch (Exception e) {
- log.warn(e.getMessage(), e);
- return ok(new ReloadStatus(e.getMessage(), config.getWebResourceMapper().mappings().size(),
- ExceptionUtils.getStackTrace(e))).build();
- }
- });
- }
- private Response whenPreBakeIsEnabled(Supplier<Response> normalResponse) {
- if (config.isPreBakeEnabled()) {
- return normalResponse.get();
- } else {
- log.warn("Pre-baking called but feature is not enabled!");
- return status(Response.Status.FORBIDDEN).build();
- }
- }
- public static class ReloadStatus {
- public String status;
- public int size;
- public String exception;
- public ReloadStatus(final String status, final int size, final String exception) {
- this.status = status;
- this.size = size;
- this.exception = exception;
- }
- }
- public static class Info {
- public State state;
- public PreBaker preBaker;
- public PrebakeConfig prebakeConfig;
- public WebResourceMapper webResourceMapper;
- public Info(final State state, final PreBaker preBaker, final PrebakeConfig prebakeConfig,
- final WebResourceMapper webResourceMapper) {
- this.state = state;
- this.preBaker = preBaker;
- this.prebakeConfig = prebakeConfig;
- this.webResourceMapper = webResourceMapper;
- }
- public static class State {
- public String baseUrl;
- public String productStateHash;
- public boolean enabled;
- public State(final String baseUrl, final String productStateHash, final boolean enabled) {
- this.baseUrl = baseUrl;
- this.productStateHash = productStateHash;
- this.enabled = enabled;
- }
- }
- public static class PreBaker {
- public boolean enabled;
- public PreBaker(boolean enabled) {
- this.enabled = enabled;
- }
- }
- public static class PrebakeConfig {
- public String mappingFilePattern;
- public String mappingFileLocation;
- public boolean fileExists;
- public PrebakeConfig(final String mappingFilePattern, final String mappingFileLocation, boolean fileExists) {
- this.mappingFilePattern = mappingFilePattern;
- this.mappingFileLocation = mappingFileLocation;
- this.fileExists = fileExists;
- }
- }
- public static class WebResourceMapper {
- public String implementationClass;
- public int numberOfEntries;
- public int countOfValues;
- public Map<String, List<String>> mappings;
- public WebResourceMapper(final Map<String, List<String>> mappings, final int numberOfEntries,
- final int countOfValues, final String implementationClass) {
- this.mappings = mappings;
- this.numberOfEntries = numberOfEntries;
- this.countOfValues = countOfValues;
- this.implementationClass = implementationClass;
- }
- }
- }
- }