TargetRecommendationsAPIClientImpl.java 20.5 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.analytics.testandtarget.TestandtargetHttpClient
 *  com.day.cq.analytics.testandtarget.TestandtargetHttpClient$TestandtargetMethodType
 *  com.day.cq.analytics.testandtarget.TestandtargetHttpClient$TestandtargetSolution
 *  com.day.cq.analytics.testandtarget.TestandtargetHttpParameters
 *  com.day.cq.wcm.webservicesupport.Configuration
 *  org.apache.commons.httpclient.util.EncodingUtil
 *  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.commons.json.JSONArray
 *  org.apache.sling.commons.json.JSONObject
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.targetrecommendations.impl;

import com.adobe.cq.targetrecommendations.api.TargetRecommendationsAPIClient;
import com.adobe.cq.targetrecommendations.api.TargetRecommendationsException;
import com.adobe.cq.targetrecommendations.api.model.ProductFeed;
import com.adobe.cq.targetrecommendations.api.model.RecommendationAlgorithm;
import com.adobe.cq.targetrecommendations.api.model.RecommendationMbox;
import com.adobe.cq.targetrecommendations.api.model.RecommendationTemplate;
import com.adobe.cq.targetrecommendations.api.model.TargetRecommendation;
import com.adobe.cq.targetrecommendations.impl.model.RecommendationMboxImpl;
import com.adobe.cq.targetrecommendations.impl.util.TargetRecommendationsJSONUtil;
import com.adobe.granite.crypto.CryptoException;
import com.adobe.granite.crypto.CryptoSupport;
import com.day.cq.analytics.testandtarget.TestandtargetHttpClient;
import com.day.cq.analytics.testandtarget.TestandtargetHttpParameters;
import com.day.cq.wcm.webservicesupport.Configuration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.httpclient.util.EncodingUtil;
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.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(label="Adobe AEM Target Recommendations API Client", description="Provides AEM support for calling Target Recommendations REST APIs")
@Service
@Properties(value={@Property(name="service.description", value={"Adobe AEM Target Recommendations API Client"})})
public class TargetRecommendationsAPIClientImpl
implements TargetRecommendationsAPIClient {
    @Reference
    private TestandtargetHttpClient testTargetClient;
    @Reference
    private CryptoSupport cryptoSupport;
    private static final String TEMPLATES_ENDPOINT_SUFFIX = "templates";
    private static final String MBOXES_ENDPOINT_SUFFIX = "mboxes";
    private static final String ALGORITHM_ENDPOINT_SUFFIX = "algorithms";
    private static final String RECOMMENDATIONS_ENDPOINT_SUFFIX = "recommendations";
    private static final String FEEDS_ENDPOINT_SUFFIX = "feeds";
    private static final String ENTITIES_ENDPOINT_SUFFIX = "entities";
    private static final Logger LOG = LoggerFactory.getLogger(TargetRecommendationsAPIClientImpl.class);

    @Override
    public List<RecommendationTemplate> getTemplates(Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String templatesResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.GET, ttConfig, "/templates", null);
            return TargetRecommendationsJSONUtil.parseTemplates(templatesResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't get a list of templates from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public RecommendationTemplate getTemplate(int id, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String singleTemplateResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.GET, ttConfig, "/templates/" + id, null);
            List<RecommendationTemplate> templates = TargetRecommendationsJSONUtil.parseTemplates(singleTemplateResponse);
            if (templates.size() >= 1) {
                return templates.get(0);
            }
            return null;
        }
        catch (Exception e) {
            LOG.debug("Can't get template with id " + id + " from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public RecommendationTemplate saveTemplate(RecommendationTemplate template, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String templateSaveResponse = "";
            templateSaveResponse = template.getId() <= 0 ? this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.POST, ttConfig, "/templates", template.toJson()) : this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.PUT, ttConfig, "/templates/" + template.getId(), template.toJson());
            return TargetRecommendationsJSONUtil.parseTemplate(templateSaveResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't save template on Target Recommendations backend!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public void deleteTemplate(int id, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String templateDeleteResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.DELETE, ttConfig, "/templates/" + id, null);
            TargetRecommendationsJSONUtil.parseTemplate(templateDeleteResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't delete template with id " + id + " from Target Recommendations backend!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public List<RecommendationMbox> getMBoxes(Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String mboxListResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.GET, ttConfig, "/mboxes", null);
            List<String> mboxNames = TargetRecommendationsJSONUtil.getJsonArrayPropValues(mboxListResponse, "name");
            ArrayList<RecommendationMbox> mboxList = new ArrayList<RecommendationMbox>();
            for (String mboxName : mboxNames) {
                mboxList.add(new RecommendationMboxImpl(mboxName));
            }
            return mboxList;
        }
        catch (Exception e) {
            LOG.debug("Can't get the MBox list from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public List<RecommendationAlgorithm> getAlgorithms(Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String algorithmsResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.GET, ttConfig, "/algorithms", null);
            return TargetRecommendationsJSONUtil.parseAlgorithms(algorithmsResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't get the algorithm list from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public RecommendationAlgorithm getAlgorithm(int id, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String algorithmResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.GET, ttConfig, "/algorithms/" + id, null);
            return TargetRecommendationsJSONUtil.parseAlgorithm(algorithmResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't get algorithm with id " + id + " from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public RecommendationAlgorithm saveAlgorithm(RecommendationAlgorithm algorithm, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String algSaveResponse = "";
            algSaveResponse = algorithm.getId() <= 0 ? this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.POST, ttConfig, "/algorithms", algorithm.toJson()) : this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.PUT, ttConfig, "/algorithms/" + algorithm.getId(), algorithm.toJson());
            return TargetRecommendationsJSONUtil.parseAlgorithm(algSaveResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't save algorithm on Target Recommendations backend!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public void deleteAlgorithm(int id, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String algorithmDeleteResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.DELETE, ttConfig, "/algorithms/" + id, null);
            TargetRecommendationsJSONUtil.parseAlgorithm(algorithmDeleteResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't delete algorithm with id " + id + " from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public List<TargetRecommendation> getRecommendations(Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String allRecommendationsResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.GET, ttConfig, "/recommendations", null);
            return TargetRecommendationsJSONUtil.parseRecommendations(allRecommendationsResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't get recommendations list from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public TargetRecommendation getRecommendation(int id, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String getRecommendationResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.GET, ttConfig, "/recommendations/" + id, null);
            return TargetRecommendationsJSONUtil.parseRecommendation(getRecommendationResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't get recommendation with id " + id + " from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public TargetRecommendation saveRecommendation(TargetRecommendation recommendation, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String recSaveResponse = "";
            recSaveResponse = recommendation.getId() <= 0 ? this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.POST, ttConfig, "/recommendations", recommendation.toJson()) : this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.PUT, ttConfig, "/recommendations/" + recommendation.getId(), recommendation.toJson());
            return TargetRecommendationsJSONUtil.parseRecommendation(recSaveResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't save algorithm on Target Recommendations backend!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public void deleteRecommendation(int id, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String recommendationDeleteResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.DELETE, ttConfig, "/recommendations/" + id, null);
            TargetRecommendationsJSONUtil.parseRecommendation(recommendationDeleteResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't delete algorithm with id " + id + " from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public List<ProductFeed> getFeeds(Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String allFeedsResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.GET, ttConfig, "/feeds", null);
            return TargetRecommendationsJSONUtil.parseFeeds(allFeedsResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't get feed list from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public ProductFeed getFeed(int id, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String getFeedResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.GET, ttConfig, "/feeds/" + id, null);
            return TargetRecommendationsJSONUtil.parseFeed(getFeedResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't get feed with id " + id + " from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public ProductFeed saveFeed(ProductFeed feed, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String feedSaveResponse = "";
            feedSaveResponse = feed.getId() <= 0 ? this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.POST, ttConfig, "/feeds", feed.toJson()) : this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.PUT, ttConfig, "/feeds/" + feed.getId(), feed.toJson());
            return TargetRecommendationsJSONUtil.parseFeed(feedSaveResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't save feed on Target Recommendations backend!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public void deleteFeed(int id, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            String feedDeleteResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.DELETE, ttConfig, "/feeds/" + id, null);
            TargetRecommendationsJSONUtil.parseFeed(feedDeleteResponse);
        }
        catch (Exception e) {
            LOG.debug("Can't delete feed with id " + id + " from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public void removeProducts(List<String> productList, Configuration ttConfig) throws TargetRecommendationsException {
        try {
            StringBuilder removedProductIds = new StringBuilder();
            for (String productId : productList) {
                removedProductIds.append(productId);
                removedProductIds.append(",");
            }
            if (removedProductIds.length() > 0) {
                removedProductIds.deleteCharAt(removedProductIds.length() - 1);
                LOG.debug("Removing products: " + removedProductIds.toString());
                HashMap<String, String> queryParams = new HashMap<String, String>();
                queryParams.put("entityIds", removedProductIds.toString());
                String entityRemovalResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.DELETE, ttConfig, "/entities", null);
                TargetRecommendationsJSONUtil.convertToJson(entityRemovalResponse);
                LOG.debug("Successfully removed products from recommendations index of configuration " + ttConfig.getPath());
            } else {
                LOG.debug("No products to remove from Target Recommendations!");
            }
        }
        catch (Exception e) {
            LOG.debug("Can't delete product entities from Target Recommendations!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    @Override
    public void checkConnection(String clientCode, String email, String password) throws TargetRecommendationsException {
        try {
            String templatesResponse = this.executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType.GET, email, password, clientCode, "/templates", new HashMap<String, String>(), null);
            TargetRecommendationsJSONUtil.parseTemplates(templatesResponse);
        }
        catch (Exception e) {
            LOG.debug("Connection check to Target Recommendations failed!", (Throwable)e);
            throw new TargetRecommendationsException(e);
        }
    }

    private String executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType method, Configuration ttConfig, String commandSuffix, String requestEntity) throws Exception {
        return this.executeRecommendationsRestCall(method, ttConfig, commandSuffix, new HashMap<String, String>(), requestEntity);
    }

    private String executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType method, Configuration ttConfig, String commandSuffix, Map<String, String> queryParameters, String requestEntity) throws Exception {
        String email = (String)ttConfig.getInherited("email", (Object)"");
        String password = this.getPassword(ttConfig);
        String clientCode = (String)ttConfig.getInherited("clientcode", (Object)"");
        return this.executeRecommendationsRestCall(method, email, password, clientCode, commandSuffix, queryParameters, requestEntity);
    }

    private String executeRecommendationsRestCall(TestandtargetHttpClient.TestandtargetMethodType method, String email, String password, String clientCode, String commandSuffix, final Map<String, String> queryParameters, final String requestEntity) throws Exception {
        String callResponse = "";
        queryParameters.put("email", email);
        queryParameters.put("password", password);
        callResponse = this.testTargetClient.executeRestCall(method, clientCode, commandSuffix + ".json", TestandtargetHttpClient.TestandtargetSolution.RECOMMENDATIONS, new TestandtargetHttpParameters(){

            public Map<String, String> getQueryParameters() {
                return queryParameters;
            }

            public String getEntityContentType() {
                return "application/json";
            }

            public byte[] getEntityContent() {
                return EncodingUtil.getAsciiBytes((String)requestEntity);
            }
        });
        this.checkErrorResponse(callResponse);
        return callResponse;
    }

    private void checkErrorResponse(String responseMessage) throws TargetRecommendationsException {
        if (responseMessage.contains("error.restapi")) {
            String errorMessage = "";
            try {
                JSONObject errorResponse = new JSONObject(responseMessage);
                errorMessage = errorResponse.getJSONArray("messages").getJSONObject(0).getString("text");
            }
            catch (Exception e) {
                LOG.debug("Can't parse recommendations error message!", (Throwable)e);
            }
            throw new TargetRecommendationsException(errorMessage);
        }
    }

    private String getPassword(Configuration configuration) throws CryptoException {
        String password = (String)configuration.getInherited("password", (Object)"");
        return this.cryptoSupport.isProtected(password) ? this.cryptoSupport.unprotect(password) : password;
    }

    protected void bindTestTargetClient(TestandtargetHttpClient testandtargetHttpClient) {
        this.testTargetClient = testandtargetHttpClient;
    }

    protected void unbindTestTargetClient(TestandtargetHttpClient testandtargetHttpClient) {
        if (this.testTargetClient == testandtargetHttpClient) {
            this.testTargetClient = null;
        }
    }

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

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

}