Skip to content

Commit

Permalink
Added filter for date range for job executions
Browse files Browse the repository at this point in the history
Fixed javadoc

added test case for task executions by date range filter

Fixed formatting issue

Polishing on Merge Updated PR to include documentation for the end point.
  • Loading branch information
siddhantsorann authored and Glenn Renfro committed Sep 28, 2020
1 parent 1bfe0b1 commit 42b1720
Show file tree
Hide file tree
Showing 11 changed files with 203 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,33 @@ public void listThinJobExecutions() throws Exception {
)));
}

@Test
public void listThinJobExecutionsByDate() throws Exception {
this.mockMvc.perform(
get("/jobs/thinexecutions")
.param("page", "0")
.param("size", "10")
.param("fromDate", "2000-09-24T17:00:45,000")
.param("toDate", "2050-09-24T18:00:45,000"))
.andDo(print())
.andExpect(status().isOk()).andDo(this.documentationHandler.document(
requestParameters(
parameterWithName("page")
.description("The zero-based page number (optional)"),
parameterWithName("size")
.description("The requested page size (optional)"),
parameterWithName("fromDate")
.description("Filter result from a starting date in the format 'yyyy-MM-dd'T'HH:mm:ss,SSS'"),
parameterWithName("toDate")
.description("Filter result up to the `to` date in the format 'yyyy-MM-dd'T'HH:mm:ss,SSS'")),
responseFields(
subsectionWithPath("_embedded.jobExecutionThinResourceList")
.description("Contains a collection of Job Executions without step executions included/"),
subsectionWithPath("_links.self").description("Link to the job execution resource"),
subsectionWithPath("page").description("Pagination properties")
)));
}

