com.metabroadcast.common.social.auth.ictomorrow.ICTomorrowApiHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.metabroadcast.common.social.auth.ictomorrow.ICTomorrowApiHelper.java

Source

package com.metabroadcast.common.social.auth.ictomorrow;

import java.io.IOException;
import java.util.List;

import nu.xom.Builder;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Elements;
import nu.xom.ParsingException;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormatterBuilder;

import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.metabroadcast.common.http.FormEncodedPayload;
import com.metabroadcast.common.http.HttpClientBackedSimpleHttpClient;
import com.metabroadcast.common.http.HttpException;
import com.metabroadcast.common.http.HttpResponse;
import com.metabroadcast.common.http.SimpleHttpClientBuilder;
import com.metabroadcast.common.security.UsernameAndPassword;
import com.metabroadcast.common.social.http.HttpClients;

public class ICTomorrowApiHelper {

    private static final String TOKEN_URL = "https://api.ictomorrow.co.uk/v1.0/oauth/access_token";
    private final static String REGISTER_USER_FOR_OFFER_URL_TEMPLATE = "https://api.ictomorrow.co.uk/v1.0/offers/%s/users/%s/register";
    private final static String METER_URL_TEMPLATE = "https://api.ictomorrow.co.uk/v1.0/offers/%s/users/%s/meter";
    private final static String RECORD_CONSUMER_ACTIVITY_URL = "https://api.ictomorrow.co.uk/v1.0/transaction";
    private final static String GET_CONTENT_METADATA_URL = "https://api.ictomorrow.co.uk/v1.0/content/request";
    private final static String GET_METADATA_FILE = "https://api.ictomorrow.co.uk/v1.0/content/get?job_id=%s";
    private final static int METER_OPERATION_INCREMENT = 0;
    private final static int METER_OPERATION_UPDATE_LIMITS = 1;

    private final HttpClientBackedSimpleHttpClient client;
    private final String applicationKey;
    private final String clientSecret;

    public ICTomorrowApiHelper(UsernameAndPassword credentials) {
        this.applicationKey = credentials.username();
        this.clientSecret = credentials.password();

        this.client = new SimpleHttpClientBuilder().withTrustUnverifiedCerts().withPreemptiveBasicAuth(credentials)
                .withUserAgent(HttpClients.PURPLE_USER_AGENT).build();
    }

    private Element getResultElement(HttpResponse res) throws ICTomorrowApiException {
        try {
            Builder builder = new Builder();
            Document document = builder.build(res.body(), null);
            Element rootElement = document.getRootElement();

            String statusCode = rootElement.getAttributeValue("status_code");
            String statusMessage = rootElement.getAttributeValue("status_message");
            if (statusCode.equals("200")) {
                return rootElement;
            } else {
                throw new ICTomorrowApiException("Request returned an error response: " + res.body(), statusCode,
                        statusMessage);
            }
        } catch (ParsingException e) {
            throw new ICTomorrowApiException("Exception while parsing response: " + res.body(), e);
        } catch (IOException e) {
            throw new ICTomorrowApiException("Exception while parsing response: " + res.body(), e);
        }
    }

    private void addOptionalParameter(FormEncodedPayload postData, String paramName, Object paramData) {
        if (paramData != null) {
            postData.withField(paramName, paramData.toString());
        }
    }

    private Integer getOptionalIntegerValue(Element element, String attributeName) {
        if (element.getFirstChildElement(attributeName) != null) {
            return Integer.valueOf(element.getFirstChildElement(attributeName).getValue().trim());
        }
        return null;
    }

    private String getOptionalValue(Element element, String attributeName) {
        if (element.getFirstChildElement(attributeName) != null) {
            return element.getFirstChildElement(attributeName).getValue().trim();
        }
        return null;
    }

    private ICTomorrowMeter parseMeter(Element meterElement) {
        Integer resultConsumerId = getOptionalIntegerValue(meterElement, "consumer_id");
        Integer resultOfferId = getOptionalIntegerValue(meterElement, "offer_id");
        Integer currentNotificationLimit = getOptionalIntegerValue(meterElement, "current_notification_limit");

        Integer lastNotificationLimit = getOptionalIntegerValue(meterElement, "last_notification_limit");

        Integer currentMaxLimit = getOptionalIntegerValue(meterElement, "current_max_limit");
        Integer currentCounterValue = getOptionalIntegerValue(meterElement, "current_counter_value");

        return new ICTomorrowMeter(resultConsumerId, resultOfferId, currentNotificationLimit, lastNotificationLimit,
                currentMaxLimit, currentCounterValue);
    }

