/src/main/java/edu/cmu/ds/pbolar/privacymonitor/server/PrivacyMontiorController.java
Java | 184 lines | 111 code | 25 blank | 48 comment | 6 complexity | 06c569719b8df98787ef24f60cbcf4df MD5 | raw file
- package edu.cmu.ds.pbolar.privacymonitor.server;
- import com.google.gson.Gson;
- import com.mongodb.MongoClient;
- import com.mongodb.MongoClientURI;
- import com.mongodb.client.MongoCollection;
- import com.mongodb.client.MongoDatabase;
- import edu.cmu.ds.pbolar.privacymonitor.server.entity.ClientRequest;
- import edu.cmu.ds.pbolar.privacymonitor.server.entity.ClientResponse;
- import edu.cmu.ds.pbolar.privacymonitor.server.model.AzureImageFeaturizer;
- import edu.cmu.ds.pbolar.privacymonitor.server.model.Constant;
- import java.io.IOException;
- import java.nio.charset.StandardCharsets;
- import javax.servlet.RequestDispatcher;
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.bson.Document;
- /**
- *
- * @author pbolar
- */
- @WebServlet(name = "PrivacyMonitorServlet", urlPatterns = {"/analyze", "/dashboard"}, loadOnStartup = 0)
- public class PrivacyMontiorController extends HttpServlet {
- public static final String MONGO_COLLECTION_ATTR = "logs-collection";
-
- private final String ANALYZE_PATH = "/analyze";
- private final String DASHBOARD_PATH = "/dashboard";
- private final String DASHBOARD_JSP = "dashboard.jsp";
- private final String COLLECTION_ID = "privacy-monitor-logs";
-
- private Gson gson;
- private AzureImageFeaturizer azImageFeaturizer;
- private MongoCollection<Document> logs;
- private MongoClient mongoClient;
- @Override
- public void init() throws ServletException {
- gson = new Gson();
- azImageFeaturizer = new AzureImageFeaturizer(gson);
- // Connecting to the MongoDB database instance at mLab
- MongoClientURI uri = new MongoClientURI(Constant.getMLabURI());
- mongoClient = new MongoClient(uri);
- MongoDatabase db = mongoClient.getDatabase(uri.getDatabase());
- logs = db.getCollection(COLLECTION_ID);
- }
-
- /**
- * Processes both GETs and POSTs, assigning requests to appropriate handlers
- *
- * @param request Incoming request
- * @param response Outgoing response
- * @param isPost Boolean, true if HTTP POST was used as the request
- * @throws ServletException
- * @throws IOException
- */
- private void processRequest(HttpServletRequest request, HttpServletResponse response, boolean isPost)
- throws ServletException, IOException {
- switch (request.getServletPath()) {
- case ANALYZE_PATH:
- // ignore GETs on this path
- if (isPost) {
- analyzeClientRequest(request, response);
- }
- break;
- case DASHBOARD_PATH:
- serveDashboard(request, response);
- break;
- }
- }
- /**
- * Processes requests from mobile clients for image analysis
- *
- * @param req
- * @param resp
- * @throws ServletException
- * @throws IOException
- */
- private void analyzeClientRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // Start a new logging session
- Document log = new Document().append(Constant.MDB_TIMESTAMP_KEY, System.nanoTime());
-
- // What sort of content-type is this?
- String contentType = getContentType(req);
- if (!contentType.equals(Constant.JSON_MIME)) {
- // We only support JSON!
- String responseJson = getJsonMessage("This Content-Type (" + req.getContentType() + ") is not accepted.");
- buildResponse(resp, HttpServletResponse.SC_NOT_ACCEPTABLE, Constant.JSON_MIME, responseJson);
- return;
- }
-
- // Deserialize the JSON
- ClientRequest request = getClientRequest(req);
- System.out.println(request);
- // Get the model to talk to Azure about this picture
- log.append(Constant.MDB_PHONE_KEY, request.getPhoneModel());
- ClientResponse response = azImageFeaturizer.analyzeImage(request, log);
- // Everything looking good?
- if (response.getStatus() == HttpServletResponse.SC_OK) {
- String responseJson = gson.toJson(response, ClientResponse.class);
- // Send this back to the client
- buildResponse(resp, HttpServletResponse.SC_OK, Constant.JSON_MIME, responseJson);
- } else {
- // Send an error
- buildResponse(resp, response.getStatus(), Constant.JSON_MIME, getJsonMessage(response.getMessage()));
- }
- // Store document in the DB
- logs.insertOne(log);
- System.out.println("---------------- COMPLETED WITH STATUS [" +response.getStatus() +"] ----------------");
- }
-
- /**
- *
- * @param req
- * @return Marshalled version of the client request JSON
- * @throws IOException
- */
- private ClientRequest getClientRequest(HttpServletRequest req) throws IOException {
- StringBuilder jsonBuilder = req.getReader().lines()
- .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);
- return gson.fromJson(jsonBuilder.toString(), ClientRequest.class);
- }
- /**
- * Responds to requests for the dashboard web page
- *
- * @param req
- * @param resp
- * @throws ServletException
- * @throws IOException
- */
- private void serveDashboard(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- req.setAttribute(MONGO_COLLECTION_ATTR, logs);
- RequestDispatcher resultView = req.getRequestDispatcher(DASHBOARD_JSP);
- resultView.forward(req, resp);
- }
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- System.out.println("---------------- NEW POST REQUEST FROM " + req.getRemoteAddr() + " ----------------");
- this.processRequest(req, resp, true);
- }
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- this.processRequest(req, resp, false);
- }
- private void buildResponse(HttpServletResponse resp, int status, String mime, String payload) throws IOException {
- resp.setStatus(status);
- resp.setContentType(mime);
- resp.setContentLength(payload.length());
- resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
- resp.getWriter().append(payload).flush();
- }
- @Override
- public void destroy() {
- mongoClient.close();
- }
- private String getJsonMessage(String message) {
- return "{\"message\":\"" + message + "\"}";
- }
- private String getContentType(HttpServletRequest req) {
- String[] contentTypeParts = req.getContentType().split(";");
- // contentTypeParts[1] => MIME
- // contentTypeParts[1] => Charset
- return contentTypeParts[0].trim();
- }
- }