Microsoft Bing Adwords Java Integration

Step 1: Setup Bing BulkServiceManager Configuration

package com.integration.adwords.config;

import com.microsoft.bingads.*;
import com.microsoft.bingads.bulk.BulkServiceManager;
import com.microsoft.bingads.campaignmanagement.ICampaignManagementService;
import com.microsoft.bingads.internal.OAuthService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.MalformedURLException;
import java.net.URL;

/**
 * Created by tmichels on 7/31/15.
 */
@Configuration
public class BingAdwordsConfig {

    @Value("${BING_ADS_CLIENTID}")
    private String bingAdsClientId;

    @Value("${BING_ADS_CLIENT_SECRET}")
    private String bingAdsClientSecret;

    @Value("${BING_ADS_ACCOUNTID}")
    private String bingAdsAccountId;

    @Value("${BING_ADS_CUSTOMERID}")
    private String bingAdsCustomerId;

    @Value("${BING_ADS_DEVELOPER_TOKEN}")
    private String bingAdsDeveloperToken;

    @Value("${BING_ADS_USERNAME}")
    private String bingAdsUsername;

    @Value("${BING_ADS_PASSWORD}")
    private String bingAdsPassword;

    @Value("${BING_ADS_REFRESH_TOKEN}")
    private String bingAdsRefreshToken;


    @Bean
    public OAuthDesktopMobileAuthCodeGrant oAuthWebAuthCodeGrant() throws MalformedURLException {
        OAuthDesktopMobileAuthCodeGrant oAuthWebAuthCodeGrant = new OAuthDesktopMobileAuthCodeGrant(bingAdsClientId, bingAdsRefreshToken);
        return oAuthWebAuthCodeGrant;
    }
    
    @Bean
    public AuthorizationData authorizationData(OAuthDesktopMobileAuthCodeGrant authentication){
        AuthorizationData authorizationData = new AuthorizationData();
        authorizationData.setAuthentication(authentication);
        authorizationData.setCustomerId(new Long(bingAdsCustomerId));
        authorizationData.setAccountId(new Long(bingAdsAccountId));
        authorizationData.setDeveloperToken(bingAdsDeveloperToken);
        return authorizationData;
    }

    @Bean
    public BulkServiceManager bulkServiceManager(AuthorizationData authorizationData){
        BulkServiceManager bulkServiceManager = new BulkServiceManager(authorizationData);
        bulkServiceManager.setStatusPollIntervalInMilliseconds(5000);
        return bulkServiceManager;
    }
}

Step 2: Setup Bing Adwords Service

package com.integration.adwords.service;

import com.microsoft.bingads.AuthorizationData;
import com.microsoft.bingads.bulk.*;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;

/**
 * Created by tmichels on 7/31/15.
 */

@Service
public class BingAdwordService {

    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(BingAdwordService.class);

    private static final String OUTPUTFILENAME="bingAdwords.csv";
    private static final String FILEDIRECTORY="adwords/bing/";

    @Autowired
    BulkServiceManager bulkService;

