package com.ibm.sbt.service.core.handlers; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ibm.commons.util.io.json.JsonJavaFactory; import com.ibm.commons.util.io.json.JsonJavaObject; import com.ibm.commons.util.io.json.JsonObject; import com.ibm.commons.util.io.json.JsonParser; import com.ibm.sbt.services.client.email.DefaultMimeEmailFactory; import com.ibm.sbt.services.client.email.MimeEmail; import com.ibm.sbt.services.client.email.MimeEmailException; import com.ibm.sbt.services.client.email.MimeEmailFactory; /** * Handles requests to the proxy to send an email. * */ public class EmailHandler extends AbstractServiceHandler { /** * Math to the proxy handler. */ public static final String URL_PATH = "mailer"; private static final String APPLICATION_JSON = "application/json"; /* (non-Javadoc) * @see com.ibm.sbt.proxy.core.handlers.AbstractProxyHandler#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if(!request.getContentType().startsWith(APPLICATION_JSON)) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Content-Type must be application/json."); return; } PrintWriter writer = new PrintWriter(new OutputStreamWriter(response.getOutputStream(), "utf-8")); try { Object obj = JsonParser.fromJson(JsonJavaFactory.instanceEx, getPostBody(request)); List<JsonObject> emails = new ArrayList<JsonObject>(); if(obj instanceof List){ emails = (List<JsonObject>)obj; } else if (obj instanceof JsonObject) { JsonObject postBody = (JsonObject)obj; emails.add(postBody); } else { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Mailer API expects either an array of JSON objects or a single JSON object"); return; } JsonObject jsonResponse = send(emails); response.setStatus(HttpServletResponse.SC_OK); response.setContentType(APPLICATION_JSON); writer.write(jsonResponse.toString()); } catch (Exception e) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage()); return; } finally { writer.flush(); } } /** * Sends a emails. * @param emails The emails to send. * @return A JSON response of what emails were successfully sent and which ones had errors. */ private JsonObject send(List<JsonObject> emails) { MimeEmailFactory emailFactory = DefaultMimeEmailFactory.getInstance(); List<JsonObject> successful = new ArrayList<JsonObject>(); List<JsonObject> error = new ArrayList<JsonObject>(); for(JsonObject json : emails) { MimeEmail email; try { email = emailFactory.createMimeEmail(json); if(email != null) { email.send(); successful.add(json); } else { error.add(createErrorResponse(json, "Email could not be created from JSON.")); } } catch (MimeEmailException e) { error.add(createErrorResponse(json, e.getMessage())); } } JsonObject response = new JsonJavaObject(); response.putJsonProperty("successful", successful); response.putJsonProperty("error", error); return response; } /** * Creates an error JSON object. * @param email The JSON representing the email. * @param errorMessage The error message describing what went wrong. * @return An error JSON object. */ private JsonObject createErrorResponse(JsonObject email, String errorMessage) { JsonObject error = new JsonJavaObject(); error.putJsonProperty("message", errorMessage); error.putJsonProperty("email", email); return error; } /* (non-Javadoc) * @see com.ibm.sbt.proxy.core.handlers.AbstractProxyHandler#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } /* (non-Javadoc) * @see com.ibm.sbt.proxy.core.handlers.AbstractProxyHandler#doPut(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } /* (non-Javadoc) * @see com.ibm.sbt.proxy.core.handlers.AbstractProxyHandler#doDelete(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } /** * Gets the POST body. * @param request The POST request. * @return The POST body. * @throws IOException Thrown if the body cannot be retrieved. */ private String getPostBody(HttpServletRequest request) throws IOException { BufferedInputStream bis = new BufferedInputStream(request.getInputStream()); ByteArrayOutputStream buf = new ByteArrayOutputStream(); int result = bis.read(); while (result != -1) { byte b = (byte) result; buf.write(b); result = bis.read(); } buf.close(); String body = buf.toString(); return body; } }