package com.voxeo.moho.imified;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.log4j.Logger;
import com.voxeo.moho.Endpoint;
import com.voxeo.moho.spi.HTTPDriver;
import com.voxeo.moho.spi.SpiFramework;
public class IMifiedDriver implements HTTPDriver {
private static final long serialVersionUID = -6982167135072972700L;
private static final Logger LOG = Logger.getLogger(IMifiedDriver.class);
protected SpiFramework _appEventSource = null;
protected DefaultHttpClient _httpClient = null;
protected String _imifiedApiURL = "https://www.imified.com/api/bot/";
protected final static String[] SCHEMAS = new String[]{"im"};
@Override
public void init(SpiFramework framework) {
_appEventSource = framework;
HttpServlet servlet = framework.getHTTPController();
if (servlet.getServletConfig().getInitParameter("imifiedApiURL") != null) {
_imifiedApiURL = servlet.getServletConfig().getInitParameter("imifiedApiURL");
}
HttpParams params = new BasicHttpParams();
ConnManagerParams.setMaxTotalConnections(params, 20);
ConnPerRouteBean connPerRoute = new ConnPerRouteBean(20);
ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
_httpClient = new DefaultHttpClient(cm, params);
_httpClient.setReuseStrategy(new DefaultConnectionReuseStrategy());
_httpClient.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
String param = he.getName();
String value = he.getValue();
if (value != null && param.equalsIgnoreCase("timeout")) {
try {
return Long.parseLong(value) * 1000;
}
catch (NumberFormatException ex) {
// ignore
}
}
}
// otherwise
return -1;
}
});
}
protected String getIMifiedURL() {
return _imifiedApiURL;
}
protected HttpResponse execute(HttpUriRequest request) throws ClientProtocolException, IOException {
return _httpClient.execute(request);
}
@Override
public void destroy() {
if (_httpClient != null) {
_httpClient.getConnectionManager().shutdown();
}
}
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
LOG.debug("Received do GET request.");
resp.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
LOG.debug("Received POST request");
BufferedReader reader = new BufferedReader(new InputStreamReader(req.getInputStream()));
String data = reader.readLine();
if (LOG.isDebugEnabled()) {
LOG.debug("The msg:" + data);
}
if (data != null && data.trim().length() > 0) {
String[] array = data.split("&");
try {
Map<String, String> keyValues = new HashMap<String, String>();
Map<String, String> history = null;
for (String part : array) {
String key = part.substring(0, part.indexOf('='));
String value = part.substring(part.indexOf('=') + 1);
if (key.startsWith("value")) {
if (history == null) {
history = new HashMap<String, String>();
}
history.put(key, URLDecoder.decode(value, "UTF-8"));
}
else {
keyValues.put(key, URLDecoder.decode(value, "UTF-8"));
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("The parsed keyValues:" + keyValues);
LOG.debug("The parsed historyValue:" + history);
}
IMifiedEventImpl event = new IMifiedEventImpl(_appEventSource, this, keyValues.get("channel"),
keyValues.get("botkey"), keyValues.get("userkey"), keyValues.get("user"), keyValues.get("network"),
keyValues.get("msg"), keyValues.get("step"), keyValues.get("to"), history);
_appEventSource.dispatch(event);
}
catch (Exception ex) {
LOG.error("Exception when processing message from imified.", ex);
throw new ServletException(ex);
}
}
}
@Override
public String getProtocolFamily() {
return PROTOCOL_HTTP;
}
@Override
public String[] getEndpointSchemas() {
return SCHEMAS;
}
@Override
public SpiFramework getFramework() {
return _appEventSource;
}
@Override
public Endpoint createEndpoint(String addr) {
return new ImifiedEndpointImpl(this, addr.substring(addr.indexOf(":") + 1));
}
@Override
public void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
LOG.debug("Received do PUT request.");
resp.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
}
@Override
public void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
LOG.debug("Received do TRACE request.");
resp.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
}
@Override
public void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
LOG.debug("Received do HEAD request.");
resp.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
}
@Override
public void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
LOG.debug("Received do OPTIONS request.");
resp.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
}
@Override
public long getLastModified(HttpServletRequest req) {
return 0;
}
}