Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2012 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.cq.mcm.salesforce;
import org.apache.commons.lang3.CharEncoding;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.osgi.services.HttpClientBuilderFactory;
import org.apache.http.util.EntityUtils;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* The SalesforceClient uses the Salesforce REST API to authenticate and query Salesforce.
* */
public class SalesforceClient {
public static final String INVALID_CLIENT_ID = "invalid_client_id";
public static final String INVALID_CLIENT = "invalid_client";
public static final String CLIENT_ID = "client_id";
public static final String CLIENT_SECRET = "client_secret";
public static final String REFRESH_ACCESS_TOKEN_ENDPOINT = "/services/oauth2/token";
public static final String APPLICATION_FORMURL_ENCODED = "application/x-www-form-urlencoded";
public static final String GRANT_TYPE = "grant_type";
public static final String REFRESH_TOKEN = "refresh_token";
final protected int HTTP_CODE_REFRESH_TOKEN_SUCCESS = 200;
public enum AvailableMethods {GET, POST, PATCH};
protected String clientId = "";
protected String clientSecret = "";
protected String instanceURL = "";
protected String path = "";
protected String accessToken = "";
protected String refreshToken = "";
protected String contentType = "";
protected String data = "";
protected HttpClientBuilderFactory clientBuilderFactory = null;
protected AvailableMethods method;
protected HashMap parameters = new HashMap();
private final Logger logger = LoggerFactory.getLogger(SalesforceClient.class);
/**
* Returns the Client Identifier.
* */
public String getClientId() {
return clientId;
}
/**
* Sets the Client Identifier. Also add into the data if not already present.
* */
public void setClientId(String clientId) {
this.clientId = clientId;
if(!data.contains(CLIENT_ID)){
addData(CLIENT_ID, clientId);
}
}
/**
* Returns the Client Secret.
* */
public String getClientSecret() {
return clientSecret;
}
/**
* Sets the Client Secret. Also add into the data if not already present.
* */
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
if(!data.contains(CLIENT_SECRET)){
addData(CLIENT_SECRET, clientSecret);
}
}
/**
* Returns the URL encoded parameters used for REST Api calls as a String.
* */
public String getData() {
return data;
}
/**
* Adds a key-value pair to parameters list
* */
public void addData(String key, String value) {
addData(key, value, true);
}
/**
* Adds a key-value pair to parameters list with an option not to encode the parameters
* */
public void addData(String key, String value, boolean encode) {
if (!this.data.equals("")) {
this.data += "&";
}
try {
this.data += key + "=" + (encode ? URLEncoder.encode(value, CharEncoding.UTF_8) : value);
} catch (UnsupportedEncodingException e) {
logger.error("Exception in adding data to Salesforce Client: "+e.getMessage());
}
}
/**
* Set the URL encoded parameters used for REST Api calls as a Map of key-value pairs.
* */
public void setData(Map data) {
this.data = "";
Iterator it = data.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry) it.next();
try {
this.data += pairs.getKey() + "=" + URLEncoder.encode(((String) pairs.getValue()), CharEncoding.UTF_8);
} catch (UnsupportedEncodingException e) {
logger.error("Exception in adding data to Salesforce Client: " + e.getMessage());
}
if (it.hasNext()) {
this.data += "&";
}
}
}
/**
* Set the URL encoded parameters used for REST Api calls as a String.
* */
public void setData(String data) {
this.data = data;
}
/**
* Returns the Instance URL for the Salesforce configuration
* */
public String getInstanceURL() {
return instanceURL;
}
/**
* Sets the Instance URL for the Salesforce configuration
* */
public void setInstanceURL(String instanceURL) {
this.instanceURL = instanceURL;
}
/**
* Returns the current REST API endpoint
* */
public String getPath() {
return path;
}
/**
* Sets the current REST API endpoint
* */
public void setPath(String path) {
this.path = path;
}
/**
* Returns the Access Token
* */
public String getAccessToken() {
return accessToken;
}
/**
* Sets the Access Token
* */
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
/**
* Returns the Refresh Token
* */
public String getRefreshToken() {
return refreshToken;
}
/**
* Sets the Refresh Token
* */
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
/**
* Returns the Content-Type of the Request
* */
public String getContentType() {
return contentType;
}
/**
* Sets the Content-Type of the Request
* */
public void setContentType(String contentType) {
this.contentType = contentType;
}
/**
* Returns the HTTP Method used in the Current Request. Will be one of the {@link AvailableMethods}
* */
public AvailableMethods getMethod() {
return method;
}
/**
* Sets the HTTP Method used in the Current Request. Will be one of the {@link AvailableMethods}
* */
public void setMethod(AvailableMethods method) {
this.method = method;
}
/**
* Sets the HTTP Method as a String to be used in Current Request
* */
public void setStringMethod(String method) {
if (method.equals("GET")) {
this.setMethod(AvailableMethods.GET);
} else if (method.equals("POST")) {
this.setMethod(AvailableMethods.POST);
} else if (method.equals("PATCH")) {
this.setMethod(AvailableMethods.PATCH);
}
}
/**
* Adds a parameter to the param list
* */
public void addParameter(String key, String value) {
parameters.put(key, value);
}
/**
* Returns the list of parameters as a map
* */
public HashMap getParameters() {
return parameters;
}
/**
* Sets the list of parameters.
* */
public void setParameters(HashMap parameters) {
this.parameters = parameters;
}
/**
* Sets the HTTP Client Builder factory
* @param clientBuilderFactory The HTTP Client Builder factory
*/
public void setClientBuilderFactory(HttpClientBuilderFactory clientBuilderFactory) {
this.clientBuilderFactory = clientBuilderFactory;
}
/**
* Executes the current request. Delegates to appropriate method based on the HTTP method used
* */
public SalesforceResponse executeRequest() throws SalesforceException {
if (method == AvailableMethods.GET) {
return executeGetRequest();
} else if (method == AvailableMethods.POST || method == AvailableMethods.PATCH) {
return executeDataRequest();
}
throw new SalesforceException("Unavailable HTTP Method");
}
/**
* Executes the Current GET Request and refreshes the access token if expired
* */
public SalesforceResponse executeGetRequest() throws SalesforceException {
SalesforceResponse response = new SalesforceResponse();
try {
response = doExecuteGetRequest();
if (isAccessTokenExpired(response)) {
SalesforceResponse refreshResponse = refreshAccessToken();
response = doExecuteGetRequest();
response.setAccessTokenUpdated(refreshResponse.getAccessTokenUpdated());
}
} catch (IOException e) {
logger.error("Transport Error while executing a GET Request ", e);
throw new SalesforceException("Transport Error while executing a GET Request ", e);
}
return response;
}
/**
* Executes the Current GET Request
* */
public SalesforceResponse doExecuteGetRequest() throws IOException, SalesforceException {
HttpClient client = getHttpClient();
SalesforceResponse response = new SalesforceResponse();
try {
String uri = instanceURL + path + "?";
Iterator it = parameters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry) it.next();
uri += (String) pairs.getKey() + "=" + URLEncoder.encode((String) pairs.getValue(), CharEncoding.UTF_8);
}
HttpGet method = new HttpGet(uri);
if (!contentType.isEmpty()) {
method.setHeader("Content-Type", contentType);
}
if (!accessToken.isEmpty()) {
method.removeHeaders("Authorization");
method.setHeader("Authorization", "OAuth " + accessToken);
}
// Execute the method.
internalExecuteRequest(client, method, response);
}
catch (Exception e){
logger.error("Error while Executing GET Request to Salesforce.com: ", e);
throw new SalesforceException("Error while Executing GET Request to Salesforce.com: ", e);
} finally {
HttpClientUtils.closeQuietly(client);
}
return response;
}
/**
* Executes the Current POST/PATCH Request and refreshes the access token if expired
* */
public SalesforceResponse executeDataRequest() throws SalesforceException {
SalesforceResponse response = new SalesforceResponse();
try {
response = doExecuteDataRequest();
if (isAccessTokenExpired(response)) {
SalesforceResponse refreshResponse = refreshAccessToken();
response = doExecuteDataRequest();
response.setAccessTokenUpdated(refreshResponse.getAccessTokenUpdated());
}
} catch (IOException e) {
logger.error("Transport Error while executing a GET Request ", e);
throw new SalesforceException("Transport Error while executing a GET Request ", e);
}
return response;
}
/**
* Executes the Current POST/PATCH Request
* */
public SalesforceResponse doExecuteDataRequest() throws IOException, SalesforceException {
HttpEntityEnclosingRequestBase method = null;
if (this.method == AvailableMethods.POST) {
method = new HttpPost(instanceURL + path);
} else if (this.method == AvailableMethods.PATCH) {
method = new HttpPatch(instanceURL + path);
}
SalesforceResponse response = new SalesforceResponse();
HttpClient client = getHttpClient();
try {
if (!contentType.isEmpty()) {
method.setHeader("Content-Type", contentType);
}
if (!accessToken.isEmpty()) {
method.removeHeaders("Authorization");
method.setHeader("Authorization", "OAuth " + accessToken);
}
method.setEntity(new StringEntity(data, ContentType.create(contentType, CharEncoding.UTF_8)));
// Read the response body.
// Execute the method.
internalExecuteRequest(client, method, response);
}
catch (Exception e){
logger.error("Error while Executing POST/PUT Request to Salesforce.com: ", e);
throw new SalesforceException("Error while Executing POST/PUT Request to Salesforce.com: ", e);
}
finally {
// Release the connection.
method.releaseConnection();
}
return response;
}
private void internalExecuteRequest(HttpClient client, HttpUriRequest method, SalesforceResponse response) throws IOException {
HttpResponse httpResponse = client.execute(method);
try {
response.setCode(httpResponse.getStatusLine().getStatusCode());
HttpEntity httpEntity = httpResponse.getEntity();
if (httpEntity != null) {
String body = EntityUtils.toString(httpResponse.getEntity());
response.setBody(body);
}
} finally {
HttpClientUtils.closeQuietly(httpResponse);
}
}
/**
* Refreshes the Access Token using the refresh_token
* Assumes that the client_id and client_secret are set before invoking this function
* */
public SalesforceResponse refreshAccessToken() throws SalesforceException {
SalesforceClient salesforceRefreshClient = new SalesforceClient();
SalesforceResponse response;
salesforceRefreshClient.setClientBuilderFactory(clientBuilderFactory);
salesforceRefreshClient.setRefreshToken(refreshToken);
salesforceRefreshClient.setPath(REFRESH_ACCESS_TOKEN_ENDPOINT);
salesforceRefreshClient.setInstanceURL(instanceURL);
salesforceRefreshClient.setContentType(APPLICATION_FORMURL_ENCODED);
salesforceRefreshClient.addData(GRANT_TYPE, REFRESH_TOKEN);
salesforceRefreshClient.addData(CLIENT_ID, clientId);
salesforceRefreshClient.addData(CLIENT_SECRET, clientSecret);
salesforceRefreshClient.addData(REFRESH_TOKEN, refreshToken);
salesforceRefreshClient.setMethod(SalesforceClient.AvailableMethods.POST);
response = salesforceRefreshClient.executeRequest();
try {
if (response.getCode() != HTTP_CODE_REFRESH_TOKEN_SUCCESS) {
String errorMessage = "";
JSONObject errorJSON = response.getBodyAsJSON();
if(errorJSON.get("error").equals(INVALID_CLIENT_ID)){
// Invalid Client/Customer Key
errorMessage = "Can't refresh access token due to Invalid Customer Key ";
}
else if(errorJSON.get("error").equals(INVALID_CLIENT)){
// Invalid Client/Customer Secret
errorMessage = "Can't refresh access token due to Invalid Customer Secret ";
}
else{
// Generic Handling
errorMessage = "Can't refresh access token due to some unknown error. " +
"Please contact Administrator ";
}
logger.error("Can't refresh access token.");
throw new SalesforceException(errorMessage);
}
else{
JSONObject responseJson = new JSONObject(response.getBody());
this.setInstanceURL(responseJson.getString("instance_url"));
this.setAccessToken(responseJson.getString("access_token"));
response.setAccessTokenUpdated(true);
}
} catch (JSONException e) {
logger.error("JSON Exception while refreshing the Access Token.");
throw new SalesforceException("JSON Exception while refreshing the Access Token.");
}
return response;
}
/**
* Checks if the currently set access token has been expired or not
* */
public boolean isAccessTokenExpired(SalesforceResponse salesforceResponse) throws SalesforceException {
JSONArray salesforceResponseJson;
if (salesforceResponse.getBody()!=null && !"".equals(salesforceResponse.getBody())) {
try {
// [{"message":"Session expired or invalid","errorCode":"INVALID_SESSION_ID"}]
String responseBody = salesforceResponse.getBody();
if(responseBody.charAt(0)!='[' && responseBody.charAt(responseBody.length()-1)!=']')
responseBody = '['+responseBody+']';
salesforceResponseJson = new JSONArray(responseBody);
return salesforceResponseJson.getJSONObject(0).getString("errorCode").equals("INVALID_SESSION_ID");
} catch (JSONException e) {
// Ignore the parsing error as errorCode is not found in success
logger.info("ErrorCode not found meaning success hence ignoring exception ");
}
}
return false;
}
/**
* Returns a HttpClient object
* @return HttpClient object
*/
private HttpClient getHttpClient() {
HttpClient client = null;
if (clientBuilderFactory != null) {
// Get HttpClient from the library to respect proxy settings
HttpClientBuilder builder = clientBuilderFactory.newBuilder();
if (builder != null) {
client = builder.build();
}
}
if (client == null) {
// If not possible, get default client
client = HttpClients.createDefault();
}
return client;
}
}