    public void submitAndDownloadWithBulkServiceManager() throws IOException, URISyntaxException {
        try {
            logger.info("Start BingAdwordService submitAndDownloadWithBulkServiceManager");
            SubmitDownloadParameters submitDownloadParameters = new SubmitDownloadParameters();
            submitDownloadParameters.setCampaignIds(null);
            ArrayList<DataScope> dataScope = new ArrayList<DataScope>();
            dataScope.add(DataScope.ENTITY_DATA);
            submitDownloadParameters.setDataScope(dataScope);
            submitDownloadParameters.setFileType(DownloadFileType.CSV);
            submitDownloadParameters.setLastSyncTimeInUTC(null);
            ArrayList<BulkDownloadEntity> bulkDownloadEntities = new ArrayList<BulkDownloadEntity>();
            bulkDownloadEntities.add(BulkDownloadEntity.CAMPAIGNS);
            bulkDownloadEntities.add(BulkDownloadEntity.AD_GROUPS);
            bulkDownloadEntities.add(BulkDownloadEntity.KEYWORDS);
            bulkDownloadEntities.add(BulkDownloadEntity.ADS);
            submitDownloadParameters.setEntities(bulkDownloadEntities);

            BulkDownloadOperation bulkDownloadOperation = bulkService.submitDownloadAsync(submitDownloadParameters, null).get();

            BulkOperationStatus<DownloadStatus> downloadStatus;
            int waitTime = 5000;

            for (int i = 0; i < 24; i++) {
                Thread.sleep(waitTime);

                downloadStatus = bulkDownloadOperation.getStatusAsync(null).get();

                if (downloadStatus.getStatus() == DownloadStatus.COMPLETED) {
                    break;
                }
            }

            File resultFile = bulkDownloadOperation.downloadResultFileAsync(
                    new File(FILEDIRECTORY),
                    OUTPUTFILENAME,
                    true,
                    true,  // Set this value true if you want to overwrite the same file.
                    null).get();

            logger.info("Download BingAdwords file success %s\n", resultFile.getName());

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

Google Adwords Java Integration

Step 1: Create Google AdwordSession configuration

package com.integration.adwords.config;

import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.client.reporting.ReportingConfiguration;
import com.google.api.ads.common.lib.auth.OfflineCredentials;
import com.google.api.ads.common.lib.exception.OAuthException;
import com.google.api.ads.common.lib.exception.ValidationException;
import com.google.api.client.auth.oauth2.Credential;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by tmichels on 7/31/15.
 */

@Configuration
public class GoogleAdwordsConfig {

    @Value("${GOOGLE_ADWORD_CLIENTID}")
    private String googleAdWordClientId;

    @Value("${GOOGLE_ADWORD_SECRET}")
    private String googleAdwordSecet;

    @Value("${GOOGLE_ADWORDS_DEV_TOKEN}")
    private String googleAdwordDevToken;

    @Value("${GOOGLE_ADWORDS_REFRESH_TOKEN}")
    private String googleAdwordRefreshToken;

    @Value("${GOOGLE_ADWORDS_USER_AGENT}")
    private String googleAdwordUserAgent;

    @Value("${GOOGLE_ADWORDS_CLIENT_CUSTOMER_ID}")
    private String googleAdwordClientCustomerId;

    @Bean
    public Credential credential() throws ValidationException, OAuthException {
        Credential credential = new OfflineCredentials.Builder()
                                .forApi(OfflineCredentials.Api.ADWORDS)
                                .withClientSecrets(googleAdWordClientId, googleAdwordSecet)
                                .withRefreshToken(googleAdwordRefreshToken)
                                .build()
                                .generateCredential();
        return credential;
    }

    @Bean
    public AdWordsSession adWordsSession(Credential credential) throws ValidationException {
        AdWordsSession adWordsSession = new AdWordsSession.Builder()
                                        .withDeveloperToken(googleAdwordDevToken)
                                        .withOAuth2Credential(credential)
                                        .withClientCustomerId(googleAdwordClientCustomerId)
                                        .withUserAgent(googleAdwordUserAgent)


                .build();
        return adWordsSession;
    }
}

2. Create AdWord Service to export KeyWords, Campaigns, AdGroups and Ads.

package com.integration.adwords.service;

import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.utils.v201506.SelectorBuilder;
import com.google.api.ads.adwords.axis.v201506.cm.*;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.selectorfields.v201502.cm.CampaignField;
import com.google.api.ads.adwords.lib.selectorfields.v201506.cm.AdGroupAdField;
import com.google.api.ads.adwords.lib.selectorfields.v201506.cm.AdGroupCriterionField;
import com.google.api.ads.adwords.lib.selectorfields.v201506.cm.AdGroupField;
import com.integration.file.FileConverter;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by tmichels on 7/31/15.
 */

@Service
public class GoogleAdwordService {

    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(GoogleAdwordService.class);

    private static final int PAGE_SIZE = 100;

    private static final String CAMPAIGNFILENAME="adwords/google/googleAdwordCampaign.csv";
    private static final String KEYWORDFILENAME="adwords/google/googleAdwordKeywords.csv";
    private static final String ADGROUPFILENAME="adwords/google/googleAdwordAdGroup.csv";
    private static final String ADSFILENAME="adwords/google/googleAdwordAds.csv";

    @Autowired
    AdWordsSession adWordsSession;

    @Autowired
    FileConverter fileConverter;

    public void getCampaigns() throws RemoteException {
        List<String> campaignColumns = new ArrayList<>();
        List<String> campaignData = new ArrayList<>();

        // Get the CampaignService.
        CampaignServiceInterface campaignService =
                new AdWordsServices().get(adWordsSession, CampaignServiceInterface.class);

        int offset = 0;

        // Create selector.
        SelectorBuilder builder = new SelectorBuilder();
        Selector selector = builder
                .fields(CampaignField.Id,
                        CampaignField.Name,
                        CampaignField.AdServingOptimizationStatus,
                        CampaignField.AdvertisingChannelSubType,
                        CampaignField.AdvertisingChannelType,
                        CampaignField.BiddingStrategyId,
                        CampaignField.BiddingStrategyName,
                        CampaignField.BiddingStrategyType,
                        CampaignField.BidType,
                        CampaignField.BudgetId,
                        CampaignField.BudgetName,
                        CampaignField.BudgetReferenceCount,
                        CampaignField.BudgetStatus,
                        CampaignField.DeliveryMethod,
                        CampaignField.Eligible,
                        CampaignField.EndDate,
                        CampaignField.FrequencyCapMaxImpressions,
                        CampaignField.Labels,
                        CampaignField.StartDate,
                        CampaignField.TrackingUrlTemplate,
                        CampaignField.UrlCustomParameters)
                .orderAscBy(CampaignField.Id)
                .offset(offset)
                .limit(PAGE_SIZE)
                .build();

        campaignColumns.add(CampaignField.Id.toString());
        campaignColumns.add(CampaignField.Name.toString());
        campaignColumns.add(CampaignField.AdServingOptimizationStatus.toString());
        campaignColumns.add(CampaignField.AdvertisingChannelSubType.toString());
        campaignColumns.add(CampaignField.AdvertisingChannelType.toString());
        campaignColumns.add(CampaignField.BiddingStrategyId.toString());
        campaignColumns.add(CampaignField.BiddingStrategyName.toString());
        campaignColumns.add(CampaignField.BiddingStrategyType.toString());
        campaignColumns.add(CampaignField.BidType.toString());
        campaignColumns.add(CampaignField.BudgetId.toString());
        campaignColumns.add(CampaignField.BudgetName.toString());
        campaignColumns.add(CampaignField.BudgetReferenceCount.toString());
        campaignColumns.add(CampaignField.BudgetStatus.toString());
        campaignColumns.add(CampaignField.DeliveryMethod.toString());
        campaignColumns.add(CampaignField.Eligible.toString());
        campaignColumns.add(CampaignField.EndDate.toString());
        campaignColumns.add(CampaignField.FrequencyCapMaxImpressions.toString());
        campaignColumns.add(CampaignField.Labels.toString());
        campaignColumns.add(CampaignField.StartDate.toString());
        campaignColumns.add(CampaignField.TrackingUrlTemplate.toString());
        campaignColumns.add(CampaignField.UrlCustomParameters.toString());

        CampaignPage page = null;
        do {
            // Get all campaigns.
            page = campaignService.get(selector);

            // Display campaigns.
            if (page.getEntries() != null) {
                for (Campaign campaign : page.getEntries()) {
                    campaignData.add(campaign.getId().toString());
                    campaignData.add(campaign.getName());
                    campaignData.add(campaign.getAdServingOptimizationStatus()!=null? campaign.getAdServingOptimizationStatus().toString() : "");
                    campaignData.add(campaign.getAdvertisingChannelSubType() != null ? campaign.getAdvertisingChannelSubType().toString() : "");
                    campaignData.add(campaign.getAdvertisingChannelType().toString());
                    campaignData.add(campaign.getBiddingStrategyConfiguration().getBiddingStrategyId() != null ? campaign.getBiddingStrategyConfiguration().getBiddingStrategyId().toString() : "");
                    campaignData.add(campaign.getBiddingStrategyConfiguration().getBiddingStrategyName());
                    campaignData.add(campaign.getBiddingStrategyConfiguration().getBiddingStrategyType() != null ? campaign.getBiddingStrategyConfiguration().getBiddingStrategyType().getValue() : "");
                    campaignData.add(campaign.getBudget().getBudgetId() != null ? campaign.getBudget().getBudgetId().toString() : "");
                    campaignData.add(campaign.getBudget().getName());
                    campaignData.add(campaign.getBudget().getReferenceCount() != null ? campaign.getBudget().getReferenceCount().toString() : "");
                    campaignData.add(campaign.getBudget().getStatus() != null ? campaign.getBudget().getStatus().getValue() : "");
                    campaignData.add(campaign.getBudget().getDeliveryMethod() != null ? campaign.getBudget().getDeliveryMethod().getValue() : "");
                    campaignData.add(campaign.getBudget().getIsExplicitlyShared() != null ? campaign.getBudget().getIsExplicitlyShared().toString() : "");
                    campaignData.add(campaign.getEndDate());
                    campaignData.add(campaign.getFrequencyCap()!=null && campaign.getFrequencyCap().getImpressions() != null ? campaign.getFrequencyCap().getImpressions().toString() : "");
                    campaignData.add(campaign.getLabels() != null ? campaign.getLabels().toString() : "");
                    campaignData.add(campaign.getStartDate());
                    campaignData.add(campaign.getTrackingUrlTemplate());
                    campaignData.add(campaign.getUrlCustomParameters()!=null &&  campaign.getUrlCustomParameters().getParameters() != null ? campaign.getUrlCustomParameters().getParameters().toString() : "");
                }
            } else {
                logger.info("No campaigns were found.");
            }

            offset += PAGE_SIZE;
            selector = builder.increaseOffsetBy(PAGE_SIZE).build();
        } while (offset < page.getTotalNumEntries());

        fileConverter.convertToCSV(campaignData, campaignColumns, CAMPAIGNFILENAME);
    }

    public void getKeyWords() throws RemoteException {
        List<String> campaignColumns = new ArrayList<>();
        List<String> campaignData = new ArrayList<>();

        // Get the AdGroupCriterionService.
        AdGroupCriterionServiceInterface adGroupCriterionService =
                new AdWordsServices().get(adWordsSession, AdGroupCriterionServiceInterface.class);

        int offset = 0;
        boolean morePages = true;

        // Create selector.
        SelectorBuilder builder = new SelectorBuilder();
        Selector selector = builder
                .fields(
                        AdGroupCriterionField.Id,
                        AdGroupCriterionField.AdGroupId,
                        AdGroupCriterionField.KeywordMatchType,
                        AdGroupCriterionField.KeywordText)
                .offset(offset)
                .limit(PAGE_SIZE)
                .equals(AdGroupCriterionField.CriteriaType, "KEYWORD")
                .build();

        campaignColumns.add(AdGroupCriterionField.Id.toString());
        campaignColumns.add(AdGroupCriterionField.AdGroupId.toString());
        campaignColumns.add(AdGroupCriterionField.KeywordMatchType.toString());
        campaignColumns.add(AdGroupCriterionField.KeywordText.toString());

        while (morePages) {
            AdGroupCriterionPage page = adGroupCriterionService.get(selector);

            if (page.getEntries() != null && page.getEntries().length > 0) {
                for (AdGroupCriterion adGroupCriterionResult : page.getEntries()) {
                    campaignData.add(adGroupCriterionResult.getAdGroupId().toString());
                    campaignData.add(adGroupCriterionResult.getCriterion().getId().toString());
                    campaignData.add(((Keyword) adGroupCriterionResult.getCriterion()).getText());
                    campaignData.add(((Keyword) adGroupCriterionResult.getCriterion()).getMatchType().toString());
                }
            } else {
                logger.info("No keywords were found.");
            }
            offset += PAGE_SIZE;
            selector = builder.increaseOffsetBy(PAGE_SIZE).build();
            morePages = offset < page.getTotalNumEntries();
        }

        fileConverter.convertToCSV(campaignData, campaignColumns, KEYWORDFILENAME);
    }

    public void getTextAds() throws RemoteException {
        List<String> campaignColumns = new ArrayList<>();
        List<String> campaignData = new ArrayList<>();

        AdGroupAdServiceInterface adGroupAdService =
                new AdWordsServices().get(adWordsSession, AdGroupAdServiceInterface.class);

        int offset = 0;
        boolean morePages = true;

        // Create selector.
        SelectorBuilder builder = new SelectorBuilder();
        Selector selector = builder
                .fields(AdGroupAdField.Id,
                        AdGroupAdField.AdGroupId,
                        AdGroupAdField.Status)
                .orderAscBy(AdGroupAdField.Id)
                .offset(offset)
                .limit(PAGE_SIZE)
                .in(AdGroupAdField.Status, "ENABLED", "PAUSED", "DISABLED")
                .build();

        campaignColumns.add(AdGroupAdField.Id.toString());
        campaignColumns.add(AdGroupAdField.AdGroupId.toString());
        campaignColumns.add(AdGroupAdField.Status.toString());

        while (morePages) {
            AdGroupAdPage page = adGroupAdService.get(selector);

            if (page.getEntries() != null && page.getEntries().length > 0) {
                for (AdGroupAd adGroupAd : page.getEntries()) {
                    campaignData.add(adGroupAd.getAd().getId().toString());
                    campaignData.add(adGroupAd.getAd().getAdType().toString());
                    campaignData.add(adGroupAd.getStatus().toString());
                }
            } else {
                logger.info("No text ads were found");
            }

            offset += PAGE_SIZE;
            selector = builder.increaseOffsetBy(PAGE_SIZE).build();
            morePages = offset < page.getTotalNumEntries();
        }

        fileConverter.convertToCSV(campaignData, campaignColumns, ADSFILENAME);

    }
    public void getAdGroups() throws RemoteException {
        List<String> campaignColumns = new ArrayList<>();
        List<String> campaignData = new ArrayList<>();

        AdGroupServiceInterface adGroupService = new AdWordsServices().get(adWordsSession, AdGroupServiceInterface.class);

        int offset = 0;
        boolean morePages = true;

        // Create selector.
        SelectorBuilder builder = new SelectorBuilder();
        Selector selector = builder
                .fields(AdGroupField.Id,
                        AdGroupField.Name,
                        AdGroupField.Status)
                .orderAscBy(AdGroupField.Name)
                .offset(offset)
                .limit(PAGE_SIZE)
                .build();

        campaignColumns.add(AdGroupField.Id.toString());
        campaignColumns.add(AdGroupField.Name.toString());
        campaignColumns.add(AdGroupField.Status.toString());

        while (morePages) {
            AdGroupPage page = adGroupService.get(selector);
            // Display ad groups.
            if (page.getEntries() != null) {
                for (AdGroup adGroup : page.getEntries()) {
                    campaignData.add(adGroup.getId().toString());
                    campaignData.add(adGroup.getName().toString());
                    campaignData.add(adGroup.getStatus()!=null ? adGroup.getStatus().getValue() : "");
                }
            } else {
                logger.info("No group ads were found.");
            }

            offset += PAGE_SIZE;
            selector = builder.increaseOffsetBy(PAGE_SIZE).build();
            morePages = offset < page.getTotalNumEntries();
        }
        fileConverter.convertToCSV(campaignData, campaignColumns, ADGROUPFILENAME);
    }
}

LendingClub Java Client

https://github.com/thysmichels/lendingclub-java-client

The minimum requirements to get started using LendingClub API:
1. Setup wsimport maven plugin
2. Run mvn clean install to generate LendingClub API Java classes from wsdl
3. Create basic LendingClub Main Class
4. Output

1. Setup wsimport maven plugin

         <plugin>
            <groupId>org.jvnet.jax-ws-commons</groupId>
            <artifactId>jaxws-maven-plugin</artifactId>
            <version>2.3</version>
            <executions>
                <execution>
                    <goals>
                        <goal>wsimport</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <wsdlUrls><wsdlUrl>https://www.lendingclub.com/ws/1.4?wsdl</wsdlUrl></wsdlUrls>
                <verbose>true</verbose>
            </configuration>
        </plugin>

2. Run mvn clean install to generate LendingClub API Java classes from wsdl

mvn clean install
...

[INFO] --- jaxws-maven-plugin:2.3:wsimport (default) @ lendingclub-java-client ---
[INFO] Processing: https://www.lendingclub.com/ws/1.4?wsdl
[INFO] jaxws:wsimport args: [-keep, -s, /Users/tmichels/git/lendingclub-java-client/target/generated-sources/wsimport, -d, /Users/tmichels/git/lendingclub-java-client/target/classes, -verbose, -encoding, UTF-8, -Xnocompile, "https://www.lendingclub.com/ws/1.4?wsdl"]
parsing WSDL...



Generating code...

com/lendingclub/ws/BadArgumentException.java
com/lendingclub/ws/BadArgumentExceptionInfo.java
com/lendingclub/ws/BrowseLoansResult.java
com/lendingclub/ws/CreatePortfolioResult.java
com/lendingclub/ws/CreditInfo.java
com/lendingclub/ws/ExcessiveRequestsException.java
com/lendingclub/ws/ExcessiveRequestsExceptionInfo.java
com/lendingclub/ws/GetPortfoliosResult.java
com/lendingclub/ws/HomeOwnership.java
com/lendingclub/ws/IncomeVerification.java
com/lendingclub/ws/InvalidCredentialsException.java
com/lendingclub/ws/InvalidCredentialsExceptionInfo.java
com/lendingclub/ws/LendingClubV14.java
com/lendingclub/ws/LendingClubV14_Service.java
com/lendingclub/ws/LoanBrowseLoans.java
com/lendingclub/ws/LoanBrowseLoansResponse.java
com/lendingclub/ws/LoanGrade.java
com/lendingclub/ws/LoanListing.java
com/lendingclub/ws/LoanPurpose.java
com/lendingclub/ws/LoanSubGrade.java
com/lendingclub/ws/MissingCredentialsException.java
com/lendingclub/ws/MissingCredentialsExceptionInfo.java
com/lendingclub/ws/ObjectFactory.java
com/lendingclub/ws/Order.java
com/lendingclub/ws/OrderConfirmation.java
com/lendingclub/ws/OrderCreatePortfolio.java
com/lendingclub/ws/OrderCreatePortfolioResponse.java
com/lendingclub/ws/OrderExecutionStatus.java
com/lendingclub/ws/OrderGetPortfolios.java
com/lendingclub/ws/OrderGetPortfoliosResponse.java
com/lendingclub/ws/OrderInstruct.java
com/lendingclub/ws/OrderInstructConfirmation.java
com/lendingclub/ws/OrderSubmitOrders.java
com/lendingclub/ws/OrderSubmitOrdersResponse.java
com/lendingclub/ws/Portfolio.java
com/lendingclub/ws/PortfolioResult.java
com/lendingclub/ws/ReviewStatus.java
com/lendingclub/ws/SubmitOrderResult.java
com/lendingclub/ws/SystemGetVersion.java
com/lendingclub/ws/SystemGetVersionResponse.java
com/lendingclub/ws/UnauthorizedWebserviceUserException.java
com/lendingclub/ws/UnauthorizedWebserviceUserExceptionInfo.java
com/lendingclub/ws/VersionInfo.java
com/lendingclub/ws/VersionStatus.java
com/lendingclub/ws/package-info.java

3. Create basic LendingClub Main Class

package com.lendingclub.main;

import com.lendingclub.exception.WebRequestException;
import com.lendingclub.ws.*;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.MessageContext;

/**
 * Created by tmichels on 8/21/14.
 */
public class Main {

   private static final String LENDINGCLUB_API_KEY = "PASTE_YOUR_API_KEY_HERE";

    public static void main(String[] args) throws WebRequestException, UnauthorizedWebserviceUserException, ExcessiveRequestsException, InvalidCredentialsException, MissingCredentialsException {
        final String endpointUrl = "https://api.lendingclub.com:443/ws/1.4";
        Map<String, List<String>> headers = new HashMap<String,List<String>>();
        headers.put("Authorization", Collections.singletonList(LENDINGCLUB_API_KEY));
        LendingClubV14_Service lcSvc = new LendingClubV14_Service();
        LendingClubV14 lcWs = lcSvc.getLendingClubV14Port();
        Map<String, Object> requestContext = ((BindingProvider) lcWs).getRequestContext();
        requestContext.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
        requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointUrl);

        BrowseLoansResult browseLoansResult = lcWs.loanBrowseLoans(true);
        for (LoanListing ll : browseLoansResult.getLoans()){
            System.out.println("Loan: " + ll.getTitle() + " " + ll.getGrade());
        }
    }
}

4. Output

Loan: Debt consolidation B
Loan: Debt consolidation D
Loan: Credit card refinancing A
Loan: Credit card refinancing D

Using LendingClub Java Client library
1. LendingClub API Connection Config
2. LendingClub Client Service
3. LendingClub Client Main Class
4. LendingClub Client Config Test
5. LendingClub Client Tests

1. LendingClub API Connection Config

package com.lendingclub.config;

import com.lendingclub.ws.LendingClubV14;
import com.lendingclub.ws.LendingClubV14_Service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.MessageContext;
import java.util.*;

/**
 * Created by tmichels on 8/21/14.
 */

@Configuration
@PropertySource("classpath:/system.properties")
public class ConnectionConfig {

    @Value("${lendingclub_api_key}")
    private String lendingclubKey;

    @Value("${lendingclub_api_url:https://api.lendingclub.com:443/ws/1.4}")
    private String lendingclubEndpoint;

    @Bean
    public LendingClubV14 lcConnection(){

        Map<String, List<String>> headers = new HashMap<String,List<String>>();
        headers.put("Authorization", Arrays.asList(lendingclubKey));

        LendingClubV14_Service lcSvc = new LendingClubV14_Service();
        LendingClubV14 lcWs = lcSvc.getLendingClubV14Port();
        Map<String, Object> requestContext = ((BindingProvider) lcWs).getRequestContext();

        // 1 minute for connection
        ((BindingProvider) lcWs).getRequestContext().put("com.sun.xml.ws.connect.timeout", 1 * 60 * 1000);
        // 1 minute for request
        ((BindingProvider) lcWs).getRequestContext().put("com.sun.xml.ws.request.timeout", 1 * 60 * 1000);

        requestContext.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
        requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, lendingclubEndpoint);
        return lcWs;
    }
}

2. LendingClub Client Service

@Service
public class LendingClubClient {