@Test
public void listJobExecutionsByName() throws Exception {
this.mockMvc.perform(
Expand Down
40 changes: 40 additions & 0 deletions spring-cloud-dataflow-docs/src/main/asciidoc/api-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2091,6 +2091,7 @@ The following topics provide more details:
* <<api-guide-resources-job-executions-thin-job-execution-list>>
* <<api-guide-resources-job-executions-job-execution-info-only-list-by-name>>
* <<api-guide-resources-job-executions-thin-job-execution-info-only-list-by-name>>
* <<api-guide-resources-job-executions-thin-job-execution-info-only-list-by-date>>
* <<api-guide-resources-job-executions-detail>>
* <<api-guide-resources-job-executions-stop>>
* <<api-guide-resources-job-executions-restart>>
Expand Down Expand Up @@ -2253,6 +2254,45 @@ include::{snippets}/job-executions-documentation/list-thin-job-executions-by-nam

include::{snippets}/job-executions-documentation/list-thin-job-executions-by-name/http-response.adoc[]

[[api-guide-resources-job-executions-thin-job-execution-info-only-list-by-date]]
==== List All Job Executions For A Specified Date Range Without Step Executions Included

The job executions endpoint lets you list all job executions.
The following topics provide more details:

* <<api-guide-resources-job-executions-thin-list-by-date-request-structure>>
* <<api-guide-resources-job-executions-thin-list-by-date-request-parameters>>
* <<api-guide-resources-job-executions-thin-list-by-date-example-request>>
* <<api-guide-resources-job-executions-thin-list-by-date-response-structure>>



[[api-guide-resources-job-executions-thin-list-by-date-request-structure]]
===== Request Structure

include::{snippets}/job-executions-documentation/list-thin-job-executions-by-date/http-request.adoc[]



[[api-guide-resources-job-executions-thin-list-by-date-request-parameters]]
===== Request Parameters

include::{snippets}/job-executions-documentation/list-thin-job-executions-by-date/request-parameters.adoc[]



[[api-guide-resources-job-executions-thin-list-by-date-example-request]]
===== Example Request

include::{snippets}/job-executions-documentation/list-thin-job-executions-by-date/curl-request.adoc[]



[[api-guide-resources-job-executions-thin-list-by-date-response-structure]]
===== Response Structure

include::{snippets}/job-executions-documentation/list-thin-job-executions-by-date/http-response.adoc[]

[[api-guide-resources-job-executions-detail]]
==== Job Execution Detail

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public final class TimeUtils {

public static final String DEFAULT_DATAFLOW_TIMEZONE_ID = "UTC";

public static final String DEFAULT_DATAFLOW_DATE_TIME_PARAMETER_FORMAT_PATTERN = "yyyy-MM-dd'T'HH:mm:ss,SSS";

/**
* Prevent instantiation.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -70,7 +71,9 @@ public class JdbcSearchableJobExecutionDao extends JdbcJobExecutionDao implement
+ " from %PREFIX%JOB_EXECUTION E, %PREFIX%JOB_INSTANCE I "
+ "where E.JOB_INSTANCE_ID=I.JOB_INSTANCE_ID and E.END_TIME is NULL";

private static final String NAME_FILTER = "I.JOB_NAME LIKE ?";
private static final String NAME_FILTER = "I.JOB_NAME LIKE ?";

private static final String DATE_RANGE_FILTER = "E.START_TIME BETWEEN ? AND ?";

private static final String STATUS_FILTER = "E.STATUS = ?";

Expand All @@ -88,6 +91,8 @@ public class JdbcSearchableJobExecutionDao extends JdbcJobExecutionDao implement

private PagingQueryProvider executionsWithStepCountPagingQueryProvider;

private PagingQueryProvider byDateRangeWithStepCountPagingQueryProvider;

private DataSource dataSource;

/**
Expand Down Expand Up @@ -121,6 +126,7 @@ protected long getNextKey() {
byStatusPagingQueryProvider = getPagingQueryProvider(STATUS_FILTER);
byJobNameAndStatusPagingQueryProvider = getPagingQueryProvider(NAME_AND_STATUS_FILTER);
byJobNameWithStepCountPagingQueryProvider = getPagingQueryProvider(FIELDS_WITH_STEP_COUNT, null, NAME_FILTER);
byDateRangeWithStepCountPagingQueryProvider = getPagingQueryProvider(FIELDS_WITH_STEP_COUNT, null, DATE_RANGE_FILTER);

super.afterPropertiesSet();

Expand Down Expand Up @@ -207,6 +213,29 @@ public int countJobExecutions(String jobName, BatchStatus status) {
return getJdbcTemplate().queryForObject(getQuery(GET_COUNT_BY_JOB_NAME_AND_STATUS), Integer.class, jobName, status.name());
}

/**
* @see SearchableJobExecutionDao#getJobExecutionsWithStepCount(Date, Date, int, int)
*/
@Override
public List<JobExecutionWithStepCount> getJobExecutionsWithStepCount(Date fromDate,
Date toDate, int start, int count) {

if (start <= 0) {
return getJdbcTemplate().query(byDateRangeWithStepCountPagingQueryProvider.generateFirstPageQuery(count),
new JobExecutionStepCountRowMapper(), fromDate, toDate);
}
try {
Long startAfterValue = getJdbcTemplate().queryForObject(
byDateRangeWithStepCountPagingQueryProvider.generateJumpToItemQuery(start, count), Long.class,
fromDate, toDate);
return getJdbcTemplate().query(byDateRangeWithStepCountPagingQueryProvider.generateRemainingPagesQuery(count),
new JobExecutionStepCountRowMapper(), fromDate, toDate, startAfterValue);
}
catch (IncorrectResultSizeDataAccessException e) {
return Collections.emptyList();
}
}

/**
* @see SearchableJobExecutionDao#getRunningJobExecutions()
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.springframework.cloud.dataflow.server.batch;

import java.util.Collection;
import java.util.Date;

import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
Expand Down Expand Up @@ -349,4 +350,17 @@ StepExecution getStepExecution(Long jobExecutionId, Long stepExecutionId) throws
*/
Collection<JobExecution> listJobExecutionsForJob(String jobName, BatchStatus status, int pageOffset, int pageSize)
throws NoSuchJobException;

/**
* List the {@link JobExecutionWithStepCount job executions} filtered by date range in
* descending order of creation (usually close to execution order).
*
* @param fromDate the date which start date must be greater than.
* @param toDate the date which start date must be less than.
* @param start the start index of the first job execution
* @param count the maximum number of executions to return
* @return a collection of {@link JobExecutionWithStepCount}
*/
Collection<JobExecutionWithStepCount> listJobExecutionsForJobWithStepCount(Date fromDate,
Date toDate, int start, int count);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.springframework.cloud.dataflow.server.batch;

import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.springframework.batch.core.BatchStatus;
Expand Down Expand Up @@ -133,4 +134,16 @@ public interface SearchableJobExecutionDao extends JobExecutionDao {
* this job
*/
int countJobExecutions(String jobName, BatchStatus status);

/**
* Get the {@link JobExecutionWithStepCount JobExecutions} for a specific date range in
* reverse order of creation (so normally of execution).
*
* @param fromDate the date which start date must be greater than.
* @param toDate the date which start date must be less than.
* @param start the start index of the instances
* @param count the maximum number of instances to return
* @return the {@link JobExecutionWithStepCount} instances requested
*/
List<JobExecutionWithStepCount> getJobExecutionsWithStepCount(Date fromDate, Date toDate, int start, int count);
}
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,12 @@ public Collection<JobExecution> listJobExecutionsForJob(String jobName, BatchSta
return jobExecutions;
}

@Override
public Collection<JobExecutionWithStepCount> listJobExecutionsForJobWithStepCount(Date fromDate,
Date toDate, int start, int count) {
return jobExecutionDao.getJobExecutionsWithStepCount(fromDate, toDate, start, count);
}

private List<JobExecution> getJobExecutions(String jobName, BatchStatus status, int pageOffset, int pageSize) {
if (StringUtils.isEmpty(jobName)) {
if (status != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.springframework.cloud.dataflow.server.controller;

import java.util.Date;
import java.util.List;
import java.util.TimeZone;

Expand All @@ -33,6 +34,7 @@
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.hateoas.PagedModel;
import org.springframework.hateoas.server.ExposesResourceFor;
import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
Expand Down Expand Up @@ -111,6 +113,29 @@ public PagedModel<JobExecutionThinResource> retrieveJobsByName(@RequestParam("na
return assembler.toModel(page, jobAssembler);
}

/**
* Retrieve all task job executions filtered with the date range specified
*
* @param fromDate the date which start date must be greater than.
* @param toDate the date which start date must be less than.
* @param pageable page-able collection of {@code TaskJobExecution}s.
* @param assembler for the {@link TaskJobExecution}s
* @return list task/job executions with the specified jobName.
* @throws NoSuchJobException if the job with the given name does not exist.
*/
@RequestMapping(value = "", method = RequestMethod.GET, params = { "fromDate",
"toDate" }, produces = "application/json")
@ResponseStatus(HttpStatus.OK)
public PagedModel<JobExecutionThinResource> retrieveJobsByDateRange(
@RequestParam("fromDate") @DateTimeFormat(pattern = TimeUtils.DEFAULT_DATAFLOW_DATE_TIME_PARAMETER_FORMAT_PATTERN) Date fromDate,
@RequestParam("toDate") @DateTimeFormat(pattern = TimeUtils.DEFAULT_DATAFLOW_DATE_TIME_PARAMETER_FORMAT_PATTERN) Date toDate,
Pageable pageable, PagedResourcesAssembler<TaskJobExecution> assembler) throws NoSuchJobException {
List<TaskJobExecution> jobExecutions = taskJobService.listJobExecutionsForJobWithStepCount(pageable, fromDate,
toDate);
Page<TaskJobExecution> page = new PageImpl<>(jobExecutions, pageable, jobExecutions.size());
return assembler.toModel(page, jobAssembler);
}



/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.springframework.cloud.dataflow.server.service;

import java.util.Date;
import java.util.List;

import org.springframework.batch.core.BatchStatus;
Expand Down Expand Up @@ -175,4 +176,17 @@ List<JobInstanceExecutions> listTaskJobInstancesForJobName(Pageable pageable, St
*/
List<TaskJobExecution> listJobExecutionsForJob(Pageable pageable, String jobName, BatchStatus status)
throws NoSuchJobException;

/**
* Retrieves Pageable list of {@link JobExecutionWithStepCount} from the JobRepository
* filtered by the date range.
*
* @param pageable enumerates the data to be returned.
* @param fromDate the date which start date must be greater than.
* @param toDate the date which start date must be less than.
* @return List containing {@link JobExecutionWithStepCount}s.
* @throws NoSuchJobException if the job with the given name does not exist.
*/
List<TaskJobExecution> listJobExecutionsForJobWithStepCount(Pageable pageable, Date fromDate, Date toDate)
throws NoSuchJobException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -120,6 +121,15 @@ public List<TaskJobExecution> listJobExecutionsForJob(Pageable pageable, String
jobService.listJobExecutionsForJob(jobName, status, getPageOffset(pageable), pageable.getPageSize()));
}

@Override
public List<TaskJobExecution> listJobExecutionsForJobWithStepCount(Pageable pageable,
Date fromDate, Date toDate) {
Assert.notNull(pageable, "pageable must not be null");
return getTaskJobExecutionsWithStepCountForList(
jobService.listJobExecutionsForJobWithStepCount(fromDate, toDate, getPageOffset(pageable),
pageable.getPageSize()));
}

@Override
public List<TaskJobExecution> listJobExecutionsForJobWithStepCount(Pageable pageable, String jobName) throws NoSuchJobException {
Assert.notNull(pageable, "pageable must not be null");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

package org.springframework.cloud.dataflow.server.controller;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang3.time.DateUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand All @@ -28,6 +32,7 @@
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.dataflow.rest.job.support.TimeUtils;
import org.springframework.cloud.dataflow.server.config.apps.CommonApplicationProperties;
import org.springframework.cloud.dataflow.server.configuration.JobDependencies;
import org.springframework.cloud.task.batch.listener.TaskBatchDao;
Expand Down Expand Up @@ -104,4 +109,21 @@ public void testGetExecutionsByName() throws Exception {
.andExpect(jsonPath("$.content", hasSize(1)));
}

@Test
public void testGetExecutionsByDateRange() throws Exception {
final Date toDate = new Date();
final Date fromDate = DateUtils.addMinutes(toDate, -10);
mockMvc.perform(get("/jobs/thinexecutions/")
.param("fromDate",
new SimpleDateFormat(TimeUtils.DEFAULT_DATAFLOW_DATE_TIME_PARAMETER_FORMAT_PATTERN)
.format(fromDate))
.param("toDate",
new SimpleDateFormat(TimeUtils.DEFAULT_DATAFLOW_DATE_TIME_PARAMETER_FORMAT_PATTERN)
.format(toDate))
.accept(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk())
.andExpect(jsonPath("$.content[*].taskExecutionId", containsInAnyOrder(8, 7, 6, 5, 4, 3, 3, 2, 1)))
.andExpect(jsonPath("$.content[0].stepExecutionCount", is(1)))
.andExpect(jsonPath("$.content", hasSize(9)));
}

}

0 comments on commit 42b1720

Please sign in to comment.