package com.webgroupmedia.cerb4.exporter.zendesk;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.dom4j.Document;
import com.cerb4.impex.Configuration;
import com.webgroupmedia.cerb4.exporter.zendesk.ZenRunnable.IResponseHandler;
public class ZendeskConnection {
private MultiThreadedHttpConnectionManager connectionManager;
private static ZendeskConnection instance = new ZendeskConnection();
private final static String sZendeskUser = new String(Configuration.get("zendeskUser", ""));
private final static String sZendeskPassword = new String(Configuration.get("zendeskPassword", ""));
private final Integer MAX_HTTP_CONNECTIONS = Integer.parseInt(Configuration.get("maxHttpConnections", "7"));
private static Cookie loginCookie;
public static ZendeskConnection getInstance() {
return instance;
}
public ZendeskConnection() {
connectionManager = new MultiThreadedHttpConnectionManager();
HttpConnectionManagerParams params = new HttpConnectionManagerParams();
params.setMaxTotalConnections(MAX_HTTP_CONNECTIONS);
connectionManager.setParams(params);
}
public void requestZendeskDocumentAsync(String objectType, String objectId, Map<String,String> params,
IResponseHandler responseHandler) {
//since this is an async request, the document returned by the method below is always null (so we don't return it)
requestZendeskDocument(objectType, objectId, params, true, responseHandler);
}
public Document requestZendeskDocumentSerial(String objectType, String objectId, Map<String,String> params) {
return requestZendeskDocument(objectType, objectId, params, false, null);
}
private Document requestZendeskDocument(String objectType, String objectId, Map<String,String> params,
boolean isAsync, IResponseHandler responseHandler) {
String cfgHelpdeskURL = Configuration.get("zendeskURL", "");
if(!cfgHelpdeskURL.endsWith("/")) {
cfgHelpdeskURL = cfgHelpdeskURL + "/";
}
String url;
if(objectId == null) {
url = cfgHelpdeskURL + objectType + ".xml";
}
else {
url = cfgHelpdeskURL + objectType + "/" + objectId + ".xml";
}
if(params != null && params.size() > 0) {
StringBuffer buffer = new StringBuffer("?");
boolean firstParam = true;
for (Entry<String,String> paramsEntry : params.entrySet()) {
if(!firstParam)
buffer.append("&");
else
firstParam = false;
paramsEntry.getKey();
buffer.append(paramsEntry.getKey());
buffer.append("=");
buffer.append(paramsEntry.getValue());
}
url += buffer.toString();
}
return requestZendeskDocumentByUrl(url, isAsync, responseHandler);
}
private Document requestZendeskDocumentByUrl(String url, boolean isAsync, IResponseHandler responseHandler) {
Document zenDoc = null;
HttpClient client = new HttpClient(connectionManager);
HttpState httpState = new HttpState();
AuthScope authScope = new AuthScope(null, -1);
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(sZendeskUser, sZendeskPassword);
httpState.setCredentials(authScope, credentials);
client.setState(httpState);
System.out.println(url);
GetMethod method = new GetMethod(url);
ZenRunnable zenRunnable = new ZenRunnable(client, method, responseHandler);
if(isAsync) {
Thread thread = new Thread(zenRunnable);
thread.start();
}
else {
zenDoc = zenRunnable.requestDoc();
}
return zenDoc;
}
public byte[] requestZendeskAttachment(Integer attachmentId) throws HttpException, IOException {
String cfgHelpdeskURL = Configuration.get("zendeskURL", "");
if(!cfgHelpdeskURL.endsWith("/")) {
cfgHelpdeskURL = cfgHelpdeskURL + "/";
}
String url = cfgHelpdeskURL + "attachments/" + attachmentId;
HttpClient httpClient = new HttpClient(connectionManager);
HttpState httpState = new HttpState();
AuthScope authScope = new AuthScope(null, -1);
System.out.println("credential:"+sZendeskUser);
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(sZendeskUser, sZendeskPassword);
httpState.setCredentials(authScope, credentials);
//Zen doesn't let us download attachments with only the simple auth. We have to login to their website
Cookie loginCookie = getZendeskCookie();
System.out.println("cookie:"+loginCookie.getName()+":"+loginCookie.getValue());
httpState.addCookie(loginCookie);
httpClient.setState(httpState);
System.out.println(url);
GetMethod method = new GetMethod(url);
httpClient.executeMethod(method);
InputStream in=method.getResponseBodyAsStream();
ByteArrayOutputStream baos= new ByteArrayOutputStream();
int c;
while ((c = in.read()) != -1) {
baos.write(c);
}
return baos.toByteArray();
}
public static Cookie getZendeskCookie() {
if(loginCookie != null) {
return loginCookie;
}
Cookie cookieCopy = null;
String cfgHelpdeskURL = Configuration.get("zendeskURL", "");
if(!cfgHelpdeskURL.endsWith("/")) {
cfgHelpdeskURL = cfgHelpdeskURL + "/";
}
String url="";
if(cfgHelpdeskURL.startsWith("http:")) {
url = "https" + cfgHelpdeskURL.substring(4);
}
url +="access/login";
//url="https://extraice.zendesk.com/access/login";
HttpClient httpClient = new HttpClient();
httpClient.getParams().setParameter(HttpMethodParams.USER_AGENT,
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.6pre) Gecko/2009011606 Firefox/3.1");
PostMethod method = new PostMethod(url);
method.addParameter("user[email]", sZendeskUser);
method.addParameter("user[password]", sZendeskPassword);
method.addParameter("commit", " Login ");
try {
method.getParams().setCookiePolicy(CookiePolicy.RFC_2109);
System.out.println("executing:"+url);
httpClient.executeMethod(method);
Cookie[] cookies = httpClient.getState().getCookies();
for (Cookie cookie : cookies) {
if(cookie.getName().equals("_love_your_new_zendesk_session")) {
cookieCopy = new Cookie(cookie.getDomain(), cookie.getName(), cookie.getValue(), cookie.getPath(), cookie.getExpiryDate(), cookie.getSecure());
break;
}
}
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
loginCookie = cookieCopy;
return cookieCopy;
}
}