From a53a304b455f0b65276b61dc815775f13adab1a5 Mon Sep 17 00:00:00 2001 From: Glenn Renfro Date: Thu, 7 Jan 2016 20:16:43 -0500 Subject: [PATCH] SCT-56 Adds Pageable to Explorer methods * findRunningTaskExecutions * findTaskExecutionsByName resolves resolves spring-cloud/spring-cloud-task#56 --- .../cloud/task/repository/TaskExplorer.java | 9 +- .../repository/dao/JdbcTaskExecutionDao.java | 90 +++++++++++-------- .../repository/dao/MapTaskExecutionDao.java | 39 +++++--- .../task/repository/dao/TaskExecutionDao.java | 20 +++-- .../support/SimpleTaskExplorer.java | 9 +- .../support/SimpleTaskExplorerTests.java | 13 +-- 6 files changed, 108 insertions(+), 72 deletions(-) diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskExplorer.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskExplorer.java index 88bddc5d..daf3baa5 100644 --- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskExplorer.java +++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskExplorer.java @@ -17,7 +17,6 @@ package org.springframework.cloud.task.repository; import java.util.List; -import java.util.Set; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -42,9 +41,10 @@ public interface TaskExplorer { * Retrieve a collection of taskExecutions that have the task name provided. * * @param taskName the name of the task + * @param pageable the constraints for the search * @return the set of running executions for tasks with the specified name */ - public Set findRunningTaskExecutions(String taskName); + public Page findRunningTaskExecutions(String taskName, Pageable pageable); /** * Retrieve a list of available task names. @@ -72,11 +72,10 @@ public interface TaskExplorer { * Get a collection/page of executions * * @param taskName the name of the task to be searched - * @param start the position of the first execution to return - * @param count the number of executions to return + * @param pageable the constraints for the search * @return list of task executions */ - public List getTaskExecutionsByName(String taskName, int start, int count); + public Page findTaskExecutionsByName(String taskName, Pageable pageable); /** * Retrieves all the task executions within the pageable constraints sorted by diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/JdbcTaskExecutionDao.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/JdbcTaskExecutionDao.java index 3c9797a4..e8ea1d42 100644 --- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/JdbcTaskExecutionDao.java +++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/JdbcTaskExecutionDao.java @@ -21,10 +21,8 @@ import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.Date; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.TreeMap; import javax.sql.DataSource; @@ -53,11 +51,16 @@ import org.springframework.util.StringUtils; public class JdbcTaskExecutionDao implements TaskExecutionDao { - public static String SELECT_CLAUSE = "TASK_EXECUTION_ID, TASK_EXTERNAL_EXECUTION_ID, " + public static final String SELECT_CLAUSE = "TASK_EXECUTION_ID, TASK_EXTERNAL_EXECUTION_ID, " + "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, " + "EXIT_MESSAGE, LAST_UPDATED, STATUS_CODE "; - public static String FROM_CLAUSE = "%PREFIX%EXECUTION"; + public static final String FROM_CLAUSE = "%PREFIX%EXECUTION"; + + public static final String RUNNING_TASK_WHERE_CLAUSE = + "where TASK_NAME = ? AND END_TIME IS NULL "; + + public static final String TASK_NAME_WHERE_CLAUSE = "where TASK_NAME = ? "; private static final String SAVE_TASK_EXECUTION = "INSERT into %PREFIX%EXECUTION" + "(TASK_EXECUTION_ID, TASK_EXTERNAL_EXECUTION_ID, START_TIME, END_TIME, " @@ -89,18 +92,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao { private static final String TASK_EXECUTION_COUNT_BY_NAME = "SELECT COUNT(*) FROM " + "%PREFIX%EXECUTION where TASK_NAME = ?"; - private static final String FIND_RUNNING_TASK_EXECUTIONS = "SELECT TASK_EXECUTION_ID, " - + "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, " - + "EXIT_MESSAGE, LAST_UPDATED, STATUS_CODE, TASK_EXTERNAL_EXECUTION_ID " - + "from %PREFIX%EXECUTION where TASK_NAME = ? AND END_TIME IS NULL " - + "order by TASK_EXECUTION_ID"; - - private static final String FIND_TASK_EXECUTIONS_BY_NAME = "SELECT TASK_EXECUTION_ID, " - + "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, " - + "EXIT_MESSAGE, LAST_UPDATED, STATUS_CODE, TASK_EXTERNAL_EXECUTION_ID " - + "from %PREFIX%EXECUTION where TASK_NAME = ? " - + "order by TASK_EXECUTION_ID " - + "LIMIT ? OFFSET ?"; + private static final String RUNNING_TASK_EXECUTION_COUNT_BY_NAME = "SELECT COUNT(*) FROM " + + "%PREFIX%EXECUTION where TASK_NAME = ? AND END_TIME IS NULL "; final String FIND_TASK_NAMES = "SELECT distinct TASK_NAME from %PREFIX%EXECUTION order by TASK_NAME"; @@ -198,6 +191,17 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao { } } + @Override + public long getRunningTaskExecutionCountByTaskName(String taskName) { + try { + return jdbcTemplate.queryForObject( + getQuery(RUNNING_TASK_EXECUTION_COUNT_BY_NAME), new Object[] { taskName }, Long.class); + } + catch (EmptyResultDataAccessException e) { + return 0; + } + } + @Override public long getTaskExecutionCount() { try { @@ -210,19 +214,17 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao { } @Override - public Set findRunningTaskExecutions(String taskName) { - final Set result = new HashSet(); - List resultList = jdbcTemplate.query(getQuery(FIND_RUNNING_TASK_EXECUTIONS), - new Object[]{ taskName }, new TaskExecutionRowMapper()); - result.addAll(resultList); - return result; - + public Page findRunningTaskExecutions(String taskName, Pageable pageable) { + return queryForPageableResults(pageable, SELECT_CLAUSE, FROM_CLAUSE, + RUNNING_TASK_WHERE_CLAUSE, new Object[]{ taskName }, + getRunningTaskExecutionCountByTaskName(taskName)); } @Override - public List getTaskExecutionsByName(String taskName, final int start, final int count) { - return jdbcTemplate.query(getQuery(FIND_TASK_EXECUTIONS_BY_NAME), - new Object[]{ taskName, count, start }, new TaskExecutionRowMapper()); + public Page findTaskExecutionsByName(String taskName, Pageable pageable) { + return queryForPageableResults(pageable, SELECT_CLAUSE, FROM_CLAUSE, + TASK_NAME_WHERE_CLAUSE, new Object[]{ taskName }, + getTaskExecutionCountByTaskName(taskName)); } @Override @@ -232,10 +234,30 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao { @Override public Page findAll(Pageable pageable) { + return queryForPageableResults(pageable, SELECT_CLAUSE, FROM_CLAUSE, null, + new Object[]{ }, getTaskExecutionCount()); + } + public void setTaskIncrementer(DataFieldMaxValueIncrementer taskIncrementer) { + this.taskIncrementer = taskIncrementer; + } + + public long getNextExecutionId(){ + return taskIncrementer.nextLongValue(); + } + + private Page queryForPageableResults(Pageable pageable, + String selectClause, + String fromClause, + String whereClause, + Object[] queryParam, + long totalCount){ SqlPagingQueryProviderFactoryBean factoryBean = new SqlPagingQueryProviderFactoryBean(); - factoryBean.setSelectClause(SELECT_CLAUSE); - factoryBean.setFromClause(FROM_CLAUSE); + factoryBean.setSelectClause(selectClause); + factoryBean.setFromClause(fromClause); + if(StringUtils.hasText(whereClause)){ + factoryBean.setWhereClause(whereClause); + } factoryBean.setSortKeys(orderMap); factoryBean.setDataSource(dataSource); PagingQueryProvider pagingQueryProvider = null; @@ -249,17 +271,9 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao { String query = pagingQueryProvider.getPageQuery(pageable); List resultList = jdbcTemplate.query( getQuery(query), - new Object[]{ }, + queryParam, new TaskExecutionRowMapper()); - return new PageImpl(resultList, pageable, getTaskExecutionCount()); - } - - public void setTaskIncrementer(DataFieldMaxValueIncrementer taskIncrementer) { - this.taskIncrementer = taskIncrementer; - } - - public long getNextExecutionId(){ - return taskIncrementer.nextLongValue(); + return new PageImpl(resultList, pageable, totalCount); } private String getQuery(String base) { diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/MapTaskExecutionDao.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/MapTaskExecutionDao.java index 8ba24bd3..6bb94d5e 100644 --- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/MapTaskExecutionDao.java +++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/MapTaskExecutionDao.java @@ -73,13 +73,25 @@ public class MapTaskExecutionDao implements TaskExecutionDao { return count; } + @Override + public long getRunningTaskExecutionCountByTaskName(String taskName) { + int count = 0; + for (Map.Entry entry : taskExecutions.entrySet()) { + if (entry.getValue().getTaskName().equals(taskName) && + entry.getValue().getEndTime() == null) { + count++; + } + } + return count; + } + @Override public long getTaskExecutionCount() { return taskExecutions.size(); } @Override - public Set findRunningTaskExecutions(String taskName) { + public Page findRunningTaskExecutions(String taskName, Pageable pageable) { Set result = getTaskExecutionTreeSet(); for (Map.Entry entry : taskExecutions.entrySet()) { if (entry.getValue().getTaskName().equals(taskName) && @@ -87,20 +99,20 @@ public class MapTaskExecutionDao implements TaskExecutionDao { result.add(entry.getValue()); } } - return result; + return getPageFromList(new ArrayList<>(result), pageable, + getRunningTaskExecutionCountByTaskName(taskName)); } @Override - public List getTaskExecutionsByName(String taskName, int start, int count) { - List result = new ArrayList<>(); + public Page findTaskExecutionsByName(String taskName, Pageable pageable) { Set filteredSet = getTaskExecutionTreeSet(); for (Map.Entry entry : taskExecutions.entrySet()) { if (entry.getValue().getTaskName().equals(taskName)) { filteredSet.add(entry.getValue()); } } - result.addAll(filteredSet); - return result.subList(start, start + count); + return getPageFromList(new ArrayList(filteredSet), pageable, + getTaskExecutionCountByTaskName(taskName)); } @Override @@ -117,12 +129,7 @@ public class MapTaskExecutionDao implements TaskExecutionDao { TreeSet sortedSet = getTaskExecutionTreeSet(); sortedSet.addAll(taskExecutions.values()); List result = new ArrayList<>(sortedSet.descendingSet()); - int toIndex = (pageable.getOffset() + pageable.getPageSize() > result.size()) ? - result.size() : pageable.getOffset() + pageable.getPageSize(); - return new PageImpl( - result.subList(pageable.getOffset(), toIndex), - pageable, - getTaskExecutionCount()); + return getPageFromList(result, pageable, getTaskExecutionCount()); } public Map getTaskExecutions() { @@ -145,4 +152,12 @@ public class MapTaskExecutionDao implements TaskExecutionDao { } }); } + + private Page getPageFromList(List executionList, Pageable pageable, long maxSize){ + int toIndex = (pageable.getOffset() + pageable.getPageSize() > executionList.size()) ? + executionList.size() : pageable.getOffset() + pageable.getPageSize(); + return new PageImpl( + executionList.subList(pageable.getOffset(), toIndex), + pageable, maxSize); + } } diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/TaskExecutionDao.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/TaskExecutionDao.java index c6e2c96d..80179ebf 100644 --- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/TaskExecutionDao.java +++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/TaskExecutionDao.java @@ -17,7 +17,6 @@ package org.springframework.cloud.task.repository.dao; import java.util.List; -import java.util.Set; import org.springframework.cloud.task.repository.TaskExecution; import org.springframework.data.domain.Page; @@ -60,6 +59,15 @@ public interface TaskExecutionDao { */ long getTaskExecutionCountByTaskName(String taskName); + + /** + * Retrieves current number of task executions for a taskName and with an endTime of null. + * + * @param taskName the name of the task to search for in the repository. + * @return current number of task executions for the taskName. + */ + long getRunningTaskExecutionCountByTaskName(String taskName); + /** * Retrieves current number of task executions. * @@ -69,22 +77,20 @@ public interface TaskExecutionDao { /** * Retrieves a set of task executions that are running for a taskName. - * * @param taskName the name of the task to search for in the repository. + * @param pageable the constraints for the search. * @return set of running task executions. */ - Set findRunningTaskExecutions(String taskName); + Page findRunningTaskExecutions(String taskName, Pageable pageable); /** * Retrieves a subset of task executions by task name, start location and size. - * * @param taskName the name of the task to search for in the repository. - * @param start the position of the first entry to be returned from result set. - * @param count the number of entries to return + * @param pageable the constraints for the search. * @return a list that contains task executions from the query bound by the start * position and count specified by the user. */ - List getTaskExecutionsByName(String taskName, int start, int count); + Page findTaskExecutionsByName(String taskName, Pageable pageable); /** * Retrieves a sorted list of distinct task names for the task executions. diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/support/SimpleTaskExplorer.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/support/SimpleTaskExplorer.java index e14c0a94..ede0f6a1 100644 --- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/support/SimpleTaskExplorer.java +++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/support/SimpleTaskExplorer.java @@ -17,7 +17,6 @@ package org.springframework.cloud.task.repository.support; import java.util.List; -import java.util.Set; import org.springframework.cloud.task.repository.TaskExecution; import org.springframework.cloud.task.repository.TaskExplorer; @@ -46,8 +45,8 @@ public class SimpleTaskExplorer implements TaskExplorer{ } @Override - public Set findRunningTaskExecutions(String taskName) { - return taskExecutionDao.findRunningTaskExecutions(taskName); + public Page findRunningTaskExecutions(String taskName, Pageable pageable) { + return taskExecutionDao.findRunningTaskExecutions(taskName, pageable); } @Override @@ -66,8 +65,8 @@ public class SimpleTaskExplorer implements TaskExplorer{ } @Override - public List getTaskExecutionsByName(String taskName, int start, int count) { - return taskExecutionDao.getTaskExecutionsByName(taskName, start, count); + public Page findTaskExecutionsByName(String taskName, Pageable pageable) { + return taskExecutionDao.findTaskExecutionsByName(taskName, pageable); } @Override diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/support/SimpleTaskExplorerTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/support/SimpleTaskExplorerTests.java index f9cf9392..29c47bb1 100644 --- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/support/SimpleTaskExplorerTests.java +++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/support/SimpleTaskExplorerTests.java @@ -179,10 +179,12 @@ public class SimpleTaskExplorerTests { dao.saveTaskExecution(expectedTaskExecution); expectedResults.put(expectedTaskExecution.getExecutionId(), expectedTaskExecution); } - Set actualResults = taskExplorer.findRunningTaskExecutions(TASK_NAME); + Pageable pageable = new PageRequest(0, 10); + + Page actualResults = taskExplorer.findRunningTaskExecutions(TASK_NAME, pageable); assertEquals(String.format( "Running task count for task name did not match expected result for testType %s", - testType), TEST_COUNT, actualResults.size()); + testType), TEST_COUNT, actualResults.getNumberOfElements()); for (TaskExecution result : actualResults) { assertTrue(String.format( @@ -198,7 +200,6 @@ public class SimpleTaskExplorerTests { public void findTasksByName() { final int TEST_COUNT = 5; final int COMPLETE_COUNT = 7; - final int RESULT_SET_SIZE = 3; final String TASK_NAME = "FOOBAR"; Map expectedResults = new HashMap<>(); @@ -213,10 +214,12 @@ public class SimpleTaskExplorerTests { dao.saveTaskExecution(expectedTaskExecution); expectedResults.put(expectedTaskExecution.getExecutionId(), expectedTaskExecution); } - List resultSet = taskExplorer.getTaskExecutionsByName(TASK_NAME, 1, RESULT_SET_SIZE); + + Pageable pageable = new PageRequest(0, 10); + Page resultSet = taskExplorer.findTaskExecutionsByName(TASK_NAME, pageable); assertEquals(String.format( "Running task count for task name did not match expected result for testType %s", - testType), RESULT_SET_SIZE, resultSet.size()); + testType), TEST_COUNT, resultSet.getNumberOfElements()); for (TaskExecution result : resultSet) { assertTrue(String.format("result returned from %s repo %s not expected",