    public int checkAccessToken(String code, String callbackUrl) throws ICTomorrowApiException {
        HttpResponse res;
        try {
            FormEncodedPayload data = new FormEncodedPayload().withField("client_id", applicationKey)
                    .withField("redirect_uri", callbackUrl).withField("client_secret", clientSecret)
                    .withField("code", code);
            res = client.post(TOKEN_URL, data);

            Element resultElement = getResultElement(res);
            return Integer.valueOf(resultElement.getFirstChildElement("access_token").getValue().trim());
        } catch (HttpException e) {
            throw new ICTomorrowAuthException("Exception while fetching consumerId", e);
        }
    }

    public boolean registerUserForOffer(int consumerId, int offerId) throws ICTomorrowApiException {
        try {
            HttpResponse res = client.post(registerUserForOfferUrl(consumerId, offerId), new FormEncodedPayload());
            return Boolean.valueOf(getResultElement(res).getFirstChildElement("result").getValue().trim());
        } catch (HttpException e) {
            // Probably already subscribed, check error code when they are more sensible (currently 55 with: 
            // Activity [GENERATE-ERROR-2] failed due to [CONTRACT_ALREADY_EXISTS_AN UNIDENTIFIED EXCEPTION HAS OCCURED. PLEASE REPORT FAULT TO ESB DEVELOPMENT TEAM.]. 
            throw new ICTomorrowApiException("Exception while registering user for offer", e);
        }
    }

    public ICTomorrowIncrementMeterResponse incrementMeter(int consumerId, int offerId, Integer incrementValue,
            String freeText) throws ICTomorrowApiException {
        try {
            FormEncodedPayload data = new FormEncodedPayload().withField("update_type",
                    Integer.toString(METER_OPERATION_INCREMENT));
            addOptionalParameter(data, "increment_value", incrementValue);
            addOptionalParameter(data, "Free_text", freeText);
            HttpResponse res = client.put(meterUrl(consumerId, offerId), data);

            Element resultElement = getResultElement(res);

            Element meterElement = resultElement.getFirstChildElement("meter");

            Boolean incrementGranted = Boolean
                    .valueOf(meterElement.getFirstChildElement("granted").getValue().trim());
            Boolean notificationLimitReached = Boolean
                    .valueOf(meterElement.getFirstChildElement("notificationLimitReached").getValue().trim());
            Boolean maximumLimitReached = Boolean
                    .valueOf(meterElement.getFirstChildElement("maximumLimitReached").getValue().trim());
            //ICTomorrowMeter meter = parseMeter(resultElement);

            return new ICTomorrowIncrementMeterResponse(incrementGranted, notificationLimitReached,
                    maximumLimitReached);
        } catch (HttpException e) {
            throw new ICTomorrowApiException("Exception while incrementing meter", e);
        }
    }

    public ICTomorrowMeter updateMeterLimits(int consumerId, int offerId, Integer notificationUpdateAmount,
            Integer maximumUpdateAmount) throws ICTomorrowApiException {
        try {
            FormEncodedPayload data = new FormEncodedPayload().withField("update_type",
                    Integer.toString(METER_OPERATION_UPDATE_LIMITS));
            addOptionalParameter(data, "notification_update_amount", notificationUpdateAmount);
            addOptionalParameter(data, "maximum_update_amount", maximumUpdateAmount);
            HttpResponse res = client.put(meterUrl(consumerId, offerId), data);

            return parseMeter(getResultElement(res).getFirstChildElement("meter"));
        } catch (HttpException e) {
            throw new ICTomorrowApiException("Exception while updating meter limits", e);
        }
    }

    public ICTomorrowMeter getMeter(int consumerId, int offerId) throws ICTomorrowApiException {
        try {
            HttpResponse res = client.get(meterUrl(consumerId, offerId));

            Element resultElement = getResultElement(res);

            return parseMeter(resultElement.getFirstChildElement("meter"));
        } catch (HttpException e) {
            throw new ICTomorrowApiException("Exception while getting meter", e);
        }
    }

    public int recordConsumerActivity(int consumerId, int offerId, int trialId, String activityType,
            DateTime transactionDate, String contentKey, String contentHandle, Integer incrementValue,
            Integer integerValue, String freeText) throws ICTomorrowApiException {
        try {
            String transactionDateString = transactionDate.toString("yyyy-MM-dd'T'HH:mm:ssZZ");

            FormEncodedPayload data = new FormEncodedPayload()
                    .withField("consumer_id", Integer.toString(consumerId))
                    .withField("offer_id", Integer.toString(offerId)).withField("application_key", applicationKey)
                    .withField("trial_id", Integer.toString(trialId)).withField("activity_type", activityType)
                    .withField("transaction_date", transactionDateString);

            addOptionalParameter(data, "content_handle", contentHandle);
            addOptionalParameter(data, "content_key", contentKey);
            addOptionalParameter(data, "increment_value", incrementValue);
            addOptionalParameter(data, "integer_value", integerValue);
            addOptionalParameter(data, "free_text", freeText);
            HttpResponse res = client.post(RECORD_CONSUMER_ACTIVITY_URL, data);
            Element resultElement = getResultElement(res);
            return Integer.valueOf(resultElement.getFirstChildElement("transaction")
                    .getFirstChildElement("TransactionID").getValue().trim());
        } catch (HttpException e) {
            throw new ICTomorrowApiException("Exception while recording consumer activity", e);
        }
    }