    @Autowired
    private LendingClubV14 lcConnection;

    public BrowseLoansResult getLoans(boolean recentlyListed) throws Exception {
        return lcConnection.loanBrowseLoans(!recentlyListed);
    }

    public VersionInfo getSystemVersion() throws ExcessiveRequestsException {
        return lcConnection.systemGetVersion();
    }

    public void submitOrders(List<OrderInstruct> orderInstructList) throws Exception {
        lcConnection.orderSubmitOrders(orderInstructList);
    }

    public GetPortfoliosResult getPortfolios(Long portfolioId) throws Exception {
        return lcConnection.orderGetPortfolios(portfolioId);
    }

    public CreatePortfolioResult orderCreatePortfolio(Portfolio portfolio) throws Exception {
        return lcConnection.orderCreatePortfolio(portfolio);
    }
}

3. LendingClub Client Main Class

public class MainSpring {

    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.scan("com.lendingclub");
        applicationContext.refresh();

        LendingClubClient loanService = applicationContext.getBean(LendingClubClient.class);

        BrowseLoansResult browseLoansResult = loanService.getLoans(true);
        for (LoanListing loanListing : browseLoansResult.getLoans()){
            System.out.println("Loans: " + loanListing.getTitle() + " " + loanListing.getGrade());
        }
    }
}

