TargetProvisioningHandler.java 17.4 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.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.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.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={"target"})})
public class TargetProvisioningHandler
implements ProvisioningHandler {
    protected static final String PROPERTY_CLIENTCODE = "target.clientcode";
    protected static final String PROPERTY_EMAIL = "target.email";
    protected static final String PROEPRTY_PASSWORD = "target.password";
    private static final String DEFAULT_SERVICE_PATH = "/etc/cloudservices/testandtarget";
    private static final String DEFAULT_CONFIG_TEMPLATE = "/libs/cq/analytics/templates/testandtarget";
    private static final String DEFAULT_CONFIG_TITLE = "Provisioned Target Configuration";
    private static final String DEFAULT_FRAMEWORK_TEMPLATE = "/libs/cq/analytics/templates/tntframework";
    private static final String DEFAULT_FRAMEWORK_TITLE = "Provisioned Target Framework";
    private static final String DEFAULT_FRAMEWORK_NAME = "framework";
    private static final String SEGMENTS_POLL_CONFIG_NAME = "segmentsPollConfig";
    private static final String ACCOUNT_OPTIONS_UPDATER_POLL_CONFIG_NAME = "accountOptionsUpdatePollConfig";
    private static final String PUBLIC_NAME = "public";
    private static final String MAPPINGS_SLING_RT = "cq/analytics/components/mappings/maparsys";
    private static final String CQMAPPINGS_SLING_RT = "cq/analytics/components/mappings/cbmappings";
    private final Logger logger;
    @Reference
    private CryptoSupport cryptoSupport;
    @Reference
    private ConfigurationManagerFactory configManagerFactory;

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

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

    @Override
    public void rollback(ResourceResolver resourceResolver, Map<String, Object> properties) {
        String pageName = this.getValidPageName((String)properties.get("target.clientcode"));
        try {
            Resource failedConfiguration = resourceResolver.getResource("/etc/cloudservices/testandtarget/" + 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("testandtarget", 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]));
            ++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 Page createConfiguration(ResourceResolver resourceResolver, String pageName, Map<String, Object> properties) throws ProvisioningException {
        Page clientCodePage = this.getOrCreateConfigurationPage(resourceResolver, pageName, properties);
        return this.createFramework(resourceResolver, clientCodePage);
    }

    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/testandtarget/" + pageName);
            if (companyPage == null && (content = (companyPage = pageManager.create("/etc/cloudservices/testandtarget", pageName, "/libs/cq/analytics/templates/testandtarget", "Provisioned Target Configuration")).getContentResource()) != null) {
                Resource publicConfig;
                Resource accountOptionsPollConfig;
                ModifiableValueMap vm = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
                vm.put((Object)"apiKind", (Object)"REST");
                vm.put((Object)"email", properties.get("target.email"));
                String password = (String)properties.get("target.password");
                vm.put((Object)"password", (Object)this.cryptoSupport.protect(password));
                Resource segmentsPollConfig = resourceResolver.getResource(content, "segmentsPollConfig");
                if (segmentsPollConfig == null) {
                    HashMap<String, Object> pollConfigProps = new HashMap<String, Object>();
                    pollConfigProps.put("jcr:mixinTypes", new String[]{"cq:PollConfig"});
                    pollConfigProps.put("enabled", true);
                    pollConfigProps.put("interval", 1200);
                    pollConfigProps.put("source", "adobe-target-segments:" + companyPage.getPath());
                    pollConfigProps.put("target", "/etc/segmentation/adobe-target/" + properties.get("target.clientcode"));
                    resourceResolver.create(content, "segmentsPollConfig", pollConfigProps);
                }
                if ((accountOptionsPollConfig = resourceResolver.getResource(content, "accountOptionsUpdatePollConfig")) == null) {
                    HashMap<String, Object> optionsPollConfigProps = new HashMap<String, Object>();
                    optionsPollConfigProps.put("jcr:mixinTypes", new String[]{"cq:PollConfig"});
                    optionsPollConfigProps.put("enabled", true);
                    optionsPollConfigProps.put("interval", 86400);
                    optionsPollConfigProps.put("source", "adobe-target-account-options:" + companyPage.getPath());
                    optionsPollConfigProps.put("target", companyPage.getPath());
                    resourceResolver.create(content, "accountOptionsUpdatePollConfig", optionsPollConfigProps);
                }
                if ((publicConfig = resourceResolver.getResource(content, "public")) == null) {
                    HashMap<String, Object> publicProps = new HashMap<String, Object>();
                    publicProps.put("clientcode", properties.get("target.clientcode"));
                    publicProps.put("accurateTargeting", true);
                    resourceResolver.create(content, "public", publicProps);
                }
            }
            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);
        }
        catch (PersistenceException e) {
            this.logger.error("Unable to create the segments poll configuration.", (Throwable)e);
            throw new ProvisioningException("Unable to create the segments poll configuration", (Throwable)e);
        }
    }

    private Page createFramework(ResourceResolver resourceResolver, Page parentPage) throws ProvisioningException {
        try {
            Resource content;
            Resource mappings;
            PageManager pageManager = (PageManager)resourceResolver.adaptTo(PageManager.class);
            Page frameworkPage = pageManager.create(parentPage.getPath(), "framework", "/libs/cq/analytics/templates/tntframework", "Provisioned Target Framework");
            if (frameworkPage != null && (content = frameworkPage.getContentResource()) != null && (mappings = ResourceUtil.getOrCreateResource((ResourceResolver)resourceResolver, (String)(content.getPath() + "/" + "public" + "/mappings"), (String)"cq/analytics/components/mappings/maparsys", (String)"cq/analytics/components/mappings/maparsys", (boolean)false)) != null) {
                HashMap<String, String> vm = new HashMap<String, String>();
                vm.put("sling:resourceType", "cq/analytics/components/mappings/cbmappings");
                vm.put("jcr:primaryType", "cq:Component");
                vm.put("cq:componentPath", "cq/personalization/components/contextstores/profiledata");
                vm.put("cq:componentName", "Profile Data");
                vm.put("cq:componentIcon", "/libs/cq/ui/widgets/themes/default/icons/16x16/components.png");
                vm.put("profile.age", "profile.age");
                vm.put("profile.gender", "profile.gender");
                ResourceUtil.getOrCreateResource((ResourceResolver)resourceResolver, (String)(mappings.getPath() + "/cq_personalization_components_contextstores_profiledata"), vm, (String)"cq/analytics/components/mappings/cbmappings", (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/testandtarget";
        defaultPath = defaultPath + "/" + pageName;
        defaultPath = defaultPath + "/framework";
        return resourceResolver.getResource(defaultPath = defaultPath + "/jcr:content/mappings/cq_personalization_components_contextstores_profiledata") != 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;
        }
    }
}