ReadOnlySchedulerImpl implements ReadOnlyScheduler.Iface { @Override public Response getJobSummary(@Nullable String maybeNullRole) { Optional<String> ownerRole = Optional.fromNullable(maybeNullRole); Multimap<IJobKey, IScheduledTask> tasks = getTasks(maybeRoleScoped(ownerRole)); Map<IJobKey, IJobConfiguration> jobs = getJobs(ownerRole, tasks); Function<IJobKey, JobSummary> makeJobSummary = jobKey -> { IJobConfiguration job = jobs.get(jobKey); JobSummary summary = new JobSummary() .setJob(job.newBuilder()) .setStats(Jobs.getJobStats(tasks.get(jobKey)).newBuilder()); if (job.isSetCronSchedule()) { CrontabEntry crontabEntry = CrontabEntry.parse(job.getCronSchedule()); Optional<Date> nextRun = cronPredictor.predictNextRun(crontabEntry); return nextRun.transform(date -> summary.setNextCronRunMs(date.getTime())).or(summary); } else { return summary; } }; ImmutableSet<JobSummary> jobSummaries = FluentIterable.from(jobs.keySet()).transform(makeJobSummary).toSet(); return ok(Result.jobSummaryResult(new JobSummaryResult().setSummaries(jobSummaries))); } @Inject  ReadOnlySchedulerImpl(
      ConfigurationManager configurationManager,
      Storage storage,
      NearestFit nearestFit,
      CronPredictor cronPredictor,
      QuotaManager quotaManager); @Override Response populateJobConfig(JobConfiguration description); @Override Response getTasksStatus(TaskQuery query); @Override Response getTasksWithoutConfigs(TaskQuery query); @Override Response getPendingReason(TaskQuery query); @Override Response getConfigSummary(JobKey job); @Override Response getRoleSummary(); @Override Response getJobSummary(@Nullable String maybeNullRole); @Override Response getJobs(@Nullable String maybeNullRole); @Override Response getQuota(String ownerRole); @Override Response getJobUpdateSummaries(JobUpdateQuery mutableQuery); @Override Response getJobUpdateDetails(JobUpdateKey mutableKey); @Override Response getJobUpdateDiff(JobUpdateRequest mutableRequest);  }
@Test public void testGetJobSummary() throws Exception { long nextCronRunMs = 100; TaskConfig ownedCronJobTask = nonProductionTask().setJob(JOB_KEY.newBuilder()); JobConfiguration ownedCronJob = makeJob() .setCronSchedule(CRON_SCHEDULE) .setTaskConfig(ownedCronJobTask); IScheduledTask ownedCronJobScheduledTask = IScheduledTask.build(new ScheduledTask() .setAssignedTask(new AssignedTask().setTask(ownedCronJobTask)) .setStatus(ScheduleStatus.ASSIGNED)); Identity otherOwner = new Identity().setUser("other"); JobConfiguration unownedCronJob = makeJob() .setOwner(otherOwner) .setCronSchedule(CRON_SCHEDULE) .setKey(JOB_KEY.newBuilder().setRole("other")) .setTaskConfig(ownedCronJobTask.deepCopy().setOwner(otherOwner)); TaskConfig ownedImmediateTaskInfo = defaultTask(false) .setJob(JOB_KEY.newBuilder().setName("immediate")); Set<JobConfiguration> ownedCronJobOnly = ImmutableSet.of(ownedCronJob); Set<JobSummary> ownedCronJobSummaryOnly = ImmutableSet.of( new JobSummary() .setJob(ownedCronJob) .setStats(new JobStats()) .setNextCronRunMs(nextCronRunMs)); Set<JobSummary> ownedCronJobSummaryWithRunningTask = ImmutableSet.of( new JobSummary() .setJob(ownedCronJob) .setStats(new JobStats().setActiveTaskCount(1)) .setNextCronRunMs(nextCronRunMs)); Set<JobConfiguration> unownedCronJobOnly = ImmutableSet.of(unownedCronJob); Set<JobConfiguration> bothCronJobs = ImmutableSet.of(ownedCronJob, unownedCronJob); IScheduledTask ownedImmediateTask = IScheduledTask.build(new ScheduledTask() .setAssignedTask(new AssignedTask().setTask(ownedImmediateTaskInfo)) .setStatus(ScheduleStatus.ASSIGNED)); JobConfiguration ownedImmediateJob = new JobConfiguration() .setKey(JOB_KEY.newBuilder().setName("immediate")) .setOwner(IDENTITY) .setInstanceCount(1) .setTaskConfig(ownedImmediateTaskInfo); Builder query = Query.roleScoped(ROLE); Set<JobSummary> ownedImmediateJobSummaryOnly = ImmutableSet.of( new JobSummary().setJob(ownedImmediateJob).setStats(new JobStats().setActiveTaskCount(1))); expect(cronPredictor.predictNextRun(CrontabEntry.parse(CRON_SCHEDULE))) .andReturn(Optional.of(new Date(nextCronRunMs))) .anyTimes(); storageUtil.expectTaskFetch(query); expect(storageUtil.jobStore.fetchJobs()) .andReturn(IJobConfiguration.setFromBuilders(ownedCronJobOnly)); storageUtil.expectTaskFetch(query); expect(storageUtil.jobStore.fetchJobs()) .andReturn(IJobConfiguration.setFromBuilders(bothCronJobs)); storageUtil.expectTaskFetch(query, ownedImmediateTask); expect(storageUtil.jobStore.fetchJobs()) .andReturn(IJobConfiguration.setFromBuilders(unownedCronJobOnly)); storageUtil.expectTaskFetch(query); expect(storageUtil.jobStore.fetchJobs()).andReturn(ImmutableSet.of()); storageUtil.expectTaskFetch(query, ownedCronJobScheduledTask); expect(storageUtil.jobStore.fetchJobs()) .andReturn(IJobConfiguration.setFromBuilders(ImmutableSet.of(ownedCronJob))); control.replay(); assertEquals(jobSummaryResponse(ownedCronJobSummaryOnly), thrift.getJobSummary(ROLE)); assertEquals(jobSummaryResponse(ownedCronJobSummaryOnly), thrift.getJobSummary(ROLE)); Response jobSummaryResponse = thrift.getJobSummary(ROLE); assertEquals( jobSummaryResponse(ownedImmediateJobSummaryOnly), IResponse.build(jobSummaryResponse).newBuilder()); assertEquals(jobSummaryResponse(ImmutableSet.of()), thrift.getJobSummary(ROLE)); assertEquals(jobSummaryResponse(ownedCronJobSummaryWithRunningTask), thrift.getJobSummary(ROLE)); }
@Test public void testGetJobSummaryWithoutNextRun() throws Exception { String cronSchedule = "* * 31 2 *"; TaskConfig task = nonProductionTask() .setJob(JOB_KEY.newBuilder()) .setOwner(IDENTITY); JobConfiguration job = makeJob() .setCronSchedule(cronSchedule) .setTaskConfig(task); expect(cronPredictor.predictNextRun(CrontabEntry.parse(cronSchedule))) .andReturn(Optional.absent()) .anyTimes(); storageUtil.expectTaskFetch(Query.roleScoped(ROLE)); Set<JobConfiguration> jobOnly = ImmutableSet.of(job); expect(storageUtil.jobStore.fetchJobs()) .andReturn(IJobConfiguration.setFromBuilders(jobOnly)); control.replay(); JobSummaryResult result = thrift.getJobSummary(ROLE).getResult().getJobSummaryResult(); assertEquals(1, result.getSummaries().size()); assertFalse(result.getSummariesIterator().next().isSetNextCronRunMs()); }