package org.ohdsi.webapi.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.ohdsi.sql.SqlRender;
import org.ohdsi.sql.SqlTranslate;
import org.ohdsi.webapi.helper.ResourceHelper;
import org.ohdsi.webapi.job.JobExecutionResource;
import org.ohdsi.webapi.job.JobInstanceResource;
import org.ohdsi.webapi.job.JobUtils;
import org.springframework.batch.admin.service.SearchableJobExecutionDao;
import org.springframework.batch.admin.service.SearchableJobInstanceDao;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.configuration.JobLocator;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.launch.NoSuchJobException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.stereotype.Component;
/**
*
*/
@Path("/job/")
@Component
public class JobService extends AbstractDaoService {
@Autowired
private String batchTablePrefix;
@Autowired
private JobExplorer jobExplorer;
@Autowired
private JobLocator jobLocator;
@Autowired
private SearchableJobExecutionDao jobExecutionDao;
@Autowired
private SearchableJobInstanceDao jobInstanceDao;
@GET
@Path("{jobId}")
@Produces(MediaType.APPLICATION_JSON)
public JobInstanceResource findJob(@PathParam("jobId") final Long jobId) {
final JobInstance job = this.jobExplorer.getJobInstance(jobId);
if (job == null) {
return null;//TODO #8 conventions under review
}
return JobUtils.toJobInstanceResource(job);
}
@GET
@Path("{jobId}/execution/{executionId}")
@Produces(MediaType.APPLICATION_JSON)
public JobExecutionResource findJobExecution(@PathParam("jobId") final Long jobId,
@PathParam("executionId") final Long executionId) {
return service(jobId, executionId);
}
/**
* Overloaded findJobExecution method.
*
* @param executionId
* @return
*/
@GET
@Path("/execution/{executionId}")
@Produces(MediaType.APPLICATION_JSON)
public JobExecutionResource findJobExecution(@PathParam("executionId") final Long executionId) {
return service(null, executionId);
}
private JobExecutionResource service(final Long jobId, final Long executionId) {
final JobExecution exec = this.jobExplorer.getJobExecution(executionId);
if ((exec == null) || ((jobId != null) && !jobId.equals(exec.getJobId()))) {
return null;//TODO #8 conventions under review
}
return JobUtils.toJobExecutionResource(exec);
}
/**
* Get job names (unique names). Note: this path (GET /job) should really
* return pages of job instances. This could be implemented should the need
* arise. See {@link JobService#list(String, Integer, Integer)} to obtain
* executions and filter by job name.
*
* @return
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<String> findJobNames() {
return this.jobExplorer.getJobNames();
}
/**
* <i>Variation of spring-batch-admin support:
* org.springframework.batch.admin.web.BatchJobExecutionsController</i>.
* <p>
* Return a paged collection of job executions. Filter for a given job.
* Returned in pages.
*
* @param jobName name of the job
* @param pageIndex start index for the job execution list
* @param pageSize page size for the list
* @param comprehensivePage boolean if true returns a comprehensive resultset
* as a page (i.e. pageRequest(0,resultset.size()))
* @return collection of JobExecutionInfo
* @throws NoSuchJobException
*/
@GET
@Path("/execution")
@Produces(MediaType.APPLICATION_JSON)
public Page<JobExecutionResource> list(@QueryParam("jobName") final String jobName,
@DefaultValue("0") @QueryParam("pageIndex") final Integer pageIndex,
@DefaultValue("20") @QueryParam("pageSize") final Integer pageSize,
@QueryParam("comprehensivePage") boolean comprehensivePage)
throws NoSuchJobException {
List<JobExecutionResource> resources = null;
if (comprehensivePage) {
String sql_statement = ResourceHelper.GetResourceAsString("/resources/job/sql/jobExecutions.sql");
sql_statement = SqlRender.renderSql(sql_statement, new String[]{"ohdsi_schema"},
new String[]{this.getOhdsiSchema()});
sql_statement = SqlTranslate.translateSql(sql_statement, "sql server", getDialect());
log.debug("Translated sql:" + sql_statement);
resources = getJdbcTemplate().query(sql_statement, new ResultSetExtractor<List<JobExecutionResource>>() {
@Override
public List<JobExecutionResource> extractData(ResultSet rs) throws SQLException, DataAccessException {
return JobUtils.toJobExecutionResource(rs);
}
});
return new PageImpl<JobExecutionResource>(resources, new PageRequest(0, pageSize), resources.size());
} else {
resources = new ArrayList<JobExecutionResource>();
for (final JobExecution jobExecution : (jobName == null ? this.jobExecutionDao.getJobExecutions(pageIndex,
pageSize) : this.jobExecutionDao.getJobExecutions(jobName, pageIndex, pageSize))) {
resources.add(JobUtils.toJobExecutionResource(jobExecution));
}
return new PageImpl<JobExecutionResource>(resources, new PageRequest(pageIndex, pageSize),
this.jobExecutionDao.countJobExecutions());
}
}
}