4. Lending Club Client Config Test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WSConnectionConfig.class, ClientConfig.class} , loader = AnnotationConfigContextLoader.class)
public class ConnectionConfigTest {

    @Autowired
    LendingClubV14 lcConnection;

    @Test
    public void testlcWSConnection() throws ExcessiveRequestsException {
        Assert.assertEquals(lcConnection.systemGetVersion().getNumber(), "1.4");
        Assert.assertEquals(lcConnection.systemGetVersion().getStatus().value(), "ACTIVE");
    }
}

5. Lending Club Client Tests

package com.lendingclub.client;

import com.lendingclub.ClientConfig;
import com.lendingclub.config.WSConnectionConfig;
import com.lendingclub.ws.Order;
import com.lendingclub.ws.OrderInstruct;
import com.lendingclub.ws.Portfolio;
import com.lendingclub.ws.SubmitOrderResult;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.util.Arrays;

/**
 * Created by tmichels on 8/22/14.
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WSConnectionConfig.class, ClientConfig.class, LendingClubClient.class} , loader = AnnotationConfigContextLoader.class)
public class LendingClubClientTest {

    @Autowired
    LendingClubClient lcClient;

    @Test
    public void testGetLoans() throws Exception {
        Assert.assertNotNull(lcClient.getLoans(true));
    }

    @Test
    public void testGetPortfolios() throws Exception {
        Assert.assertNotNull(lcClient.getPortfolios(new Long(6817950)));
    }

    @Test
    public void testOrderCreatePortfolio() throws Exception {
        Portfolio portfolio = new Portfolio();
        portfolio.setAid(new Long(6817950));
        portfolio.setPortfolioDescription("Dummy portfolio description");
        portfolio.setPortfolioName("Dummy portfilio");
        Assert.assertNotNull(lcClient.orderCreatePortfolio(portfolio));
    }

    @Test
    public void testSubmitOrders() throws Exception {
        OrderInstruct orderInstruct = new OrderInstruct();
        orderInstruct.setAid(new Long(6817950));
        lcClient.submitOrders(Arrays.asList(orderInstruct));
    }
}

Dropbox OAuth 2.0 Scribe Java Example

Dropbox OAuthServiceConfig and OAuthServiceProvider Bean

<bean id="dropboxServiceConfig" class="com.example.oauth.OAuthServiceConfig">
		<constructor-arg value="xxx" />
		<constructor-arg value="xxx"/>
		<constructor-arg value="https://www.example.com/oauth/dropbox"/>
		<constructor-arg value="com.example.oauth.DropBoxApi20"/>
	</bean>
	
	<bean id="dropboxServiceProvider" class="com.example.oauth.OAuthServiceProvider">
		<constructor-arg name="config" ref="dropboxServiceConfig" />
	</bean>

Dropbox OAuth Spring MVC Controller

package com.example.oauth.controller;

import static org.springframework.web.context.request.RequestAttributes.SCOPE_SESSION;

import java.util.Map;

import javax.servlet.http.HttpSession;

import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.WebRequest;

import com.example.oauth.OAuthServiceProvider;

@Controller
@RequestMapping("/oauth/dropbox")
public class DropboxController {
	
	@Autowired
	@Qualifier("dropboxServiceProvider")
	private OAuthServiceProvider dropboxServiceProvider;
	
	private static final Token EMPTY_TOKEN = null;
	
	@RequestMapping(value = "/login-dropbox", method = RequestMethod.GET)
	public String loginToDropBox(Map<String, Object> map, WebRequest request) {
		OAuthService service = dropboxServiceProvider.getService();
		String authUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
		System.out.println("RequestToken: " + authUrl);
		return "redirect:" + authUrl;
	}

	@RequestMapping(value = { "" }, method = RequestMethod.GET)
	public String callback(
			@RequestParam(value = "oauth_token", required = false) String oauthToken,
			@RequestParam(value = "code", required = false) String oauthVerifier,
			WebRequest request, Map<String, Object> map) {

		OAuthService service = dropboxServiceProvider.getService();

		// getting access token
		Verifier verifier = new Verifier(oauthVerifier);
		Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);

		// store access token as a session attribute
		request.setAttribute("oauthAccessToken", accessToken, SCOPE_SESSION);

		ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder
				.currentRequestAttributes();
		HttpSession session = attr.getRequest().getSession(false); // create a
																	// new
																	// session
		session.setAttribute("accessToken", accessToken);

		return "settings";
	}
}

DropBoxApi20 extends DefaultApi20

package com.example.oauth;

import org.scribe.builder.api.DefaultApi20;
import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.extractors.JsonTokenExtractor;
import org.scribe.model.OAuthConfig;
import org.scribe.model.Verb;

public class DropBoxApi20 extends DefaultApi20 {

	@Override
	public String getAccessTokenEndpoint() {
		return "https://api.dropbox.com/1/oauth2/token?grant_type=authorization_code";
	}

	@Override
	public String getAuthorizationUrl(OAuthConfig config) {
		// TODO Auto-generated method stub
		return String.format("https://www.dropbox.com/1/oauth2/authorize?client_id=%s&response_type=code&redirect_uri=%s", config.getApiKey(), config.getCallback());
	}

	 @Override
	 public Verb getAccessTokenVerb(){
	       return Verb.POST;
	 }
	 
	@Override
    public AccessTokenExtractor getAccessTokenExtractor() {
        return new JsonTokenExtractor();
    }
}

Google OAuth 2.0 Scribe Java Example

Google OAuthServiceConfig and OAuthServiceProvider Bean

<bean id="gdServiceConfig" class="com.example.oauth.OAuthServiceConfig">
		<constructor-arg value="xxx.apps.googleusercontent.com" />
		<constructor-arg value="xxx"/>
		<constructor-arg value="https://www.example.com/oauth/gd"/>
		<!-- <constructor-arg value="openid profile email https://www.googleapis.com/auth/drive.file"/> -->
		<constructor-arg value="com.example.oauth.GoogleDriveOauthApi"/>
	</bean>
	<bean id="gdServiceProvider" class="com.example.oauth.OAuthServiceProvider">
		<constructor-arg name="config" ref="gdServiceConfig" />
	</bean>
</bean>

Google OAuth Spring MVC Controller

package com.example.oauth.controller;

import static org.springframework.web.context.request.RequestAttributes.SCOPE_SESSION;

import java.util.Map;

import javax.servlet.http.HttpSession;

import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.WebRequest;

import com.example.oauth.OAuthServiceProvider;

@Controller
@RequestMapping("/oauth/gd")
public class GoogleDriveController {

	@Autowired
	@Qualifier("gdServiceProvider")
	private OAuthServiceProvider gdServiceProvider;
	
	private static final Token EMPTY_TOKEN = null;
	
	@RequestMapping(value = "/login-gd", method = RequestMethod.GET)
	public String loginToGoogleDrive(Map<String, Object> map, WebRequest request) {
		OAuthService service = gdServiceProvider.getService();
		String auth = service.getAuthorizationUrl(EMPTY_TOKEN);
		System.out.println("RequestToken: " + auth);
		return "redirect:" + auth;
	}
	
	@RequestMapping(value={""}, method = RequestMethod.GET)
	public String callback(@RequestParam(value="oauth_token", required=false) String oauthToken,
			@RequestParam(value="code", required=false) String oauthVerifier, WebRequest request, Map<String, Object> map) {

		OAuthService service = gdServiceProvider.getService();

		// getting access token
		Verifier verifier = new Verifier(oauthVerifier);
		Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);

		// store access token as a session attribute
		request.setAttribute("oauthAccessToken", accessToken, SCOPE_SESSION);

		ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
		HttpSession session = attr.getRequest().getSession(false); //create a new session
		session.setAttribute("accessToken",accessToken);

		return "settings";
	}
}

Google OAuth extends DefaultApi20

package com.example.oauth;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.scribe.builder.api.DefaultApi20;
import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.model.OAuthConfig;
import org.scribe.model.Verb;
import org.scribe.exceptions.OAuthException;
import org.scribe.model.OAuthConstants;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuth20ServiceImpl;
import org.scribe.oauth.OAuthService;
import org.scribe.utils.OAuthEncoder;
import org.scribe.utils.Preconditions;

public class GoogleDriveOauthApi extends DefaultApi20{

	  private static final String AUTHORIZE_URL = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=%s&redirect_uri=%s";
	    private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s";
	 
	    @Override
	    public String getAccessTokenEndpoint() {
	        return "https://accounts.google.com/o/oauth2/token";
	    }
	    
	    @Override
	    public AccessTokenExtractor getAccessTokenExtractor() {
	        return new AccessTokenExtractor() {
	            
	            @Override
	            public Token extract(String response) {
	                Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string");
	 
	                Matcher matcher = Pattern.compile("\"access_token\" : \"([^&\"]+)\"").matcher(response);
	                if (matcher.find())
	                {
	                  String token = OAuthEncoder.decode(matcher.group(1));
	                  return new Token(token, "", response);
	                } 
	                else
	                {
	                  throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", null);
	                }
	            }
	        };
	    }
	 
	    @Override
	    public String getAuthorizationUrl(OAuthConfig config) {
            return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(),
                    OAuthEncoder.encode(config.getCallback()),
                    OAuthEncoder.encode("openid profile email https://www.googleapis.com/auth/drive.file"));
	    }
	    
	    @Override
	    public Verb getAccessTokenVerb() {
	        return Verb.POST;
	    }
	    
	    @Override
	    public OAuthService createService(OAuthConfig config) {
	        return new GoogleOAuth2Service(this, config);
	    }
	    
	    private class GoogleOAuth2Service extends OAuth20ServiceImpl {
	 
	        private static final String GRANT_TYPE_AUTHORIZATION_CODE = "authorization_code";
	        private static final String GRANT_TYPE = "grant_type";
	        private DefaultApi20 api;
	        private OAuthConfig config;
	 
	        public GoogleOAuth2Service(DefaultApi20 api, OAuthConfig config) {
	            super(api, config);
	            this.api = api;
	            this.config = config;
	        }
	        
	        @Override
	        public Token getAccessToken(Token requestToken, Verifier verifier) {
	            OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
	            switch (api.getAccessTokenVerb()) {
	            case POST:
	                request.addBodyParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
	                request.addBodyParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
	                request.addBodyParameter(OAuthConstants.CODE, verifier.getValue());
	                request.addBodyParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
	                request.addBodyParameter(GRANT_TYPE, GRANT_TYPE_AUTHORIZATION_CODE);
	                break;
	            case GET:
	            default:
	                request.addQuerystringParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
	                request.addQuerystringParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
	                request.addQuerystringParameter(OAuthConstants.CODE, verifier.getValue());
	                request.addQuerystringParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
	                if(config.hasScope()) request.addQuerystringParameter(OAuthConstants.SCOPE, "openid profile email https://www.googleapis.com/auth/drive.file");
	            }
	            Response response = request.send();
	            return api.getAccessTokenExtractor().extract(response.getBody());
	        }
	    }
}

GitHub OAuth 2.0 Scribe Java Example

Github OAuth ServiceConfig and ServiceProvider Bean

<bean id="githubServiceConfig" class="com.example.oauth.OAuthServiceConfig">
		<constructor-arg value="xxx" />
		<constructor-arg value="xxx"/>
		<constructor-arg value="https://www.example.com/oauth/github"/>
		<!--  <constructor-arg value="user,public_repo"/>-->
		<constructor-arg value="com.example.oauth.GithubOauthApi"/>
	</bean>
	<bean id="githubServiceProvider" class="com.example.oauth.OAuthServiceProvider">
		<constructor-arg name="config" ref="githubServiceConfig" />
	</bean>

Github OAuth Spring MVC Controller

package com.example.oauth.controller;

import static org.springframework.web.context.request.RequestAttributes.SCOPE_SESSION;

import java.util.Map;

import javax.servlet.http.HttpSession;

import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;

import com.example.oauth.OAuthServiceProvider;

@Controller
@RequestMapping("/oauth/github")
public class GitHubController {
	
	@Autowired
	@Qualifier("githubServiceProvider")
	private OAuthServiceProvider githubServiceProvider;
	
	private static final Token EMPTY_TOKEN = null;
	
	@RequestMapping(value = "/login-github", method = RequestMethod.GET)
	public String loginToGithub(Map<String, Object> map, WebRequest request) {
		OAuthService service = githubServiceProvider.getService();
		String auth = service.getAuthorizationUrl(EMPTY_TOKEN);
		System.out.println("RequestToken: " + auth);
		return "redirect:" + auth;
	}

	@RequestMapping(value = { "" }, method = RequestMethod.GET)
	public String callback(
			@RequestParam(value = "oauth_token", required = false) String oauthToken,
			@RequestParam(value = "code", required = false) String oauthVerifier,
			WebRequest request, Map<String, Object> map) {

		// getting request token
		OAuthService service = githubServiceProvider.getService();
		Token requestToken = (Token) request.getAttribute("oauthRequestToken",
				SCOPE_SESSION);

		// getting access token
		Verifier verifier = new Verifier(oauthVerifier);
		Token accessToken = service.getAccessToken(requestToken, verifier);

		// store access token as a session attribute
		request.setAttribute("oauthAccessToken", accessToken, SCOPE_SESSION);

		ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder
				.currentRequestAttributes();
		HttpSession session = attr.getRequest().getSession(false); // create a
																	
		session.setAttribute("accessToken", accessToken);

		return "settings";
	}
}

GithubOauthApi extends DefaultApi20

package com.example.oauth;

import org.scribe.builder.api.DefaultApi20;
import org.scribe.model.OAuthConfig;

public class GithubOauthApi extends DefaultApi20{

	private static final String ACCESSTOKEN="https://github.com/login/oauth/access_token";
	
	@Override
	public String getAccessTokenEndpoint() {
		// TODO Auto-generated method stub
		return ACCESSTOKEN;
	}

	@Override
	public String getAuthorizationUrl(OAuthConfig config) {
		// TODO Auto-generated method stub
		return String.format("https://github.com/login/oauth/authorize?client_id=%s&scope=%s&redirect_uri=%s", config.getApiKey(), config.getScope(), config.getCallback());
	}
}

Force.com OAuth 2.0 Scribe Java Example

OAuthServiceConfig and OAuthServiceProvider Bean in ApplicationContext

<bean id="salesforceServiceConfig" class="com.example.oauth.OAuthServiceConfig">
		<constructor-arg value="xxx" />
		<constructor-arg value="xxxx"/>
		<constructor-arg value="https://www.example.com/oauth/salesforce"/>
		<constructor-arg value="com.example.oauth.SalesforceOauthApi"/>
	</bean>
	<bean id="salesforceServiceProvider" class="com.example.oauth.OAuthServiceProvider">
		<constructor-arg name="config" ref="salesforceServiceConfig" />
	</bean>

SalesforceOauthApi extends DefaultApi20

package com.example.oauth;

import org.scribe.builder.api.DefaultApi20;
import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.extractors.JsonTokenExtractor;
import org.scribe.model.OAuthConfig;
import org.scribe.model.Verb;

public class SalesforceOauthApi extends DefaultApi20{

	private static final String ACCESSTOKEN = "https://login.salesforce.com/services/oauth2/token?grant_type=authorization_code";
	
	@Override
	public String getAccessTokenEndpoint() {
		return ACCESSTOKEN;
	}

	@Override
	public String getAuthorizationUrl(OAuthConfig config) {
		return String.format("https://login.salesforce.com/services/oauth2/authorize?client_id=%s&response_type=code&redirect_uri=%s&display=popup&scope=%s", config.getApiKey(), config.getCallback(), "full refresh_token");
	}
	
	 @Override
	 public Verb getAccessTokenVerb(){
	       return Verb.POST;
	 }
	
	@Override
	 public AccessTokenExtractor getAccessTokenExtractor() {
	    return new JsonTokenExtractor();
	 }
}

Spring MVC SalesforceController for requesting access token

package com.example.oauth.controller;

import static org.springframework.web.context.request.RequestAttributes.SCOPE_SESSION;

import java.util.Map;

import javax.servlet.http.HttpSession;

import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.WebRequest;

import com.example.oauth.OAuthServiceProvider;

@Controller
@RequestMapping("/oauth/salesforce")
public class SalesforceController {

	@Autowired
	@Qualifier("salesforceServiceProvider")
	private OAuthServiceProvider salesforceServiceProvider;
	
	private static final Token EMPTY_TOKEN = null;

	@RequestMapping(value = "/login-salesforce", method = RequestMethod.GET)
	public String loginToSalesforce(Map<String, Object> map, WebRequest request) {
		OAuthService service = salesforceServiceProvider.getService();

		String authUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
		System.out.println("RequestToken: " + authUrl);
		return "redirect:" + authUrl;
	}

	@RequestMapping(value = { "" }, method = RequestMethod.GET)
	public String callback(
			@RequestParam(value = "oauth_token", required = false) String oauthToken,
			@RequestParam(value = "code", required = false) String oauthVerifier,
			WebRequest request, Map<String, Object> map) {

		OAuthService service = salesforceServiceProvider.getService();

		// getting access token
		Verifier verifier = new Verifier(oauthVerifier);
		Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);

		// store access token as a session attribute
		request.setAttribute("oauthAccessToken", accessToken, SCOPE_SESSION);

		ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder
				.currentRequestAttributes();
		HttpSession session = attr.getRequest().getSession(false); // create a
																	// new
																	// session
		session.setAttribute("accessToken", accessToken);

		return "settings";
	}
}

New-Relic Add-on for Java Application on Heroku Setup

Add New Relic Agent Dependency

 <dependency>
  	<groupId>com.newrelic.agent.java</groupId>
  	<artifactId>newrelic-agent</artifactId>
  	<version>3.5.1</version>
  	<scope>provided</scope>
</dependency>

pom.xml build tag

  <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
                <version>2.3.2</version>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.2</version>
            </plugin>
            
            <plugin>
				<groupId>com.mysema.maven</groupId>
				<artifactId>apt-maven-plugin</artifactId>
				<version>1.0.8</version>
				<dependencies>
					<dependency>
						<groupId>com.mysema.querydsl</groupId>
						<artifactId>querydsl-apt</artifactId>
						<version>2.9.0</version>
					</dependency>
				</dependencies>
				<executions>
					<execution>
						<phase>generate-sources</phase>
						<goals>
							<goal>process</goal>
						</goals>
						<configuration>
							<outputDirectory>target/generated-sources</outputDirectory>
							<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
						</configuration>
					</execution>
				</executions>
			</plugin>
            
            
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                           <goal>copy</goal>
                        </goals>
                         
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>com.github.jsimone</groupId>
                                    <artifactId>webapp-runner</artifactId>
                                    <version>7.0.22.3</version>
                                    <destFileName>webapp-runner.jar</destFileName>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                   <execution>
         				 <id>copy-new-relic</id>
          					<phase>package</phase>
         				<goals>
          					 <goal>copy-dependencies</goal>
         				 </goals>
         				 <configuration>
           					 <includeGroupIds>com.newrelic.agent.java</includeGroupIds>
           					 <includeArtifactIds>newrelic-agent</includeArtifactIds>
           					 <stripVersion>true</stripVersion>
          					</configuration>
        			</execution>
                </executions>
            </plugin>
        </plugins>
        <pluginManagement>
	<plugins>
    <!-- Ignore/Execute plugin execution -->
    <plugin>
        <groupId>org.eclipse.m2e</groupId>
        <artifactId>lifecycle-mapping</artifactId>
        <version>1.0.0</version>
        <configuration>
            <lifecycleMappingMetadata>
                <pluginExecutions>
                    <!-- copy-dependency plugin -->
                    <pluginExecution>
                        <pluginExecutionFilter>
                            <groupId>org.apache.maven.plugins</groupId>
                            <artifactId>maven-dependency-plugin</artifactId>
                            <versionRange>[1.0.0,)</versionRange>
                            <goals>
                                <goal>copy-dependencies</goal>
                            </goals>
                        </pluginExecutionFilter>
                        <action>
                            <ignore />
                        </action>
                    </pluginExecution>
                </pluginExecutions>
            </lifecycleMappingMetadata>
        </configuration>
    </plugin>
   </plugins></pluginManagement>
        
    </build>
    <name>CloudSole Developer</name>
    <description>CloudSole Developer</description>
    <organization>
    	<name>Thys Michels</name>
    	<url>http://www.thysmichels.com</url>
    </organization>

Create newrelic.yml and save to project route (same level as pom.xml)

.....
license_key: 'OURLICENCEKEYHERE'
....
app_name: CloudSole
....

Add the following flag to your JAVA_OPTS config var on Heroku:

heroku config:set JAVA_OPTS='-Xmx384m -Xss512k -XX:+UseCompressedOops -javaagent:target/dependency/newrelic-agent.jar' NEW_RELIC_APP_NAME="CloudSole"

Java REST Client with Basic Authentication

This Java Client can be used to invoke any RESTful endpoint by proving a baseURL, username and password.

import org.apache.commons.codec.binary.Base64;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

public class RESTInvoker {
    private final String baseUrl;
    private final String username;
    private final String password;

    public RESTInvoker(String baseUrl, String username, String password) {
        this.baseUrl = baseUrl;
        this.username = username;
        this.password = password;
    }

    public String getRESTResponse(String accountId){
       getDataFromServer("account/" + accountId);
    }

    String getDataFromServer(String path) {
        StringBuilder sb = new StringBuilder();
        try {
            URL url = new URL(baseUrl + path);
            URLConnection urlConnection = setUsernamePassword(url);
            BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();

            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private URLConnection setUsernamePassword(URL url) throws IOException {
        URLConnection urlConnection = url.openConnection();
        String authString = username + ":" + password;
        String authStringEnc = new String(Base64.encodeBase64(authString.getBytes()));
        urlConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
        return urlConnection;
    }
}

Parse JSON to POJO using Java

JSON response:

{"restRequest":{"id":1619,"sessionId":"b6f67825-1ed5-43e1-ba5f-1324550f5798",
"loanId":1123456,"creationDate":1392420577000,"knowledgeBaseName":"automation.drl"},
"finalOutcomeStatus":"REVIEW"}

Parsing the JSON to POJO:

private List<RESTResponseModel> restResponseArray = new ArrayList<RESTResponseModel>();
JSONArray jsonResponse = new JSONArray(getJsonResponse());
for (int k = 0; k<jsonResponse.length();k++){
        
    RESTResponseModel dm = new RESTResponseModel();
 	JSONObject restRequest=jsonResponse.getJSONObject(k);

	JSONObject restBody = restRequest.optJSONObject("restRequest");
				
	dm.setId(restBody.optString("id"));
	dm.setSessionId(restBody.optString("sessionId"));
					
	if (new Long(restBody.optLong("creationDate"))!=null){
		Date date = new Date(restBody.optLong("creationDate"));
		dm.setCreationDate(new SimpleDateFormat("MM/dd/yyyy").format(date));
    }
					
	dm.setKnowledgeBaseName(restBody.optString("knowledgeBaseName"));
	dm.setFinalOutcomeStatus(restRequest.optString("finalOutcomeStatus"));
	restResponseArray.add(dm);
}

RESTResponseModel POJO


public class RESTResponseModel {
	
	private String id;
	private String sessionId;
	private String creationDate;
	private String knowledgeBaseName;
	private String finalOutcomeStatus;	
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getSessionId() {
		return sessionId;
	}
	public void setSessionId(String sessionId) {
		this.sessionId = sessionId;
	}
	public String getCreationDate() {
		return creationDate;
	}
	public void setCreationDate(String creationDate) {
		this.creationDate = creationDate;
	}
	public String getKnowledgeBaseName() {
		return knowledgeBaseName;
	}
	public void setKnowledgeBaseName(String knowledgeBaseName) {
		this.knowledgeBaseName = knowledgeBaseName;
	}
	public String getFinalOutcomeStatus() {
		return finalOutcomeStatus;
	}
	public void setFinalOutcomeStatus(String finalOutcomeStatus) {
		this.finalOutcomeStatus = finalOutcomeStatus;
	}
}