SiteCatalystProvisioningHandler.java 18.3 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.crypto.CryptoException
 *  com.adobe.granite.crypto.CryptoSupport
 *  com.day.cq.commons.jcr.JcrUtil
 *  com.day.cq.wcm.api.Page
 *  com.day.cq.wcm.api.PageManager
 *  com.day.cq.wcm.api.WCMException
 *  com.day.cq.wcm.webservicesupport.Configuration
 *  com.day.cq.wcm.webservicesupport.ConfigurationManager
 *  com.day.cq.wcm.webservicesupport.ConfigurationManagerFactory
 *  org.apache.commons.lang.ArrayUtils
 *  org.apache.commons.lang.StringUtils
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.resource.ModifiableValueMap
 *  org.apache.sling.api.resource.PersistenceException
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ResourceUtil
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.analytics.provisioning.impl;

import com.adobe.granite.crypto.CryptoException;
import com.adobe.granite.crypto.CryptoSupport;
import com.day.cq.analytics.provisioning.impl.ProvisioningException;
import com.day.cq.analytics.provisioning.impl.ProvisioningHandler;
import com.day.cq.analytics.sitecatalyst.SitecatalystWebservice;
import com.day.cq.analytics.sitecatalyst.impl.util.ReportConfigUtils;
import com.day.cq.analytics.sitecatalyst.impl.util.VariableUtils;
import com.day.cq.commons.jcr.JcrUtil;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.WCMException;
import com.day.cq.wcm.webservicesupport.Configuration;
import com.day.cq.wcm.webservicesupport.ConfigurationManager;
import com.day.cq.wcm.webservicesupport.ConfigurationManagerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=0)
@Service
@Properties(value={@Property(name="cloudservice.id", value={"analytics"})})
public class SiteCatalystProvisioningHandler
implements ProvisioningHandler {
    protected static final String PROPERTY_SERVER = "analytics.server";
    protected static final String PROPERTY_NAMESPACE = "analytics.namespace";
    protected static final String PROPERTY_TRACKINGSERVER = "analytics.trackingserver";
    protected static final String PROPERTY_TRACKINGSERVERSECURE = "analytics.trackingserversecure";
    protected static final String PROPERTY_COMPANY = "analytics.company";
    protected static final String PROPERTY_USERNAME = "analytics.username";
    protected static final String PROPERTY_PASSWORD = "analytics.password";
    protected static final String PROPERTY_SECRET = "analytics.secret";
    protected static final String PROPERTY_REPORTSUITE = "analytics.reportsuite";
    private static final String[] PROPERTIES_REQUIRED = new String[]{"analytics.server", "analytics.namespace", "analytics.trackingserver", "analytics.company", "analytics.username", "analytics.secret", "analytics.reportsuite"};
    private static final String DEFAULT_SERVICE_PATH = "/etc/cloudservices/sitecatalyst";
    private static final String DEFAULT_CONFIG_TEMPLATE = "/libs/cq/analytics/templates/sitecatalyst";
    private static final String DEFAULT_CONFIG_TITLE = "Provisioned Analytics Account";
    private static final String DEFAULT_FRAMEWORK_TEMPLATE = "/libs/cq/analytics/templates/framework";
    private static final String DEFAULT_FRAMEWORK_TITLE = "Provisioned Analytics Framework";
    private static final String DEFAULT_FRAMEWORK_NAME = "framework";
    private static final String MAPPINGS_SLING_RT = "cq/analytics/components/mappings/maparsys";
    private static final String CQMAPPINGS_SLING_RT = "cq/analytics/components/mappings/cqmappings";
    private static final String DEFAULT_REPORTSUITE_RUNMODE = "publish";
    private final Logger logger;
    @Reference
    private CryptoSupport cryptoSupport;
    @Reference
    private ConfigurationManagerFactory configManagerFactory;
    @Reference
    private SitecatalystWebservice sitecatalyst;

    public SiteCatalystProvisioningHandler() {
        this.logger = LoggerFactory.getLogger(this.getClass());
    }

    @Override
    public Resource setup(ResourceResolver resourceResolver, Map<String, Object> properties) throws ProvisioningException {
        try {
            this.logger.info("Provisioning Analytics...");
            this.checkProperties(properties, PROPERTIES_REQUIRED);
            String pageName = this.getValidPageName(StringUtils.trim((String)((String)properties.get("analytics.company"))));
            if (this.isSetup(resourceResolver, pageName)) {
                this.logger.debug("Found provisioned configuration for Analytics, skipping step.");
                return null;
            }
            Page newConfiguration = this.createConfiguration(resourceResolver, pageName, properties);
            return resourceResolver.getResource(newConfiguration.getPath());
        }
        catch (Exception e) {
            this.logger.error("Provisioning of Analytics failed: ", (Object)e.getMessage());
            throw new ProvisioningException("Provisioning of Analytics failed.", e);
        }
    }

    @Override
    public void rollback(ResourceResolver resourceResolver, Map<String, Object> properties) {
        String pageName = this.getValidPageName(StringUtils.trim((String)((String)properties.get("analytics.company"))));
        try {
            Resource failedConfiguration = resourceResolver.getResource("/etc/cloudservices/sitecatalyst/" + pageName);
            if (failedConfiguration != null) {
                resourceResolver.delete(failedConfiguration);
            }
        }
        catch (PersistenceException pe) {
            this.logger.error("Unable to rollback failed setup.", (Throwable)pe);
        }
    }

    /*
     * Enabled aggressive block sorting
     */
    @Override
    public void applyToSites(ResourceResolver resourceResolver, String[] sites, Resource configuration) throws ProvisioningException {
        PageManager pageMgr = (PageManager)resourceResolver.adaptTo(PageManager.class);
        String[] arr$ = sites;
        int len$ = arr$.length;
        int i$ = 0;
        while (i$ < len$) {
            String site = arr$[i$];
            Page page = pageMgr.getPage(site);
            if (page == null) {
                this.logger.error("Cannot find site at '{}'.", (Object)site);
                throw new ProvisioningException("Unable to apply configuration '" + configuration.getPath() + "' to sites.");
            }
            Resource content = page.getContentResource();
            if (content == null) {
                this.logger.error("Site at '{}' has no content.", (Object)site);
                throw new ProvisioningException("Unable to apply configuration '" + configuration.getPath() + "' to sites.");
            }
            ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
            String[] services = (String[])properties.get("cq:cloudserviceconfigs", (Object)new String[0]);
            Configuration config = this.configManagerFactory.getConfigurationManager(resourceResolver).getConfiguration("sitecatalyst", services);
            if (config != null) {
                this.logger.error("Site at '{}' already has a configuration applied.", (Object)site);
                throw new ProvisioningException("Unable to apply configuration '" + configuration.getPath() + "' to sites.");
            }
            this.logger.info("Applying cloudservice '{}' to '{}'.", (Object)configuration.getPath(), (Object)site);
            ArrayList<String> values = new ArrayList<String>(Arrays.asList(services));
            values.add(configuration.getPath());
            properties.remove((Object)"cq:cloudserviceconfigs");
            properties.put((Object)"cq:cloudserviceconfigs", (Object)values.toArray(new String[0]));
            this.postProcess(content, configuration);
            ++i$;
        }
    }

    /*
     * Enabled aggressive block sorting
     */
    @Override
    public void revokeFromSites(ResourceResolver resourceResolver, String[] sites, Resource configuration) throws ProvisioningException {
        PageManager pageMgr = (PageManager)resourceResolver.adaptTo(PageManager.class);
        String[] arr$ = sites;
        int len$ = arr$.length;
        int i$ = 0;
        while (i$ < len$) {
            String site = arr$[i$];
            Page page = pageMgr.getPage(site);
            if (page == null) {
                this.logger.error("Cannot find site at '{}'.", (Object)site);
                throw new ProvisioningException("Unable to apply configuration '" + configuration.getPath() + "' to sites.");
            }
            Resource content = page.getContentResource();
            if (content == null) {
                this.logger.error("Site at '{}' has no content.", (Object)site);
                throw new ProvisioningException("Unable to apply configuration '" + configuration.getPath() + "' to sites.");
            }
            ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
            Object[] services = (String[])properties.get("cq:cloudserviceconfigs", (Object)new String[0]);
            Configuration config = this.configManagerFactory.getConfigurationManager(resourceResolver).getConfiguration("testandtarget", (String[])services);
            if (config != null) throw new ProvisioningException("Unable to apply configuration '" + configuration.getPath() + "' to sites.");
            this.logger.info("Revoking cloudservice '{}' from '{}'.", (Object)configuration.getPath(), (Object)site);
            ArrayUtils.removeElement((Object[])services, (Object)configuration.getPath());
            properties.put((Object)"cq:cloudserviceconfigs", (Object)services);
            ++i$;
        }
    }

    private void postProcess(Resource target, Resource configuration) throws ProvisioningException {
        Configuration config = (Configuration)configuration.adaptTo(Configuration.class);
        ReportConfigUtils.addAnalytics(target, config.getResource(), this.configManagerFactory.getConfigurationManager(configuration.getResourceResolver()));
    }

    private Page createConfiguration(ResourceResolver resourceResolver, String pageName, Map<String, Object> properties) throws ProvisioningException {
        Page companyPage = this.getOrCreateConfigurationPage(resourceResolver, pageName, properties);
        Page framework = this.createFramework(resourceResolver, companyPage, properties);
        this.initializeConfiguration(framework);
        return framework;
    }

    private void initializeConfiguration(Page frameworkPage) {
        Configuration config = (Configuration)frameworkPage.adaptTo(Configuration.class);
        VariableUtils.getAndUpdateTrafficVariables(config, this.sitecatalyst, true);
        VariableUtils.getAndUpdateConversionVariables(config, this.sitecatalyst, true);
        VariableUtils.getAndUpdateEventVariables(config, this.sitecatalyst, true);
        VariableUtils.getAndUpdateMetrics(config, this.sitecatalyst, true);
    }

    private Page getOrCreateConfigurationPage(ResourceResolver resourceResolver, String pageName, Map<String, Object> properties) throws ProvisioningException {
        try {
            Resource content;
            PageManager pageManager = (PageManager)resourceResolver.adaptTo(PageManager.class);
            Page companyPage = pageManager.getPage("/etc/cloudservices/sitecatalyst/" + pageName);
            if (companyPage == null && (content = (companyPage = pageManager.create("/etc/cloudservices/sitecatalyst", pageName, "/libs/cq/analytics/templates/sitecatalyst", "Provisioned Analytics Account")).getContentResource()) != null) {
                ModifiableValueMap vm = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
                vm.put((Object)"server", (Object)StringUtils.trim((String)properties.get("analytics.server").toString()));
                vm.put((Object)"company", (Object)StringUtils.trim((String)properties.get("analytics.company").toString()));
                vm.put((Object)"username", properties.get("analytics.username"));
                String password = (String)properties.get("analytics.password");
                if (password != null) {
                    vm.put((Object)"password", (Object)this.cryptoSupport.protect(password));
                }
                String secret = (String)properties.get("analytics.secret");
                vm.put((Object)"secret", (Object)this.cryptoSupport.protect(secret));
            }
            return companyPage;
        }
        catch (CryptoException e) {
            this.logger.error("Unable to encrypt secret.", (Throwable)e);
            throw new ProvisioningException("Unable to encrypt secret", (Throwable)e);
        }
        catch (WCMException e) {
            this.logger.error("Unable to create configuration.", (Throwable)e);
            throw new ProvisioningException("Unable to create configuration", (Throwable)e);
        }
    }

    private Page createFramework(ResourceResolver resourceResolver, Page parentPage, Map<String, Object> properties) throws ProvisioningException {
        try {
            Resource content;
            PageManager pageManager = (PageManager)resourceResolver.adaptTo(PageManager.class);
            Page frameworkPage = pageManager.create(parentPage.getPath(), "framework", "/libs/cq/analytics/templates/framework", "Provisioned Analytics Framework");
            if (frameworkPage != null && (content = frameworkPage.getContentResource()) != null) {
                Resource publicFramework = content.getChild("public");
                ModifiableValueMap props = (ModifiableValueMap)publicFramework.adaptTo(ModifiableValueMap.class);
                props.put((Object)"reportsuite", properties.get("analytics.reportsuite"));
                props.put((Object)"reportsuites", (Object)(properties.get("analytics.reportsuite") + ";" + "publish"));
                props.put((Object)"cq:visitorNamespace", properties.get("analytics.namespace"));
                props.put((Object)"cq:trackingServer", properties.get("analytics.trackingserver"));
                props.put((Object)"cq:trackingServerSecure", properties.get("analytics.trackingserversecure"));
                Resource mappings = ResourceUtil.getOrCreateResource((ResourceResolver)resourceResolver, (String)(publicFramework.getPath() + "/mappings"), (String)"cq/analytics/components/mappings/maparsys", (String)"cq/analytics/components/mappings/maparsys", (boolean)false);
                if (mappings != null) {
                    HashMap<String, String> vm = new HashMap<String, String>();
                    vm.put("sling:resourceType", "cq/analytics/components/mappings/cqmappings");
                    vm.put("jcr:primaryType", "cq:Component");
                    vm.put("cq:componentPath", "foundation/components/page");
                    vm.put("cq:componentName", "Page");
                    vm.put("cq:componentIcon", "/libs/foundation/components/page/icon.png");
                    ResourceUtil.getOrCreateResource((ResourceResolver)resourceResolver, (String)(mappings.getPath() + "/foundation_components_page"), vm, (String)"cq/analytics/components/mappings/cqmappings", (boolean)true);
                }
            }
            return frameworkPage;
        }
        catch (PersistenceException e) {
            this.logger.error("Unable to create mapping.", (Throwable)e);
            throw new ProvisioningException("Unable to create mapping", (Throwable)e);
        }
        catch (WCMException e) {
            this.logger.error("Unable to create framework.", (Throwable)e);
            throw new ProvisioningException("Unable to create framework", (Throwable)e);
        }
    }

    private boolean isSetup(ResourceResolver resourceResolver, String pageName) {
        String defaultPath = "/etc/cloudservices/sitecatalyst";
        defaultPath = defaultPath + "/" + pageName;
        defaultPath = defaultPath + "/framework";
        return resourceResolver.getResource(defaultPath = defaultPath + "/jcr:content/public/mappings/foundation_components_page") != null;
    }

    private void checkProperties(Map<String, Object> properties, String[] requiredProperties) throws IllegalArgumentException {
        for (String param : requiredProperties) {
            if (properties.get(param) != null) continue;
            throw new IllegalArgumentException("Required property '" + param + "' is missing.");
        }
    }

    private String getValidPageName(String str) {
        return JcrUtil.createValidName((String)str, (String[])JcrUtil.HYPHEN_LABEL_CHAR_MAPPING);
    }

    protected void bindCryptoSupport(CryptoSupport cryptoSupport) {
        this.cryptoSupport = cryptoSupport;
    }

    protected void unbindCryptoSupport(CryptoSupport cryptoSupport) {
        if (this.cryptoSupport == cryptoSupport) {
            this.cryptoSupport = null;
        }
    }

    protected void bindConfigManagerFactory(ConfigurationManagerFactory configurationManagerFactory) {
        this.configManagerFactory = configurationManagerFactory;
    }

    protected void unbindConfigManagerFactory(ConfigurationManagerFactory configurationManagerFactory) {
        if (this.configManagerFactory == configurationManagerFactory) {
            this.configManagerFactory = null;
        }
    }

    protected void bindSitecatalyst(SitecatalystWebservice sitecatalystWebservice) {
        this.sitecatalyst = sitecatalystWebservice;
    }

    protected void unbindSitecatalyst(SitecatalystWebservice sitecatalystWebservice) {
        if (this.sitecatalyst == sitecatalystWebservice) {
            this.sitecatalyst = null;
        }
    }
}