HsJobBlock extends HtmlBlock { @Override protected void render(Block html) { String jid = $(JOB_ID); if (jid.isEmpty()) { html. p().__("Sorry, can't do anything without a JobID.").__(); return; } JobId jobID = MRApps.toJobID(jid); Job j = appContext.getJob(jobID); if (j == null) { html.p().__("Sorry, ", jid, " not found.").__(); return; } if(j instanceof UnparsedJob) { final int taskCount = j.getTotalMaps() + j.getTotalReduces(); UnparsedJob oversizedJob = (UnparsedJob) j; html.p().__("The job has a total of " + taskCount + " tasks. ") .__("Any job larger than " + oversizedJob.getMaxTasksAllowed() + " will not be loaded.").__(); html.p().__("You can either use the CLI tool: 'mapred job -history'" + " to view large jobs or adjust the property " + JHAdminConfig.MR_HS_LOADED_JOBS_TASKS_MAX + ".").__(); return; } List<AMInfo> amInfos = j.getAMInfos(); JobInfo job = new JobInfo(j); ResponseInfo infoBlock = info("Job Overview"). __("Job Name:", job.getName()). __("User Name:", job.getUserName()). __("Queue:", job.getQueueName()). __("State:", job.getState()). __("Uberized:", job.isUber()). __("Submitted:", new Date(job.getSubmitTime())). __("Started:", job.getStartTimeStr()). __("Finished:", new Date(job.getFinishTime())). __("Elapsed:", StringUtils.formatTime( Times.elapsed(job.getStartTime(), job.getFinishTime(), false))); String amString = amInfos.size() == 1 ? "ApplicationMaster" : "ApplicationMasters"; List<String> diagnostics = j.getDiagnostics(); if(diagnostics != null && !diagnostics.isEmpty()) { StringBuffer b = new StringBuffer(); for(String diag: diagnostics) { b.append(addTaskLinks(diag)); } infoBlock._r("Diagnostics:", b.toString()); } if(job.getNumMaps() > 0) { infoBlock.__("Average Map Time", StringUtils.formatTime(job.getAvgMapTime())); } if(job.getNumReduces() > 0) { infoBlock.__("Average Shuffle Time", StringUtils.formatTime(job.getAvgShuffleTime())); infoBlock.__("Average Merge Time", StringUtils.formatTime(job.getAvgMergeTime())); infoBlock.__("Average Reduce Time", StringUtils.formatTime(job.getAvgReduceTime())); } for (ConfEntryInfo entry : job.getAcls()) { infoBlock.__("ACL "+entry.getName()+":", entry.getValue()); } DIV<Hamlet> div = html. __(InfoBlock.class). div(_INFO_WRAP); TABLE<DIV<Hamlet>> table = div.table("#job"); table. tr(). th(amString). __(). tr(). th(_TH, "Attempt Number"). th(_TH, "Start Time"). th(_TH, "Node"). th(_TH, "Logs"). __(); boolean odd = false; for (AMInfo amInfo : amInfos) { AMAttemptInfo attempt = new AMAttemptInfo(amInfo, job.getId(), job.getUserName(), "", ""); table.tr((odd = !odd) ? _ODD : _EVEN). td(String.valueOf(attempt.getAttemptId())). td(new Date(attempt.getStartTime()).toString()). td().a(".nodelink", url(MRWebAppUtil.getYARNWebappScheme(), attempt.getNodeHttpAddress()), attempt.getNodeHttpAddress()).__(). td().a(".logslink", url(attempt.getLogsLink()), "logs").__(). __(); } table.__(); div.__(); html.div(_INFO_WRAP). table("#job"). tr(). th(_TH, "Task Type"). th(_TH, "Total"). th(_TH, "Complete").__(). tr(_ODD). th(). a(url("tasks", jid, "m"), "Map").__(). td(String.valueOf(String.valueOf(job.getMapsTotal()))). td(String.valueOf(String.valueOf(job.getMapsCompleted()))).__(). tr(_EVEN). th(). a(url("tasks", jid, "r"), "Reduce").__(). td(String.valueOf(String.valueOf(job.getReducesTotal()))). td(String.valueOf(String.valueOf(job.getReducesCompleted()))).__() .__(). table("#job"). tr(). th(_TH, "Attempt Type"). th(_TH, "Failed"). th(_TH, "Killed"). th(_TH, "Successful").__(). tr(_ODD). th("Maps"). td().a(url("attempts", jid, "m", TaskAttemptStateUI.FAILED.toString()), String.valueOf(job.getFailedMapAttempts())).__(). td().a(url("attempts", jid, "m", TaskAttemptStateUI.KILLED.toString()), String.valueOf(job.getKilledMapAttempts())).__(). td().a(url("attempts", jid, "m", TaskAttemptStateUI.SUCCESSFUL.toString()), String.valueOf(job.getSuccessfulMapAttempts())).__(). __(). tr(_EVEN). th("Reduces"). td().a(url("attempts", jid, "r", TaskAttemptStateUI.FAILED.toString()), String.valueOf(job.getFailedReduceAttempts())).__(). td().a(url("attempts", jid, "r", TaskAttemptStateUI.KILLED.toString()), String.valueOf(job.getKilledReduceAttempts())).__(). td().a(url("attempts", jid, "r", TaskAttemptStateUI.SUCCESSFUL.toString()), String.valueOf(job.getSuccessfulReduceAttempts())).__(). __(). __(). __(); } @Inject  HsJobBlock(AppContext appctx);   }
@Test public void testHsJobBlockForOversizeJobShouldDisplayWarningMessage() { int maxAllowedTaskNum = 100; Configuration config = new Configuration(); config.setInt(JHAdminConfig.MR_HS_LOADED_JOBS_TASKS_MAX, maxAllowedTaskNum); JobHistory jobHistory = new JobHistoryStubWithAllOversizeJobs(maxAllowedTaskNum); jobHistory.init(config); HsJobBlock jobBlock = new HsJobBlock(jobHistory) { @Override public Map<String, String> moreParams() { Map<String, String> map = new HashMap<>(); map.put(AMParams.JOB_ID, "job_0000_0001"); return map; } }; OutputStream outputStream = new ByteArrayOutputStream(); HtmlBlock.Block block = createBlockToCreateTo(outputStream); jobBlock.render(block); block.getWriter().flush(); String out = outputStream.toString(); Assert.assertTrue("Should display warning message for jobs that have too " + "many tasks", out.contains("Any job larger than " + maxAllowedTaskNum + " will not be loaded")); }
@Test public void testHsJobBlockForNormalSizeJobShouldNotDisplayWarningMessage() { Configuration config = new Configuration(); config.setInt(JHAdminConfig.MR_HS_LOADED_JOBS_TASKS_MAX, -1); JobHistory jobHistory = new JobHitoryStubWithAllNormalSizeJobs(); jobHistory.init(config); HsJobBlock jobBlock = new HsJobBlock(jobHistory) { @Override public Map<String, String> moreParams() { Map<String, String> map = new HashMap<>(); map.put(AMParams.JOB_ID, "job_0000_0001"); return map; } @Override public ResponseInfo info(String about) { return new ResponseInfo().about(about); } @Override public String url(String... parts) { return StringHelper.ujoin("", parts); } }; OutputStream outputStream = new ByteArrayOutputStream(); HtmlBlock.Block block = createBlockToCreateTo(outputStream); jobBlock.render(block); block.getWriter().flush(); String out = outputStream.toString(); Assert.assertTrue("Should display job overview for the job.", out.contains("ApplicationMaster")); }