AMBARI-21071. Ambari Infra Manager: add jobs/steps REST API endpoints (oleewere)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9ffef7fc Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9ffef7fc Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9ffef7fc Branch: refs/heads/branch-feature-AMBARI-12556 Commit: 9ffef7fc58b4313dfdf8d96badce5198855934a7 Parents: c23602c Author: oleewere <[email protected]> Authored: Fri May 19 14:41:42 2017 +0200 Committer: oleewere <[email protected]> Committed: Sat May 20 12:51:51 2017 +0200 ---------------------------------------------------------------------- .../org/apache/ambari/infra/InfraManager.java | 1 + .../conf/batch/InfraManagerBatchConfig.java | 55 ++++ .../apache/ambari/infra/manager/JobManager.java | 274 +++++++++++++++++++ .../infra/model/ExecutionContextResponse.java | 40 +++ .../ambari/infra/model/JobDetailsResponse.java | 53 ++++ .../model/JobExecutionDetailsResponse.java | 49 ++++ .../infra/model/JobExecutionInfoResponse.java | 141 ++++++++++ .../ambari/infra/model/JobExecutionRequest.java | 46 ++++ .../infra/model/JobExecutionRestartRequest.java | 52 ++++ .../infra/model/JobExecutionStopRequest.java | 50 ++++ .../infra/model/JobInstanceDetailsResponse.java | 54 ++++ .../infra/model/JobInstanceStartRequest.java | 49 ++++ .../ambari/infra/model/JobOperationParams.java | 31 +++ .../apache/ambari/infra/model/JobRequest.java | 37 +++ .../apache/ambari/infra/model/PageRequest.java | 49 ++++ .../model/StepExecutionContextResponse.java | 58 ++++ .../infra/model/StepExecutionInfoResponse.java | 115 ++++++++ .../model/StepExecutionProgressResponse.java | 53 ++++ .../infra/model/StepExecutionRequest.java | 49 ++++ .../infra/model/wrapper/JobExecutionData.java | 118 ++++++++ .../infra/model/wrapper/StepExecutionData.java | 133 +++++++++ .../ambari/infra/rest/JobExceptionMapper.java | 110 ++++++++ .../apache/ambari/infra/rest/JobResource.java | 151 ++++++++-- 23 files changed, 1748 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/InfraManager.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/InfraManager.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/InfraManager.java index 656127e..227bab4 100644 --- a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/InfraManager.java +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/InfraManager.java @@ -142,6 +142,7 @@ public class InfraManager { ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/api/v1/*"); jerseyServlet.setInitOrder(1); jerseyServlet.setInitParameter("jersey.config.server.provider.packages","org.apache.ambari.infra.rest,io.swagger.jaxrs.listing"); + context.getSessionHandler().getSessionManager().setMaxInactiveInterval(SESSION_TIMEOUT); context.getSessionHandler().getSessionManager().getSessionCookieConfig().setName(INFRA_MANAGER_SESSION_ID); http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/conf/batch/InfraManagerBatchConfig.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/conf/batch/InfraManagerBatchConfig.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/conf/batch/InfraManagerBatchConfig.java index 7310626..c3d8db6 100644 --- a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/conf/batch/InfraManagerBatchConfig.java +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/conf/batch/InfraManagerBatchConfig.java @@ -21,6 +21,14 @@ package org.apache.ambari.infra.conf.batch; import org.apache.ambari.infra.job.dummy.DummyItemProcessor; import org.apache.ambari.infra.job.dummy.DummyItemWriter; import org.apache.ambari.infra.job.dummy.DummyObject; +import org.springframework.batch.admin.service.JdbcSearchableJobExecutionDao; +import org.springframework.batch.admin.service.JdbcSearchableJobInstanceDao; +import org.springframework.batch.admin.service.JdbcSearchableStepExecutionDao; +import org.springframework.batch.admin.service.JobService; +import org.springframework.batch.admin.service.SearchableJobExecutionDao; +import org.springframework.batch.admin.service.SearchableJobInstanceDao; +import org.springframework.batch.admin.service.SearchableStepExecutionDao; +import org.springframework.batch.admin.service.SimpleJobService; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.JobRegistry; @@ -34,6 +42,9 @@ import org.springframework.batch.core.launch.JobOperator; import org.springframework.batch.core.launch.support.SimpleJobLauncher; import org.springframework.batch.core.launch.support.SimpleJobOperator; import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.repository.dao.DefaultExecutionContextSerializer; +import org.springframework.batch.core.repository.dao.ExecutionContextDao; +import org.springframework.batch.core.repository.dao.JdbcExecutionContextDao; import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemReader; @@ -53,6 +64,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.task.SimpleAsyncTaskExecutor; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.jdbc.datasource.init.DataSourceInitializer; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; @@ -166,6 +178,49 @@ public class InfraManagerBatchConfig { return jobRegistryBeanPostProcessor; } + @Bean + public JdbcTemplate jdbcTemplate() { + return new JdbcTemplate(dataSource()); + } + + @Bean + public SearchableJobInstanceDao searchableJobInstanceDao() { + JdbcSearchableJobInstanceDao dao = new JdbcSearchableJobInstanceDao(); + dao.setJdbcTemplate(jdbcTemplate()); + return dao; + } + + @Bean + public SearchableJobExecutionDao searchableJobExecutionDao() { + JdbcSearchableJobExecutionDao dao = new JdbcSearchableJobExecutionDao(); + dao.setJdbcTemplate(jdbcTemplate()); + dao.setDataSource(dataSource()); + return dao; + } + + @Bean + public SearchableStepExecutionDao searchableStepExecutionDao() { + JdbcSearchableStepExecutionDao dao = new JdbcSearchableStepExecutionDao(); + dao.setDataSource(dataSource()); + dao.setJdbcTemplate(jdbcTemplate()); + return dao; + } + + @Bean + public ExecutionContextDao executionContextDao() { + JdbcExecutionContextDao dao = new JdbcExecutionContextDao(); + dao.setSerializer(new DefaultExecutionContextSerializer()); + dao.setJdbcTemplate(jdbcTemplate()); + return dao; + } + + @Bean + public JobService jobService() throws Exception { + return new + SimpleJobService(searchableJobInstanceDao(), searchableJobExecutionDao(), searchableStepExecutionDao(), + jobRepository(), jobLauncher(), jobRegistry, executionContextDao()); + } + @Bean(name = "dummyStep") protected Step dummyStep(ItemReader<DummyObject> reader, ItemProcessor<DummyObject, String> processor, http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/manager/JobManager.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/manager/JobManager.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/manager/JobManager.java new file mode 100644 index 0000000..fc0a4f7 --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/manager/JobManager.java @@ -0,0 +1,274 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.manager; + +import com.google.common.collect.Lists; +import org.apache.ambari.infra.model.ExecutionContextResponse; +import org.apache.ambari.infra.model.JobDetailsResponse; +import org.apache.ambari.infra.model.JobExecutionDetailsResponse; +import org.apache.ambari.infra.model.JobExecutionInfoResponse; +import org.apache.ambari.infra.model.JobInstanceDetailsResponse; +import org.apache.ambari.infra.model.JobOperationParams; +import org.apache.ambari.infra.model.StepExecutionContextResponse; +import org.apache.ambari.infra.model.StepExecutionInfoResponse; +import org.apache.ambari.infra.model.StepExecutionProgressResponse; +import org.springframework.batch.admin.history.StepExecutionHistory; +import org.springframework.batch.admin.service.JobService; +import org.springframework.batch.admin.service.NoSuchStepExecutionException; +import org.springframework.batch.admin.web.JobInfo; +import org.springframework.batch.admin.web.StepExecutionProgress; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobInstance; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.JobParametersInvalidException; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.launch.JobExecutionNotRunningException; +import org.springframework.batch.core.launch.JobInstanceAlreadyExistsException; +import org.springframework.batch.core.launch.JobOperator; +import org.springframework.batch.core.launch.NoSuchJobException; +import org.springframework.batch.core.launch.NoSuchJobExecutionException; +import org.springframework.batch.core.launch.NoSuchJobInstanceException; +import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; +import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; +import org.springframework.batch.core.repository.JobRestartException; + +import javax.inject.Inject; +import javax.inject.Named; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TimeZone; + +@Named +public class JobManager { + + @Inject + private JobService jobService; + + @Inject + private JobOperator jobOperator; + + private TimeZone timeZone = TimeZone.getDefault(); + + public Set<String> getAllJobNames() { + return jobOperator.getJobNames(); + } + + /** + * Launch a new job instance (based on job name) and applies customized parameters to it. + * Also add a new date parameter to make sure the job instance will be unique + */ + public JobExecutionInfoResponse launchJob(String jobName, String params) + throws JobParametersInvalidException, JobInstanceAlreadyExistsException, NoSuchJobException, + JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException { + // TODO: handle params + JobParametersBuilder jobParametersBuilder = new JobParametersBuilder(); + jobParametersBuilder.addDate("date", new Date()); + return new JobExecutionInfoResponse(jobService.launch(jobName, jobParametersBuilder.toJobParameters()), timeZone); + } + + /** + * Get all executions ids that mapped to specific job name, + */ + public Set<Long> getExecutionIdsByJobName(String jobName) throws NoSuchJobException { + return jobOperator.getRunningExecutions(jobName); + } + + /** + * Stop all running job executions and returns with the number of stopped jobs. + */ + public Integer stopAllJobs() { + return jobService.stopAll(); + } + + /** + * Gather job execution details by job execution id. + */ + public JobExecutionDetailsResponse getExectionInfo(Long jobExecutionId) throws NoSuchJobExecutionException { + JobExecution jobExecution = jobService.getJobExecution(jobExecutionId); + List<StepExecutionInfoResponse> stepExecutionInfos = new ArrayList<StepExecutionInfoResponse>(); + for (StepExecution stepExecution : jobExecution.getStepExecutions()) { + stepExecutionInfos.add(new StepExecutionInfoResponse(stepExecution, timeZone)); + } + Collections.sort(stepExecutionInfos, new Comparator<StepExecutionInfoResponse>() { + @Override + public int compare(StepExecutionInfoResponse o1, StepExecutionInfoResponse o2) { + return o1.getId().compareTo(o2.getId()); + } + }); + return new JobExecutionDetailsResponse(new JobExecutionInfoResponse(jobExecution, timeZone), stepExecutionInfos); + } + + /** + * Stop or abandon a running job execution by job execution id + */ + public JobExecutionInfoResponse stopOrAbandonJobByExecutionId(Long jobExecutionId, JobOperationParams.JobStopOrAbandonOperationParam operation) + throws NoSuchJobExecutionException, JobExecutionNotRunningException, JobExecutionAlreadyRunningException { + JobExecution jobExecution; + if (JobOperationParams.JobStopOrAbandonOperationParam.STOP.equals(operation)) { + jobExecution = jobService.stop(jobExecutionId); + } else if (JobOperationParams.JobStopOrAbandonOperationParam.ABANDON.equals(operation)) { + jobExecution = jobService.abandon(jobExecutionId); + } else { + throw new UnsupportedOperationException("Unsupported operaration"); + } + return new JobExecutionInfoResponse(jobExecution, timeZone); + } + + /** + * Get execution context for a job execution instance. (context can be shipped between job executions) + */ + public ExecutionContextResponse getExecutionContextByJobExecutionId(Long executionId) throws NoSuchJobExecutionException { + JobExecution jobExecution = jobService.getJobExecution(executionId); + Map<String, Object> executionMap = new HashMap<>(); + for (Map.Entry<String, Object> entry : jobExecution.getExecutionContext().entrySet()) { + executionMap.put(entry.getKey(), entry.getValue()); + } + return new ExecutionContextResponse(executionId, executionMap); + } + + /** + * Restart a specific job instance with the same parameters. (only restart operation is supported here) + */ + public JobExecutionInfoResponse restart(Long jobInstanceId, String jobName, + JobOperationParams.JobRestartOperationParam operation) throws NoSuchJobException, JobParametersInvalidException, + JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, NoSuchJobExecutionException { + if (JobOperationParams.JobRestartOperationParam.RESTART.equals(operation)) { + Collection<JobExecution> jobExecutions = jobService.getJobExecutionsForJobInstance(jobName, jobInstanceId); + JobExecution jobExecution = jobExecutions.iterator().next(); + Long jobExecutionId = jobExecution.getId(); + return new JobExecutionInfoResponse(jobService.restart(jobExecutionId), timeZone); + } else { + throw new UnsupportedOperationException("Unsupported operation (try: RESTART)"); + } + } + + /** + * Get all job details. (paged) + */ + public List<JobInfo> getAllJobs(int start, int pageSize) { + List<JobInfo> jobs = new ArrayList<>(); + Collection<String> names = jobService.listJobs(start, pageSize); + for (String name : names) { + int count = 0; + try { + count = jobService.countJobExecutionsForJob(name); + } + catch (NoSuchJobException e) { + // shouldn't happen + } + boolean launchable = jobService.isLaunchable(name); + boolean incrementable = jobService.isIncrementable(name); + jobs.add(new JobInfo(name, count, null, launchable, incrementable)); + } + return jobs; + } + + /** + * Get all executions for unique job instance. + */ + public List<JobExecutionInfoResponse> getExecutionsForJobInstance(String jobName, Long jobInstanceId) throws NoSuchJobInstanceException, NoSuchJobException { + List<JobExecutionInfoResponse> result = Lists.newArrayList(); + JobInstance jobInstance = jobService.getJobInstance(jobInstanceId); + Collection<JobExecution> jobExecutions = jobService.getJobExecutionsForJobInstance(jobName, jobInstance.getInstanceId()); + for (JobExecution jobExecution : jobExecutions) { + result.add(new JobExecutionInfoResponse(jobExecution, timeZone)); + } + return result; + } + + /** + * Get job details for a specific job. (paged) + */ + public JobDetailsResponse getJobDetails(String jobName, int page, int size) throws NoSuchJobException { + List<JobInstanceDetailsResponse> jobInstanceResponses = Lists.newArrayList(); + Collection<JobInstance> jobInstances = jobService.listJobInstances(jobName, page, size); + + int count = jobService.countJobExecutionsForJob(jobName); + boolean launchable = jobService.isLaunchable(jobName); + boolean isIncrementable = jobService.isIncrementable(jobName); + + for (JobInstance jobInstance: jobInstances) { + List<JobExecutionInfoResponse> executionInfos = Lists.newArrayList(); + Collection<JobExecution> jobExecutions = jobService.getJobExecutionsForJobInstance(jobName, jobInstance.getId()); + if (jobExecutions != null) { + for (JobExecution jobExecution : jobExecutions) { + executionInfos.add(new JobExecutionInfoResponse(jobExecution, timeZone)); + } + } + jobInstanceResponses.add(new JobInstanceDetailsResponse(jobInstance, executionInfos)); + } + return new JobDetailsResponse(new JobInfo(jobName, count, launchable, isIncrementable), jobInstanceResponses); + } + + /** + * Get step execution details based for job execution id and step execution id. + */ + public StepExecutionInfoResponse getStepExecution(Long jobExecutionId, Long stepExecutionId) throws NoSuchStepExecutionException, NoSuchJobExecutionException { + StepExecution stepExecution = jobService.getStepExecution(jobExecutionId, stepExecutionId); + return new StepExecutionInfoResponse(stepExecution, timeZone); + } + + /** + * Get step execution context details. (execution context can be shipped between steps) + */ + public StepExecutionContextResponse getStepExecutionContext(Long jobExecutionId, Long stepExecutionId) throws NoSuchStepExecutionException, NoSuchJobExecutionException { + StepExecution stepExecution = jobService.getStepExecution(jobExecutionId, stepExecutionId); + Map<String, Object> executionMap = new HashMap<>(); + for (Map.Entry<String, Object> entry : stepExecution.getExecutionContext().entrySet()) { + executionMap.put(entry.getKey(), entry.getValue()); + } + return new StepExecutionContextResponse(executionMap, jobExecutionId, stepExecutionId, stepExecution.getStepName()); + } + + /** + * Get step execution progress status detauls. + */ + public StepExecutionProgressResponse getStepExecutionProgress(Long jobExecutionId, Long stepExecutionId) throws NoSuchStepExecutionException, NoSuchJobExecutionException { + StepExecution stepExecution = jobService.getStepExecution(jobExecutionId, stepExecutionId); + StepExecutionInfoResponse stepExecutionInfoResponse = new StepExecutionInfoResponse(stepExecution, timeZone); + String stepName = stepExecution.getStepName(); + if (stepName.contains(":partition")) { + stepName = stepName.replaceAll("(:partition).*", "$1*"); + } + String jobName = stepExecution.getJobExecution().getJobInstance().getJobName(); + StepExecutionHistory stepExecutionHistory = computeHistory(jobName, stepName); + StepExecutionProgress stepExecutionProgress = new StepExecutionProgress(stepExecution, stepExecutionHistory); + + return new StepExecutionProgressResponse(stepExecutionProgress, stepExecutionHistory, stepExecutionInfoResponse); + + } + + private StepExecutionHistory computeHistory(String jobName, String stepName) { + int total = jobService.countStepExecutionsForStep(jobName, stepName); + StepExecutionHistory stepExecutionHistory = new StepExecutionHistory(stepName); + for (int i = 0; i < total; i += 1000) { + for (StepExecution stepExecution : jobService.listStepExecutionsForStep(jobName, stepName, i, 1000)) { + stepExecutionHistory.append(stepExecution); + } + } + return stepExecutionHistory; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/ExecutionContextResponse.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/ExecutionContextResponse.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/ExecutionContextResponse.java new file mode 100644 index 0000000..2d46c54 --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/ExecutionContextResponse.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import java.util.Map; + +public class ExecutionContextResponse { + + private final Long jobExecutionId; + private final Map<String, Object> executionContextMap; + + public ExecutionContextResponse(Long jobExecutionId, Map<String, Object> executionContextMap) { + this.jobExecutionId = jobExecutionId; + this.executionContextMap = executionContextMap; + } + + public Long getJobExecutionId() { + return jobExecutionId; + } + + public Map<String, Object> getExecutionContextMap() { + return executionContextMap; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobDetailsResponse.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobDetailsResponse.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobDetailsResponse.java new file mode 100644 index 0000000..cd34fef --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobDetailsResponse.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import org.springframework.batch.admin.web.JobInfo; + +import java.util.List; + +public class JobDetailsResponse { + + private JobInfo jobInfo; + private List<JobInstanceDetailsResponse> jobInstanceDetailsResponseList; + + public JobDetailsResponse() { + } + + public JobDetailsResponse(JobInfo jobInfo, List<JobInstanceDetailsResponse> jobInstanceDetailsResponseList) { + this.jobInfo = jobInfo; + this.jobInstanceDetailsResponseList = jobInstanceDetailsResponseList; + } + + public JobInfo getJobInfo() { + return jobInfo; + } + + public void setJobInfo(JobInfo jobInfo) { + this.jobInfo = jobInfo; + } + + public List<JobInstanceDetailsResponse> getJobInstanceDetailsResponseList() { + return jobInstanceDetailsResponseList; + } + + public void setJobInstanceDetailsResponseList(List<JobInstanceDetailsResponse> jobInstanceDetailsResponseList) { + this.jobInstanceDetailsResponseList = jobInstanceDetailsResponseList; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionDetailsResponse.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionDetailsResponse.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionDetailsResponse.java new file mode 100644 index 0000000..695b57f --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionDetailsResponse.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import java.util.List; + +public class JobExecutionDetailsResponse { + + private JobExecutionInfoResponse jobExecutionInfoResponse; + + private List<StepExecutionInfoResponse> stepExecutionInfoList; + + public JobExecutionDetailsResponse(JobExecutionInfoResponse jobExecutionInfoResponse, List<StepExecutionInfoResponse> stepExecutionInfoList) { + this.jobExecutionInfoResponse = jobExecutionInfoResponse; + this.stepExecutionInfoList = stepExecutionInfoList; + } + + public JobExecutionInfoResponse getJobExecutionInfoResponse() { + return jobExecutionInfoResponse; + } + + public void setJobExecutionInfoResponse(JobExecutionInfoResponse jobExecutionInfoResponse) { + this.jobExecutionInfoResponse = jobExecutionInfoResponse; + } + + public List<StepExecutionInfoResponse> getStepExecutionInfoList() { + return stepExecutionInfoList; + } + + public void setStepExecutionInfoList(List<StepExecutionInfoResponse> stepExecutionInfoList) { + this.stepExecutionInfoList = stepExecutionInfoList; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionInfoResponse.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionInfoResponse.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionInfoResponse.java new file mode 100644 index 0000000..a7e4a4f --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionInfoResponse.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import org.apache.ambari.infra.model.wrapper.JobExecutionData; +import org.springframework.batch.admin.web.JobParametersExtractor; +import org.springframework.batch.core.BatchStatus; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobInstance; +import org.springframework.batch.core.converter.DefaultJobParametersConverter; +import org.springframework.batch.core.converter.JobParametersConverter; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Properties; +import java.util.TimeZone; + +public class JobExecutionInfoResponse { + private Long id; + private int stepExecutionCount; + private Long jobId; + private String jobName; + private String startDate = ""; + private String startTime = ""; + private String duration = ""; + private JobExecutionData jobExecutionData; + private Properties jobParameters; + private String jobParametersString; + private boolean restartable = false; + private boolean abandonable = false; + private boolean stoppable = false; + private final TimeZone timeZone; + + + public JobExecutionInfoResponse(JobExecution jobExecution, TimeZone timeZone) { + JobParametersConverter converter = new DefaultJobParametersConverter(); + this.jobExecutionData = new JobExecutionData(jobExecution); + this.timeZone = timeZone; + this.id = jobExecutionData.getId(); + this.jobId = jobExecutionData.getJobId(); + this.stepExecutionCount = jobExecutionData.getStepExecutions().size(); + this.jobParameters = converter.getProperties(jobExecutionData.getJobParameters()); + this.jobParametersString = (new JobParametersExtractor()).fromJobParameters(jobExecutionData.getJobParameters()); + JobInstance jobInstance = jobExecutionData.getJobInstance(); + if(jobInstance != null) { + this.jobName = jobInstance.getJobName(); + BatchStatus endTime = jobExecutionData.getStatus(); + this.restartable = endTime.isGreaterThan(BatchStatus.STOPPING) && endTime.isLessThan(BatchStatus.ABANDONED); + this.abandonable = endTime.isGreaterThan(BatchStatus.STARTED) && endTime != BatchStatus.ABANDONED; + this.stoppable = endTime.isLessThan(BatchStatus.STOPPING); + } else { + this.jobName = "?"; + } + + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); + SimpleDateFormat durationFormat = new SimpleDateFormat("HH:mm:ss"); + + durationFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + timeFormat.setTimeZone(timeZone); + dateFormat.setTimeZone(timeZone); + if(jobExecutionData.getStartTime() != null) { + this.startDate = dateFormat.format(jobExecutionData.getStartTime()); + this.startTime = timeFormat.format(jobExecutionData.getStartTime()); + Date endTime1 = jobExecutionData.getEndTime() != null? jobExecutionData.getEndTime():new Date(); + this.duration = durationFormat.format(new Date(endTime1.getTime() - jobExecutionData.getStartTime().getTime())); + } + } + + public Long getId() { + return id; + } + + public int getStepExecutionCount() { + return stepExecutionCount; + } + + public Long getJobId() { + return jobId; + } + + public String getJobName() { + return jobName; + } + + public String getStartDate() { + return startDate; + } + + public String getStartTime() { + return startTime; + } + + public String getDuration() { + return duration; + } + + public JobExecutionData getJobExecutionData() { + return jobExecutionData; + } + + public Properties getJobParameters() { + return jobParameters; + } + + public String getJobParametersString() { + return jobParametersString; + } + + public boolean isRestartable() { + return restartable; + } + + public boolean isAbandonable() { + return abandonable; + } + + public boolean isStoppable() { + return stoppable; + } + + public TimeZone getTimeZone() { + return timeZone; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionRequest.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionRequest.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionRequest.java new file mode 100644 index 0000000..b4c20e9 --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionRequest.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import javax.ws.rs.PathParam; + +public class JobExecutionRequest { + + @PathParam("jobName") + private String jobName; + + @PathParam("jobInstanceId") + private Long jobInstanceId; + + public String getJobName() { + return jobName; + } + + public Long getJobInstanceId() { + return jobInstanceId; + } + + public void setJobName(String jobName) { + this.jobName = jobName; + } + + public void setJobInstanceId(Long jobInstanceId) { + this.jobInstanceId = jobInstanceId; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionRestartRequest.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionRestartRequest.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionRestartRequest.java new file mode 100644 index 0000000..88687e7 --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionRestartRequest.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +public class JobExecutionRestartRequest { + + private String jobName; + + private Long jobInstanceId; + + private JobOperationParams.JobRestartOperationParam operation; + + public String getJobName() { + return jobName; + } + + public void setJobName(String jobName) { + this.jobName = jobName; + } + + public Long getJobInstanceId() { + return jobInstanceId; + } + + public void setJobExecutionId(Long jobExecutionId) { + this.jobInstanceId = jobExecutionId; + } + + public JobOperationParams.JobRestartOperationParam getOperation() { + return operation; + } + + public void setOperation(JobOperationParams.JobRestartOperationParam operation) { + this.operation = operation; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionStopRequest.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionStopRequest.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionStopRequest.java new file mode 100644 index 0000000..b176f12 --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobExecutionStopRequest.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import javax.validation.constraints.NotNull; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; + +public class JobExecutionStopRequest { + + @PathParam("jobExecutionId") + @NotNull + private Long jobExecutionId; + + @QueryParam("operation") + @NotNull + private JobOperationParams.JobStopOrAbandonOperationParam operation; + + public Long getJobExecutionId() { + return jobExecutionId; + } + + public void setJobExecutionId(Long jobExecutionId) { + this.jobExecutionId = jobExecutionId; + } + + public JobOperationParams.JobStopOrAbandonOperationParam getOperation() { + return operation; + } + + public void setOperation(JobOperationParams.JobStopOrAbandonOperationParam operation) { + this.operation = operation; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobInstanceDetailsResponse.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobInstanceDetailsResponse.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobInstanceDetailsResponse.java new file mode 100644 index 0000000..af88654 --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobInstanceDetailsResponse.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import org.springframework.batch.core.JobInstance; + +import java.util.List; + +public class JobInstanceDetailsResponse { + + private JobInstance jobInstance; + + private List<JobExecutionInfoResponse> jobExecutionInfoResponseList; + + public JobInstanceDetailsResponse() { + } + + public JobInstanceDetailsResponse(JobInstance jobInstance, List<JobExecutionInfoResponse> jobExecutionInfoResponseList) { + this.jobInstance = jobInstance; + this.jobExecutionInfoResponseList = jobExecutionInfoResponseList; + } + + public JobInstance getJobInstance() { + return jobInstance; + } + + public void setJobInstance(JobInstance jobInstance) { + this.jobInstance = jobInstance; + } + + public List<JobExecutionInfoResponse> getJobExecutionInfoResponseList() { + return jobExecutionInfoResponseList; + } + + public void setJobExecutionInfoResponseList(List<JobExecutionInfoResponse> jobExecutionInfoResponseList) { + this.jobExecutionInfoResponseList = jobExecutionInfoResponseList; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobInstanceStartRequest.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobInstanceStartRequest.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobInstanceStartRequest.java new file mode 100644 index 0000000..905a4fa --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobInstanceStartRequest.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import javax.validation.constraints.NotNull; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; + +public class JobInstanceStartRequest { + + @PathParam("jobName") + @NotNull + private String jobName; + + @QueryParam("params") + String params; + + public String getJobName() { + return jobName; + } + + public void setJobName(String jobName) { + this.jobName = jobName; + } + + public String getParams() { + return params; + } + + public void setParams(String params) { + this.params = params; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobOperationParams.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobOperationParams.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobOperationParams.java new file mode 100644 index 0000000..e286deb --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobOperationParams.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +public class JobOperationParams { + + public enum JobStopOrAbandonOperationParam { + STOP, ABANDON; + } + + public enum JobRestartOperationParam { + RESTART; + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobRequest.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobRequest.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobRequest.java new file mode 100644 index 0000000..b4fd478 --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/JobRequest.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import javax.validation.constraints.NotNull; +import javax.ws.rs.PathParam; + +public class JobRequest extends PageRequest { + + @NotNull + @PathParam("jobName") + private String jobName; + + public String getJobName() { + return jobName; + } + + public void setJobName(String jobName) { + this.jobName = jobName; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/PageRequest.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/PageRequest.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/PageRequest.java new file mode 100644 index 0000000..679d4fd --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/PageRequest.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import javax.ws.rs.DefaultValue; +import javax.ws.rs.QueryParam; + +public class PageRequest { + + @QueryParam("page") + @DefaultValue("0") + private int page; + + @QueryParam("size") + @DefaultValue("20") + private int size; + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionContextResponse.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionContextResponse.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionContextResponse.java new file mode 100644 index 0000000..0e67a87 --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionContextResponse.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import java.util.Map; + +public class StepExecutionContextResponse { + + private Map<String, Object> executionContextMap; + + private Long jobExecutionId; + + private Long stepExecutionId; + + private String stepName; + + public StepExecutionContextResponse() { + } + + public StepExecutionContextResponse(Map<String, Object> executionContextMap, Long jobExecutionId, Long stepExecutionId, String stepName) { + this.executionContextMap = executionContextMap; + this.jobExecutionId = jobExecutionId; + this.stepExecutionId = stepExecutionId; + this.stepName = stepName; + } + + public Map<String, Object> getExecutionContextMap() { + return executionContextMap; + } + + public Long getJobExecutionId() { + return jobExecutionId; + } + + public Long getStepExecutionId() { + return stepExecutionId; + } + + public String getStepName() { + return stepName; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionInfoResponse.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionInfoResponse.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionInfoResponse.java new file mode 100644 index 0000000..ed04767 --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionInfoResponse.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.apache.ambari.infra.model.wrapper.StepExecutionData; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.StepExecution; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +public class StepExecutionInfoResponse { + private Long id; + private Long jobExecutionId; + private String jobName; + private String name; + private String startDate = "-"; + private String startTime = "-"; + private String duration = "-"; + private StepExecutionData stepExecutionData; + private long durationMillis; + + public StepExecutionInfoResponse(String jobName, Long jobExecutionId, String name, TimeZone timeZone) { + this.jobName = jobName; + this.jobExecutionId = jobExecutionId; + this.name = name; + this.stepExecutionData = new StepExecutionData(new StepExecution(name, new JobExecution(jobExecutionId))); + } + + public StepExecutionInfoResponse(StepExecution stepExecution, TimeZone timeZone) { + this.stepExecutionData = new StepExecutionData(stepExecution); + this.id = stepExecutionData.getId(); + this.name = stepExecutionData.getStepName(); + this.jobName = stepExecutionData.getJobExecution() != null && stepExecutionData.getJobExecution().getJobInstance() != null? stepExecutionData.getJobExecution().getJobInstance().getJobName():"?"; + this.jobExecutionId = stepExecutionData.getJobExecutionId(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); + SimpleDateFormat durationFormat = new SimpleDateFormat("HH:mm:ss"); + + durationFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + timeFormat.setTimeZone(timeZone); + dateFormat.setTimeZone(timeZone); + if(stepExecutionData.getStartTime() != null) { + this.startDate = dateFormat.format(stepExecutionData.getStartTime()); + this.startTime = timeFormat.format(stepExecutionData.getStartTime()); + Date endTime = stepExecutionData.getEndTime() != null? stepExecutionData.getEndTime():new Date(); + this.durationMillis = endTime.getTime() - stepExecutionData.getStartTime().getTime(); + this.duration = durationFormat.format(new Date(this.durationMillis)); + } + + } + + public Long getId() { + return this.id; + } + + public Long getJobExecutionId() { + return this.jobExecutionId; + } + + public String getName() { + return this.name; + } + + public String getJobName() { + return this.jobName; + } + + public String getStartDate() { + return this.startDate; + } + + public String getStartTime() { + return this.startTime; + } + + public String getDuration() { + return this.duration; + } + + public long getDurationMillis() { + return this.durationMillis; + } + + public String getStatus() { + return this.id != null?this.stepExecutionData.getStatus().toString():"NONE"; + } + + public String getExitCode() { + return this.id != null?this.stepExecutionData.getExitStatus().getExitCode():"NONE"; + } + + @JsonIgnore + public StepExecutionData getStepExecution() { + return this.stepExecutionData; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionProgressResponse.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionProgressResponse.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionProgressResponse.java new file mode 100644 index 0000000..26f9ed4 --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionProgressResponse.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import org.springframework.batch.admin.history.StepExecutionHistory; +import org.springframework.batch.admin.web.StepExecutionProgress; + +public class StepExecutionProgressResponse { + + private StepExecutionProgress stepExecutionProgress; + + private StepExecutionHistory stepExecutionHistory; + + private StepExecutionInfoResponse stepExecutionInfoResponse; + + public StepExecutionProgressResponse() { + } + + public StepExecutionProgressResponse(StepExecutionProgress stepExecutionProgress, StepExecutionHistory stepExecutionHistory, + StepExecutionInfoResponse stepExecutionInfoResponse) { + this.stepExecutionProgress = stepExecutionProgress; + this.stepExecutionHistory = stepExecutionHistory; + this.stepExecutionInfoResponse = stepExecutionInfoResponse; + } + + public StepExecutionProgress getStepExecutionProgress() { + return stepExecutionProgress; + } + + public StepExecutionHistory getStepExecutionHistory() { + return stepExecutionHistory; + } + + public StepExecutionInfoResponse getStepExecutionInfoResponse() { + return stepExecutionInfoResponse; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionRequest.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionRequest.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionRequest.java new file mode 100644 index 0000000..2228171 --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/StepExecutionRequest.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model; + +import javax.validation.constraints.NotNull; +import javax.ws.rs.PathParam; + +public class StepExecutionRequest { + + @PathParam("jobExecutionId") + @NotNull + private Long jobExecutionId; + + @PathParam("stepExecutionId") + @NotNull + private Long stepExecutionId; + + public Long getJobExecutionId() { + return jobExecutionId; + } + + public void setJobExecutionId(Long jobExecutionId) { + this.jobExecutionId = jobExecutionId; + } + + public Long getStepExecutionId() { + return stepExecutionId; + } + + public void setStepExecutionId(Long stepExecutionId) { + this.stepExecutionId = stepExecutionId; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/wrapper/JobExecutionData.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/wrapper/JobExecutionData.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/wrapper/JobExecutionData.java new file mode 100644 index 0000000..28e262a --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/wrapper/JobExecutionData.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model.wrapper; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.google.common.collect.Lists; +import org.springframework.batch.core.BatchStatus; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobInstance; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.item.ExecutionContext; + +import java.util.Collection; +import java.util.Date; +import java.util.List; + +/** + * Wrapper for #{{@link JobExecution}} + */ +public class JobExecutionData { + + private JobExecution jobExecution; + + public JobExecutionData(JobExecution jobExecution) { + this.jobExecution = jobExecution; + } + + @JsonIgnore + public JobExecution getJobExecution() { + return jobExecution; + } + + @JsonIgnore + public Collection<StepExecution> getStepExecutions() { + return jobExecution.getStepExecutions(); + } + + public JobParameters getJobParameters() { + return jobExecution.getJobParameters(); + } + + public JobInstance getJobInstance() { + return jobExecution.getJobInstance(); + } + + public Collection<StepExecutionData> getStepExecutionDataList() { + List<StepExecutionData> stepExecutionDataList = Lists.newArrayList(); + Collection<StepExecution> stepExecutions = getStepExecutions(); + if (stepExecutions != null) { + for (StepExecution stepExecution : stepExecutions) { + stepExecutionDataList.add(new StepExecutionData(stepExecution)); + } + } + return stepExecutionDataList; + } + + public BatchStatus getStatus() { + return jobExecution.getStatus(); + } + + public Date getStartTime() { + return jobExecution.getStartTime(); + } + + public Date getCreateTime() { + return jobExecution.getCreateTime(); + } + + public Date getEndTime() { + return jobExecution.getEndTime(); + } + + public Date getLastUpdated() { + return jobExecution.getLastUpdated(); + } + + public ExitStatus getExitStatus() { + return jobExecution.getExitStatus(); + } + + public ExecutionContext getExecutionContext() { + return jobExecution.getExecutionContext(); + } + + public List<Throwable> getFailureExceptions() { + return jobExecution.getFailureExceptions(); + } + + public String getJobConfigurationName() { + return jobExecution.getJobConfigurationName(); + } + + public Long getId() { + return jobExecution.getId(); + } + + public Long getJobId() { + return jobExecution.getJobId(); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/wrapper/StepExecutionData.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/wrapper/StepExecutionData.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/wrapper/StepExecutionData.java new file mode 100644 index 0000000..26552ae --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/model/wrapper/StepExecutionData.java @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.model.wrapper; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.springframework.batch.core.BatchStatus; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.item.ExecutionContext; + +import java.util.Date; +import java.util.List; + +/** + * Wrapper for #{{@link StepExecution}} + */ +public class StepExecutionData { + + @JsonIgnore + private final JobExecution jobExecution; + + @JsonIgnore + private final StepExecution stepExecution; + + + public StepExecutionData(StepExecution stepExecution) { + this.stepExecution = stepExecution; + this.jobExecution = stepExecution.getJobExecution(); + } + + @JsonIgnore + public JobExecution getJobExecution() { + return jobExecution; + } + + @JsonIgnore + public StepExecution getStepExecution() { + return stepExecution; + } + + public String getStepName() { + return stepExecution.getStepName(); + } + + public int getReadCount() { + return stepExecution.getReadCount(); + } + + public BatchStatus getStatus() { + return stepExecution.getStatus(); + } + + public int getWriteCount() { + return stepExecution.getWriteCount(); + } + + public int getCommitCount() { + return stepExecution.getCommitCount(); + } + + public int getRollbackCount() { + return stepExecution.getRollbackCount(); + } + + public int getReadSkipCount() { + return stepExecution.getReadSkipCount(); + } + + public int getProcessSkipCount() { + return stepExecution.getProcessSkipCount(); + } + + public Date getStartTime() { + return stepExecution.getStartTime(); + } + + public int getWriteSkipCount() { + return stepExecution.getWriteSkipCount(); + } + + public Date getEndTime() { + return stepExecution.getEndTime(); + } + + public Date getLastUpdated() { + return stepExecution.getLastUpdated(); + } + + public ExecutionContext getExecutionContext() { + return stepExecution.getExecutionContext(); + } + + public ExitStatus getExitStatus() { + return stepExecution.getExitStatus(); + } + + public boolean isTerminateOnly() { + return stepExecution.isTerminateOnly(); + } + + public int getFilterCount() { + return stepExecution.getFilterCount(); + } + + public List<Throwable> getFailureExceptions() { + return stepExecution.getFailureExceptions(); + } + + public Long getId() { + return stepExecution.getId(); + } + + public Long getJobExecutionId() { + return stepExecution.getJobExecutionId(); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/rest/JobExceptionMapper.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/rest/JobExceptionMapper.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/rest/JobExceptionMapper.java new file mode 100644 index 0000000..079cce3 --- /dev/null +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/rest/JobExceptionMapper.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.ambari.infra.rest; + + +import com.google.common.collect.Maps; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.admin.service.NoSuchStepExecutionException; +import org.springframework.batch.core.JobParametersInvalidException; +import org.springframework.batch.core.launch.JobExecutionNotFailedException; +import org.springframework.batch.core.launch.JobExecutionNotRunningException; +import org.springframework.batch.core.launch.JobExecutionNotStoppedException; +import org.springframework.batch.core.launch.JobInstanceAlreadyExistsException; +import org.springframework.batch.core.launch.JobParametersNotFoundException; +import org.springframework.batch.core.launch.NoSuchJobException; +import org.springframework.batch.core.launch.NoSuchJobExecutionException; +import org.springframework.batch.core.launch.NoSuchJobInstanceException; +import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; +import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; +import org.springframework.batch.core.repository.JobRestartException; +import org.springframework.batch.core.step.NoSuchStepException; +import org.springframework.web.bind.MethodArgumentNotValidException; + +import javax.batch.operations.JobExecutionAlreadyCompleteException; +import javax.inject.Named; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; +import java.util.Map; + +@Named +@Provider +public class JobExceptionMapper implements ExceptionMapper<Throwable> { + + private static final Logger LOG = LoggerFactory.getLogger(JobExceptionMapper.class); + + private static final Map<Class, Response.Status> exceptionStatusCodeMap = Maps.newHashMap(); + + static { + exceptionStatusCodeMap.put(MethodArgumentNotValidException.class, Response.Status.BAD_REQUEST); + exceptionStatusCodeMap.put(NoSuchJobException.class, Response.Status.NOT_FOUND); + exceptionStatusCodeMap.put(NoSuchStepException.class, Response.Status.NOT_FOUND); + exceptionStatusCodeMap.put(NoSuchStepExecutionException.class, Response.Status.NOT_FOUND); + exceptionStatusCodeMap.put(NoSuchJobExecutionException.class, Response.Status.NOT_FOUND); + exceptionStatusCodeMap.put(NoSuchJobInstanceException.class, Response.Status.NOT_FOUND); + exceptionStatusCodeMap.put(JobExecutionNotRunningException.class, Response.Status.INTERNAL_SERVER_ERROR); + exceptionStatusCodeMap.put(JobExecutionNotStoppedException.class, Response.Status.INTERNAL_SERVER_ERROR); + exceptionStatusCodeMap.put(JobInstanceAlreadyExistsException.class, Response.Status.ACCEPTED); + exceptionStatusCodeMap.put(JobInstanceAlreadyCompleteException.class, Response.Status.ACCEPTED); + exceptionStatusCodeMap.put(JobExecutionAlreadyRunningException.class, Response.Status.ACCEPTED); + exceptionStatusCodeMap.put(JobExecutionAlreadyCompleteException.class, Response.Status.ACCEPTED); + exceptionStatusCodeMap.put(JobParametersNotFoundException.class, Response.Status.NOT_FOUND); + exceptionStatusCodeMap.put(JobExecutionNotFailedException.class, Response.Status.INTERNAL_SERVER_ERROR); + exceptionStatusCodeMap.put(JobRestartException.class, Response.Status.INTERNAL_SERVER_ERROR); + exceptionStatusCodeMap.put(JobParametersInvalidException.class, Response.Status.BAD_REQUEST); + } + + @Override + public Response toResponse(Throwable throwable) { + LOG.error("REST Exception occurred:", throwable); + Response.Status status = Response.Status.INTERNAL_SERVER_ERROR; + + for (Map.Entry<Class, Response.Status> entry : exceptionStatusCodeMap.entrySet()) { + if (throwable.getClass().isAssignableFrom(entry.getKey())) { + status = entry.getValue(); + LOG.info("Exception mapped to: {} with status code: {}", entry.getKey().getCanonicalName(), entry.getValue().getStatusCode()); + break; + } + } + + return Response.status(status).entity(new StatusMessage(throwable.getMessage(), status.getStatusCode())) + .type(MediaType.APPLICATION_JSON_TYPE).build(); + } + + private class StatusMessage { + private String message; + private int statusCode; + + StatusMessage(String message, int statusCode) { + this.message = message; + this.statusCode = statusCode; + } + + public String getMessage() { + return message; + } + + public int getStatusCode() { + return statusCode; + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9ffef7fc/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/rest/JobResource.java ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/rest/JobResource.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/rest/JobResource.java index 27fed40..7023957 100644 --- a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/rest/JobResource.java +++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/rest/JobResource.java @@ -20,23 +20,46 @@ package org.apache.ambari.infra.rest; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import org.springframework.batch.core.JobParametersBuilder; +import org.apache.ambari.infra.manager.JobManager; +import org.apache.ambari.infra.model.ExecutionContextResponse; +import org.apache.ambari.infra.model.JobDetailsResponse; +import org.apache.ambari.infra.model.JobExecutionDetailsResponse; +import org.apache.ambari.infra.model.JobExecutionInfoResponse; +import org.apache.ambari.infra.model.JobExecutionRequest; +import org.apache.ambari.infra.model.JobExecutionRestartRequest; +import org.apache.ambari.infra.model.JobExecutionStopRequest; +import org.apache.ambari.infra.model.JobInstanceStartRequest; +import org.apache.ambari.infra.model.JobRequest; +import org.apache.ambari.infra.model.PageRequest; +import org.apache.ambari.infra.model.StepExecutionContextResponse; +import org.apache.ambari.infra.model.StepExecutionInfoResponse; +import org.apache.ambari.infra.model.StepExecutionProgressResponse; +import org.apache.ambari.infra.model.StepExecutionRequest; +import org.springframework.batch.admin.service.NoSuchStepExecutionException; +import org.springframework.batch.admin.web.JobInfo; import org.springframework.batch.core.JobParametersInvalidException; -import org.springframework.batch.core.explore.JobExplorer; +import org.springframework.batch.core.launch.JobExecutionNotRunningException; import org.springframework.batch.core.launch.JobInstanceAlreadyExistsException; -import org.springframework.batch.core.launch.JobOperator; import org.springframework.batch.core.launch.NoSuchJobException; +import org.springframework.batch.core.launch.NoSuchJobExecutionException; +import org.springframework.batch.core.launch.NoSuchJobInstanceException; +import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; +import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; +import org.springframework.batch.core.repository.JobRestartException; import org.springframework.context.annotation.Scope; import javax.inject.Inject; import javax.inject.Named; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.ws.rs.BeanParam; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import java.util.Date; +import java.util.List; import java.util.Set; @Api(value = "jobs", description = "Job operations") @@ -46,35 +69,123 @@ import java.util.Set; public class JobResource { @Inject - private JobOperator jobOperator; + private JobManager jobManager; - @Inject - private JobExplorer jobExplorer; + @GET + @Produces({"application/json"}) + @ApiOperation("Get all jobs") + public List<JobInfo> getAllJobs(@BeanParam @Valid PageRequest request) { + return jobManager.getAllJobs(request.getPage(), request.getSize()); + } + + @POST + @Produces({"application/json"}) + @Path("{jobName}") + @ApiOperation("Start a new job instance by job name.") + public JobExecutionInfoResponse startJob(@BeanParam @Valid JobInstanceStartRequest request) + throws JobParametersInvalidException, JobInstanceAlreadyExistsException, NoSuchJobException, JobExecutionAlreadyRunningException, + JobRestartException, JobInstanceAlreadyCompleteException { + return jobManager.launchJob(request.getJobName(), request.getParams()); + } @GET @Produces({"application/json"}) + @Path("/info/names") @ApiOperation("Get all job names") public Set<String> getAllJobNames() { - return jobOperator.getJobNames(); + return jobManager.getAllJobNames(); + } + + @GET + @Produces({"application/json"}) + @Path("/info/{jobName}") + @ApiOperation("Get job details by job name.") + public JobDetailsResponse getJobDetails(@BeanParam @Valid JobRequest jobRequest) throws NoSuchJobException { + return jobManager.getJobDetails(jobRequest.getJobName(), jobRequest.getPage(), jobRequest.getSize()); + } + + @GET + @Path("{jobName}/executions") + @Produces({"application/json"}) + @ApiOperation("Get the id values of all the running job instances.") + public Set<Long> getExecutionIdsByJobName(@PathParam("jobName") @NotNull @Valid String jobName) throws NoSuchJobException { + return jobManager.getExecutionIdsByJobName(jobName); } @GET - @Path("executions/{jobName}") @Produces({"application/json"}) - @ApiOperation("Get the id values of all the running job instances by job name") - public Set<Long> getExecutionIdsByJobName( - @PathParam("jobName") String jobName) throws NoSuchJobException { - return jobOperator.getRunningExecutions(jobName); + @Path("/executions/{jobExecutionId}") + @ApiOperation("Get job and step details for job execution instance.") + public JobExecutionDetailsResponse getExectionInfo(@PathParam("jobExecutionId") @Valid Long jobExecutionId) throws NoSuchJobExecutionException { + return jobManager.getExectionInfo(jobExecutionId); + } + + @GET + @Produces({"application/json"}) + @Path("/executions/{jobExecutionId}/context") + @ApiOperation("Get execution context for specific job.") + public ExecutionContextResponse getExecutionContextByJobExecId(@PathParam("jobExecutionId") Long executionId) throws NoSuchJobExecutionException { + return jobManager.getExecutionContextByJobExecutionId(executionId); + } + + + @DELETE + @Produces({"application/json"}) + @Path("/executions/{jobExecutionId}") + @ApiOperation("Stop or abandon a running job execution.") + public JobExecutionInfoResponse stopOrAbandonJobExecution(@BeanParam @Valid JobExecutionStopRequest request) + throws NoSuchJobExecutionException, JobExecutionNotRunningException, JobExecutionAlreadyRunningException { + return jobManager.stopOrAbandonJobByExecutionId(request.getJobExecutionId(), request.getOperation()); + } + + @DELETE + @Produces({"application/json"}) + @Path("/executions") + @ApiOperation("Stop all job executions.") + public Integer stopAll() { + return jobManager.stopAllJobs(); + } + + @GET + @Produces({"application/json"}) + @Path("/{jobName}/{jobInstanceId}/executions") + @ApiOperation("Get execution for job instance.") + public List<JobExecutionInfoResponse> getExecutionsForInstance(@BeanParam @Valid JobExecutionRequest request) throws JobInstanceAlreadyCompleteException, + NoSuchJobExecutionException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException, NoSuchJobException, NoSuchJobInstanceException { + return jobManager.getExecutionsForJobInstance(request.getJobName(), request.getJobInstanceId()); } @POST @Produces({"application/json"}) - @Path("start/{jobName}") - public Long startJob(@PathParam("jobName") String jobName, @QueryParam("params") String params) - throws JobParametersInvalidException, JobInstanceAlreadyExistsException, NoSuchJobException { - JobParametersBuilder jobParametersBuilder = new JobParametersBuilder(); - jobParametersBuilder.addDate("date", new Date()); - return jobOperator.start(jobName, jobParametersBuilder.toJobParameters() + "," + params); + @Path("/{jobName}/{jobInstanceId}/executions") + @ApiOperation("Restart job instance.") + public JobExecutionInfoResponse restartJobInstance(@BeanParam @Valid JobExecutionRestartRequest request) throws JobInstanceAlreadyCompleteException, + NoSuchJobExecutionException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException, NoSuchJobException { + return jobManager.restart(request.getJobInstanceId(), request.getJobName(), request.getOperation()); + } + + @GET + @Produces({"application/json"}) + @Path("/executions/{jobExecutionId}/steps/{stepExecutionId}") + @ApiOperation("Get step execution details.") + public StepExecutionInfoResponse getStepExecution(@BeanParam @Valid StepExecutionRequest request) throws NoSuchStepExecutionException, NoSuchJobExecutionException { + return jobManager.getStepExecution(request.getJobExecutionId(), request.getStepExecutionId()); + } + + @GET + @Produces({"application/json"}) + @Path("/executions/{jobExecutionId}/steps/{stepExecutionId}/execution-context") + @ApiOperation("Get the execution context of step execution.") + public StepExecutionContextResponse getStepExecutionContext(@BeanParam @Valid StepExecutionRequest request) throws NoSuchStepExecutionException, NoSuchJobExecutionException { + return jobManager.getStepExecutionContext(request.getJobExecutionId(), request.getStepExecutionId()); + } + + @GET + @Produces({"application/json"}) + @Path("/executions/{jobExecutionId}/steps/{stepExecutionId}/progress") + @ApiOperation("Get progress of step execution.") + public StepExecutionProgressResponse getStepExecutionProgress(@BeanParam @Valid StepExecutionRequest request) throws NoSuchStepExecutionException, NoSuchJobExecutionException { + return jobManager.getStepExecutionProgress(request.getJobExecutionId(), request.getStepExecutionId()); } }