    public int getContentMetadata(Integer csaId, Integer wholesaleOfferId, Integer consumerOfferID)
            throws ICTomorrowApiException {
        try {
            FormEncodedPayload data = new FormEncodedPayload();

            addOptionalParameter(data, "csa_id", csaId);
            addOptionalParameter(data, "wholesale_offer_id", wholesaleOfferId);
            addOptionalParameter(data, "consumer_offer_id", consumerOfferID);
            Element resultElem = getResultElement(client.post(GET_CONTENT_METADATA_URL, data));
            return Integer.valueOf(resultElem.getValue().trim());
        } catch (HttpException e) {
            throw new ICTomorrowApiException("Exception while recording consumer activity", e);
        }
    }

    public List<ICTomorrowItemMetadata> getMetadataFile(int jobId) throws ICTomorrowApiException {
        try {
            Element resultElement = getResultElement(client.get(getMetadataFileUrl(jobId)));

            String jobStatus = resultElement.getFirstChildElement("job_status").getValue().trim();

            if ("COMPLETE".equals(jobStatus)) {
                Element downloadElement = resultElement.getFirstChildElement("Download");

                List<ICTomorrowItemMetadata> items = Lists.newArrayList();
                Elements itemElements = downloadElement.getFirstChildElement("Items").getChildElements("Item");
                for (int i = 0; i < itemElements.size(); i++) {
                    items.add(getItem(itemElements.get(i)));
                }

                return items;
            } else if ("FAILED".equals(jobStatus)) {
                throw new ICTomorrowApiException("Metadata file creation failed");
            }

            return null;
        } catch (HttpException e) {
            throw new ICTomorrowApiException("Exception while recording consumer activity", e);
        }
    }

    private String getCharacteristic(Element itemElement, String characteristicName) {
        Elements characteristics = itemElement.getChildElements("Characteristic");
        for (int i = 0; i < characteristics.size(); i++) {
            Element currentElement = characteristics.get(i);
            String nameAttribute = currentElement.getAttributeValue("Name");
            if (characteristicName.equals(nameAttribute)) {
                return currentElement.getAttributeValue("Value");
            }
        }
        return null;
    }

    private ICTomorrowItemMetadata getItem(Element itemElement) {
        Integer contentHandle = Integer.valueOf(itemElement.getAttributeValue("ContentHandle"));
        String contentKey = itemElement.getFirstChildElement("Key").getValue().trim();

        ICTomorrowItemMetadata item = new ICTomorrowItemMetadata(contentHandle, contentKey);

        item.setChannelTitle(getCharacteristic(itemElement, "Channel-Title"));
        String link = getCharacteristic(itemElement, "Link");
        if (link == null) {
            link = getCharacteristic(itemElement, "URL Location");
        }
        item.setLink(link);
        item.setSource(getCharacteristic(itemElement, "Source"));
        item.setWebmaster(getCharacteristic(itemElement, "WebMaster"));
        item.setTitle(getOptionalValue(itemElement, "Title"));
        item.setContentProvider(getOptionalValue(itemElement, "ContentProvider"));
        item.setLicenceTemplateName(getOptionalValue(itemElement, "LicenseTemplateName"));

        String keywords = getCharacteristic(itemElement, "Keywords");
        if (keywords != null) {
            item.setKeywords(
                    ImmutableSet.copyOf(Splitter.on(",").trimResults().omitEmptyStrings().split(keywords)));
        }

        String dateString = getCharacteristic(itemElement, "Pub-date");
        if (dateString != null) {
            DateTimeFormatter dateParser = new DateTimeFormatterBuilder().appendDayOfWeekShortText()
                    .appendLiteral(", ").appendDayOfMonth(2).appendLiteral(" ").appendMonthOfYearShortText()
                    .appendLiteral(" ").appendYear(4, 4).appendLiteral(" ").appendHourOfDay(2).appendLiteral(":")
                    .appendMinuteOfHour(2).appendLiteral(":").appendSecondOfMinute(2).appendLiteral(" GMT")
                    .toFormatter();
            //DateTimeFormat.forPattern("E, dd MM yyyy HH:mm:ss z");

            DateTime date = dateParser.parseDateTime(dateString);

            item.setPublishedDate(date);
        }

        return item;
    }

    private String registerUserForOfferUrl(int consumerId, int offerId) {
        return String.format(REGISTER_USER_FOR_OFFER_URL_TEMPLATE, offerId, consumerId);
    }

    private String meterUrl(int consumerId, int offerId) {
        return String.format(METER_URL_TEMPLATE, offerId, consumerId);
    }

    private String getMetadataFileUrl(int jobId) {
        return String.format(GET_METADATA_FILE, jobId);
    }
}