@GET @Path("flowStats/{cluster}/{user}/{appId}") @Produces(MediaType.APPLICATION_JSON) public PaginatedResult<Flow> getJobFlowStats( @PathParam("cluster") String cluster, @PathParam("user") String user, @PathParam("appId") String appId, @QueryParam("version") String version, @QueryParam("startRow") String startRowParam, @QueryParam("startTime") long startTime, @QueryParam("endTime") long endTime, @QueryParam("limit") @DefaultValue("100") int limit, @QueryParam("includeJobs") boolean includeJobs) throws IOException { LOG.info( "Fetching flowStats for flowStats/{cluster}/{user}/{appId} with input query: " + "flowStats/" + cluster + SLASH // + user /{appId} cluster + " user " + user + appId + "?version=" + version + "&limit=" + limit + "&startRow=" + startRowParam + "&startTime=" + startTime + "&endTime=" + endTime + "&includeJobs=" + includeJobs); Stopwatch timer = new Stopwatch().start(); byte[] startRow = null; if (startRowParam != null) { startRow = Base64.decode(startRowParam); } if (includeJobs) { serializationContext.set( new SerializationContext( SerializationContext.DetailLevel.FLOW_SUMMARY_STATS_WITH_JOB_STATS)); } else { serializationContext.set( new SerializationContext(SerializationContext.DetailLevel.FLOW_SUMMARY_STATS_ONLY)); } if (endTime == 0) { endTime = Long.MAX_VALUE; } if ((limit == 0) || (limit == Integer.MAX_VALUE)) { limit = Integer.MAX_VALUE - 1; } List<Flow> flows = getJobHistoryService() .getFlowTimeSeriesStats( cluster, user, appId, version, startTime, endTime, limit + 1, startRow); PaginatedResult<Flow> flowStatsPage = new PaginatedResult<Flow>(limit); // add request parameters flowStatsPage.addRequestParameter("user", user); flowStatsPage.addRequestParameter("appId", appId); if (StringUtils.isNotBlank(version)) { flowStatsPage.addRequestParameter("version", version); } else { flowStatsPage.addRequestParameter("version", "all"); } flowStatsPage.addRequestParameter("startTime", Long.toString(startTime)); flowStatsPage.addRequestParameter("endTime", Long.toString(endTime)); flowStatsPage.addRequestParameter("limit", Integer.toString(limit)); if (startRow != null) { flowStatsPage.addRequestParameter("startRow", startRowParam); } if (includeJobs) { flowStatsPage.addRequestParameter("includeJobs", "true"); } else { flowStatsPage.addRequestParameter("includeJobs", "false"); } if (flows.size() > limit) { // copy over the last excluding the last element // the last element is the start row for next page flowStatsPage.setValues(flows.subList(0, limit)); flowStatsPage.setNextStartRow(new FlowKeyConverter().toBytes(flows.get(limit).getFlowKey())); } else { flowStatsPage.setNextStartRow(null); flowStatsPage.setValues(flows); } timer.stop(); LOG.info( "For flowStats/{cluster}/{user}/{appId} with input query: " + "flowStats/" + cluster + SLASH // + user /{appId} cluster + " user " + user + appId + "?version=" + version + "&limit=" + limit + "&startRow=" + startRow + "&startTime=" + startTime + "&endTime=" + endTime + "&includeJobs=" + includeJobs + " fetched " + flows.size() + " in " + timer); return flowStatsPage; }