@Test public void returnsA404WhenNotFound() throws Exception { when(request.getMethod()).thenReturn("POST"); when(request.getPathInfo()).thenReturn("/test"); servlet.service(request, response); verify(response).sendError(404); }
@Test public void passesQueryStringParamsAlong() throws Exception { final PrintWriter output = mock(PrintWriter.class); when(request.getMethod()).thenReturn("POST"); when(request.getPathInfo()).thenReturn("/gc"); when(request.getParameterNames()).thenReturn(Collections.enumeration(ImmutableList.of("runs"))); when(request.getParameterValues("runs")).thenReturn(new String[] {"1"}); when(response.getWriter()).thenReturn(output); servlet.service(request, response); verify(gc).execute(ImmutableMultimap.of("runs", "1"), output); }
@Test public void runsATaskWhenFound() throws Exception { final PrintWriter output = mock(PrintWriter.class); when(request.getMethod()).thenReturn("POST"); when(request.getPathInfo()).thenReturn("/gc"); when(request.getParameterNames()) .thenReturn(Collections.enumeration(ImmutableList.<String>of())); when(response.getWriter()).thenReturn(output); servlet.service(request, response); verify(gc).execute(ImmutableMultimap.<String, String>of(), output); }
@Test @SuppressWarnings("unchecked") public void returnsA500OnExceptions() throws Exception { when(request.getMethod()).thenReturn("POST"); when(request.getPathInfo()).thenReturn("/gc"); when(request.getParameterNames()) .thenReturn(Collections.enumeration(ImmutableList.<String>of())); final PrintWriter output = mock(PrintWriter.class); when(response.getWriter()).thenReturn(output); final RuntimeException ex = new RuntimeException("whoops"); doThrow(ex).when(gc).execute(any(ImmutableMultimap.class), any(PrintWriter.class)); servlet.service(request, response); verify(response).setStatus(500); }
@Before public void setUp() throws Exception { servlet.add(gc); servlet.add(clearCache); }
/** Get map info operation. */ private long mapInfoOp( final HttpServletRequest request, final HttpServletResponse response, final PersistenceManager pm, final ApiAccount apiAccount) throws IOException { String mapFileName = request.getParameter(PARAM_MAP_FILE_NAME); LOGGER.fine( "API account: " + apiAccount.getUser().getEmail() + ", map file name: " + mapFileName); if (mapFileName == null || mapFileName.isEmpty()) { LOGGER.warning("Missing map file name!"); response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing map file name!"); return 0; } if ((mapFileName = ServerUtils.checkMapFileName(mapFileName)) == null) { LOGGER.warning("Invalid map file name: " + mapFileName); response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid map file name!"); return 0; } try { final XmlBuilder xb = new XmlBuilder("1.0"); long opsCharged = 0; final List<Map> mapList = new JQBuilder<>(pm, Map.class).filter("fname==p1", "String p1").get(mapFileName); if (mapList.isEmpty()) { // Register a task to process the map TaskServlet.register_processMapTask(mapFileName); xb.createResultElement(MapInfoResult.PROCESSING); } else { final Map map = mapList.get(0); switch (map.getStatus()) { case Map.STATUS_PROCESSING: xb.createResultElement(MapInfoResult.PROCESSING); break; case Map.STATUS_PARSING_ERROR: xb.createResultElement(MapInfoResult.PARSING_ERROR); break; case Map.STATUS_DL_ERROR: xb.createResultElement(MapInfoResult.DOWNLOAD_ERROR); break; case Map.STATUS_READY: { opsCharged = 1; xb.createResultElement(MapInfoResult.OK); Element element = xb.createElement(XTAG_MAP); element.setAttribute(XATTR_NAME, map.getName()); element.setAttribute(XATTR_WIDTH, Integer.toString(map.getMwidth())); element.setAttribute(XATTR_HEIGHT, Integer.toString(map.getMheight())); element = xb.createElement(XTAG_MAP_IMAGE); element.setAttribute(XATTR_FORMAT, "JPEG"); element.setAttribute(XATTR_SIZE, Integer.toString(map.getSize())); element.setAttribute(XATTR_WIDTH, Integer.toString(map.getWidth())); element.setAttribute(XATTR_HEIGHT, Integer.toString(map.getHeight())); element.setTextContent( javax.xml.bind.DatatypeConverter.printBase64Binary(map.getImage().getBytes())); break; } } } xb.printDocument(response); return opsCharged; } catch (final Exception e) { LOGGER.log(Level.SEVERE, "", e); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return 0; } }
@Override protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { final long startNanoTime = System.nanoTime(); final String operation = checkProtVerAndGetOperation(PROTOCOL_VERSION_1, request, response); if (operation == null) return; final String apiKey = request.getParameter(PARAM_API_KEY); if (apiKey == null || apiKey.isEmpty()) { LOGGER.warning("Missing API key!"); response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing API key!"); return; } long opsCharged = 0; ApiAccount apiAccount = null; PersistenceManager pm = null; ResponseWrapper responseWrapper = null; boolean denied = false; try { pm = PMF.get().getPersistenceManager(); // Check API key final List<ApiAccount> apiAccountList = new JQBuilder<>(pm, ApiAccount.class).filter("apiKey==p1", "String p1").get(apiKey); if (apiAccountList.isEmpty()) { LOGGER.warning("Unauthorized access, invalid API Key: " + apiKey); response.sendError( HttpServletResponse.SC_FORBIDDEN, "Unauthorized access, invalid API Key!"); return; } apiAccount = apiAccountList.get(0); responseWrapper = new ResponseWrapper(response); // Check Ops quota final List<ApiCallStat> totalApiCallStatList = new JQBuilder<>(pm, ApiCallStat.class) .filter("ownerKey==p1 && day==p2", "KEY p1, String p2") .get(apiAccount.getKey(), ApiCallStat.DAY_TOTAL); final long totalUsedOps = totalApiCallStatList.isEmpty() ? 0 : totalApiCallStatList.get(0).getUsedOps(); if (!OPERATION_INFO.equals(operation) && totalUsedOps >= apiAccount.getPaidOps()) { denied = true; LOGGER.warning( "Ops quota have been exceeded, serving denied! (API account: " + apiAccount.getUser().getEmail() + ")"); responseWrapper.sendError( HttpServletResponse.SC_PAYMENT_REQUIRED, "Ops quota have been exceeded, serving denied!"); return; } switch (operation) { case OPERATION_INFO: opsCharged = infoOp(request, responseWrapper, pm, apiAccount); break; case OPERATION_MAP_INFO: opsCharged = mapInfoOp(request, responseWrapper, pm, apiAccount); break; case OPERATION_PARSE_REPLAY: opsCharged = parseRepOp(request, responseWrapper, pm, apiAccount); break; case OPERATION_PROFILE_INFO: opsCharged = profInfoOp(request, responseWrapper, pm, apiAccount); break; default: LOGGER.warning( "Invalid Operation! (API account: " + apiAccount.getUser().getEmail() + ")"); responseWrapper.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid Operation!"); return; } // Notification available Ops will be checked in the task servlet, update API call stat task } finally { if (apiAccount != null) TaskServlet.register_updateApiCallStat( apiAccount.getKey(), apiAccount.getPaidOps(), apiAccount.getNotificationAvailOps(), opsCharged, (System.nanoTime() - startNanoTime) / 1000000l, denied, responseWrapper == null ? true : responseWrapper.isError(), operation); if (pm != null) pm.close(); } }