SCT-7 Add TaskExplorer implementation
* Supports SimpleTaskExplorer that accepts a TaskExecutionDao. * Updated Dao's to support the explorer query requirements * Added tests. This resolves spring-cloud/spring-cloud-task#7
This commit is contained in:
committed by
Michael Minella
parent
5c3795e7c7
commit
b62cb184c0
@@ -24,7 +24,9 @@ import org.springframework.cloud.task.repository.TaskExplorer;
|
||||
import org.springframework.cloud.task.repository.TaskRepository;
|
||||
import org.springframework.cloud.task.repository.dao.JdbcTaskExecutionDao;
|
||||
import org.springframework.cloud.task.repository.dao.MapTaskExecutionDao;
|
||||
import org.springframework.cloud.task.repository.support.JdbcTaskExplorerFactoryBean;
|
||||
import org.springframework.cloud.task.repository.support.JdbcTaskRepositoryFactoryBean;
|
||||
import org.springframework.cloud.task.repository.support.MapTaskExplorerFactoryBean;
|
||||
import org.springframework.cloud.task.repository.support.MapTaskRepositoryFactoryBean;
|
||||
import org.springframework.cloud.task.repository.support.SimpleTaskRepository;
|
||||
|
||||
@@ -48,6 +50,8 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
||||
|
||||
private TaskRepository taskRepository;
|
||||
|
||||
private TaskExplorer taskExplorer;
|
||||
|
||||
public DefaultTaskConfigurer(){
|
||||
initialize();
|
||||
}
|
||||
@@ -62,8 +66,7 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
||||
}
|
||||
|
||||
public TaskExplorer getTaskExplorer() {
|
||||
throw new UnsupportedOperationException("method not implemented");
|
||||
//TODO if datasource != null use TaskRepositoryFactoryBean from above like initialize method in DefaultBatchConfigurer
|
||||
return taskExplorer;
|
||||
}
|
||||
|
||||
private void initialize(){
|
||||
@@ -72,11 +75,18 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
||||
MapTaskRepositoryFactoryBean mapTaskRepositoryFactoryBean =
|
||||
new MapTaskRepositoryFactoryBean();
|
||||
taskRepository = mapTaskRepositoryFactoryBean.getObject();
|
||||
MapTaskExplorerFactoryBean mapTaskExplorerFactoryBean =
|
||||
new MapTaskExplorerFactoryBean();
|
||||
taskExplorer = mapTaskExplorerFactoryBean.getObject();
|
||||
|
||||
}
|
||||
else {
|
||||
JdbcTaskRepositoryFactoryBean jdbcTaskRepositoryFactoryBean =
|
||||
new JdbcTaskRepositoryFactoryBean(dataSource);
|
||||
taskRepository = jdbcTaskRepositoryFactoryBean.getObject();
|
||||
JdbcTaskExplorerFactoryBean jdbcTaskExplorerFactoryBean =
|
||||
new JdbcTaskExplorerFactoryBean(dataSource);
|
||||
taskExplorer = jdbcTaskExplorerFactoryBean.getObject();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public interface TaskExplorer {
|
||||
* @param executionId the task execution id
|
||||
* @return the {@link TaskExecution} with this id, or null if not found
|
||||
*/
|
||||
public TaskExecution getTaskExecution(Long executionId);
|
||||
public TaskExecution getTaskExecution(String executionId);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,15 +16,26 @@
|
||||
|
||||
package org.springframework.cloud.task.repository.dao;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.cloud.task.repository.TaskExecution;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
import org.springframework.jdbc.core.RowCallbackHandler;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -51,6 +62,30 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
+ "EXIT_MESSAGE = ?, LAST_UPDATED = ?, STATUS_CODE = ? "
|
||||
+ "where TASK_EXECUTION_ID = ?";
|
||||
|
||||
private static final String GET_EXECUTION_BY_ID = "SELECT TASK_EXECUTION_ID, " +
|
||||
"START_TIME, END_TIME, TASK_NAME, EXIT_CODE, "
|
||||
+ "EXIT_MESSAGE, LAST_UPDATED, STATUS_CODE "
|
||||
+ "from %PREFIX%EXECUTION where TASK_EXECUTION_ID = ?";
|
||||
|
||||
private static final String FIND_PARAMS_FROM_ID = "SELECT TASK_EXECUTION_ID, "
|
||||
+ "TASK_PARAM from %PREFIX%EXECUTION_PARAMS where TASK_EXECUTION_ID = ?";
|
||||
|
||||
private static final String TASK_EXECUTION_COUNT = "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 "
|
||||
+ "from %PREFIX%EXECUTION where TASK_NAME = ? AND END_TIME IS NULL "
|
||||
+ "order by TASK_EXECUTION_ID";
|
||||
|
||||
private static final String FIND_TASK_EXECUTIONS = "SELECT TASK_EXECUTION_ID, "
|
||||
+ "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, "
|
||||
+ "EXIT_MESSAGE, LAST_UPDATED, STATUS_CODE "
|
||||
+ "from %PREFIX%EXECUTION where TASK_NAME = ? "
|
||||
+ "order by TASK_EXECUTION_ID";
|
||||
|
||||
final String FIND_TASK_NAMES = "SELECT distinct TASK_NAME from %PREFIX%EXECUTION order by TASK_NAME";
|
||||
|
||||
private static final String DEFAULT_TABLE_PREFIX = "TASK_";
|
||||
|
||||
@@ -75,7 +110,7 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
parameters,
|
||||
new int[]{ Types.VARCHAR, Types.TIMESTAMP, Types.TIMESTAMP, Types.VARCHAR,
|
||||
Types.INTEGER, Types.VARCHAR, Types.TIMESTAMP, Types.VARCHAR });
|
||||
insertJobParameters(taskExecution.getExecutionId(), taskExecution.getParameters());
|
||||
insertTaskParameters(taskExecution.getExecutionId(), taskExecution.getParameters());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -109,6 +144,92 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
this.tablePrefix = tablePrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskExecution getTaskExecution(String executionId) {
|
||||
try {
|
||||
TaskExecution taskExecution = jdbcTemplate.queryForObject(getQuery(GET_EXECUTION_BY_ID),
|
||||
new TaskExecutionRowMapper(), executionId);
|
||||
taskExecution.setParameters(getTaskParameters(executionId));
|
||||
return taskExecution;
|
||||
}
|
||||
catch (EmptyResultDataAccessException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTaskExecutionCount(String taskName) {
|
||||
try {
|
||||
return jdbcTemplate.queryForObject(
|
||||
getQuery(TASK_EXECUTION_COUNT), new Object[] { taskName }, Long.class);
|
||||
}
|
||||
catch (EmptyResultDataAccessException e) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TaskExecution> findRunningTaskExecutions(String taskName) {
|
||||
final Set<TaskExecution> result = new HashSet<TaskExecution>();
|
||||
RowCallbackHandler handler = new RowCallbackHandler() {
|
||||
@Override
|
||||
public void processRow(ResultSet rs) throws SQLException {
|
||||
TaskExecutionRowMapper mapper = new TaskExecutionRowMapper();
|
||||
result.add(mapper.mapRow(rs, 0));
|
||||
}
|
||||
};
|
||||
jdbcTemplate.query(getQuery(FIND_RUNNING_TASK_EXECUTIONS),
|
||||
new Object[] { taskName }, handler);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TaskExecution> getTaskExecutionsByName(String taskName, final int start,
|
||||
final int count) {
|
||||
ResultSetExtractor<List<TaskExecution>> extractor =
|
||||
new ResultSetExtractor<List<TaskExecution>>() {
|
||||
|
||||
private List<TaskExecution> list = new ArrayList<TaskExecution>();
|
||||
|
||||
@Override
|
||||
public List<TaskExecution> extractData(ResultSet rs) throws SQLException,
|
||||
DataAccessException {
|
||||
int rowNum = 0;
|
||||
while (rowNum < start && rs.next()) {
|
||||
rowNum++;
|
||||
}
|
||||
while (rowNum < start + count && rs.next()) {
|
||||
RowMapper<TaskExecution> rowMapper = new TaskExecutionRowMapper();
|
||||
list.add(rowMapper.mapRow(rs, rowNum));
|
||||
rowNum++;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
List<TaskExecution> result = jdbcTemplate.query(getQuery(FIND_TASK_EXECUTIONS),
|
||||
new Object[] { taskName }, extractor);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTaskNames() {
|
||||
return jdbcTemplate.query(getQuery(FIND_TASK_NAMES),
|
||||
new RowMapper<String>() {
|
||||
@Override
|
||||
public String mapRow(ResultSet rs, int rowNum)
|
||||
throws SQLException {
|
||||
return rs.getString(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private String getQuery(String base) {
|
||||
return StringUtils.replace(base, "%PREFIX%", tablePrefix);
|
||||
}
|
||||
@@ -120,7 +241,7 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
* @param executionId The executionId to which the params are associated.
|
||||
* @param taskParameters The parameters to be stored.
|
||||
*/
|
||||
private void insertJobParameters(String executionId, List<String> taskParameters) {
|
||||
private void insertTaskParameters(String executionId, List<String> taskParameters) {
|
||||
for (String param : taskParameters) {
|
||||
insertParameter(executionId, param);
|
||||
}
|
||||
@@ -136,4 +257,46 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
jdbcTemplate.update(getQuery(CREATE_TASK_PARAMETER), args, argTypes);
|
||||
}
|
||||
|
||||
private List<String> getTaskParameters(String executionId){
|
||||
final List<String> params= new ArrayList<>();
|
||||
RowCallbackHandler handler = new RowCallbackHandler() {
|
||||
@Override
|
||||
public void processRow(ResultSet rs) throws SQLException {
|
||||
params.add(rs.getString(2));
|
||||
}
|
||||
};
|
||||
|
||||
jdbcTemplate.query(getQuery(FIND_PARAMS_FROM_ID), new Object[] { executionId },
|
||||
handler);
|
||||
return Collections.unmodifiableList(params);
|
||||
|
||||
}
|
||||
/**
|
||||
* Re-usable mapper for {@link TaskExecution} instances.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
private final class TaskExecutionRowMapper implements RowMapper<TaskExecution> {
|
||||
|
||||
public TaskExecutionRowMapper() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskExecution mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
String id = rs.getString(1);
|
||||
TaskExecution taskExecution=new TaskExecution();
|
||||
taskExecution.setExecutionId(rs.getString(1));
|
||||
taskExecution.setStartTime(rs.getTimestamp("START_TIME"));
|
||||
taskExecution.setEndTime(rs.getTimestamp("END_TIME"));
|
||||
taskExecution.setExitCode(rs.getInt("EXIT_CODE"));
|
||||
taskExecution.setExitMessage(rs.getString("EXIT_MESSAGE"));
|
||||
taskExecution.setStatusCode(rs.getString("STATUS_CODE"));
|
||||
taskExecution.setTaskName(rs.getString("TASK_NAME"));
|
||||
taskExecution.setParameters(getTaskParameters(id));
|
||||
|
||||
return taskExecution;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,8 +16,13 @@
|
||||
|
||||
package org.springframework.cloud.task.repository.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
@@ -46,7 +51,67 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
||||
taskExecutions.put(taskExecution.getExecutionId(), taskExecution);
|
||||
}
|
||||
|
||||
public Map<String, TaskExecution> getTaskExecutions(){
|
||||
@Override
|
||||
public TaskExecution getTaskExecution(String executionId) {
|
||||
return taskExecutions.get(executionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTaskExecutionCount(String taskName) {
|
||||
int count = 0;
|
||||
for (Map.Entry<String, TaskExecution> entry : taskExecutions.entrySet()) {
|
||||
if (entry.getValue().getTaskName().equals(taskName)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TaskExecution> findRunningTaskExecutions(String taskName) {
|
||||
Set<TaskExecution> result = new HashSet<>();
|
||||
for (Map.Entry<String, TaskExecution> entry : taskExecutions.entrySet()) {
|
||||
if (entry.getValue().getTaskName().equals(taskName) &&
|
||||
entry.getValue().getEndTime() == null) {
|
||||
result.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableSet(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TaskExecution> getTaskExecutionsByName(String taskName, int start, int count) {
|
||||
List<TaskExecution> result = new ArrayList<>();
|
||||
Set<TaskExecution> filteredSet = new HashSet<>();
|
||||
for (Map.Entry<String, TaskExecution> entry : taskExecutions.entrySet()) {
|
||||
if (entry.getValue().getTaskName().equals(taskName)) {
|
||||
filteredSet.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
int rowNum = 0;
|
||||
Iterator<TaskExecution> rs = filteredSet.iterator();
|
||||
while (rowNum < start && rs.hasNext()) {
|
||||
rs.next();
|
||||
rowNum++;
|
||||
}
|
||||
while (rowNum < start + count && rs.hasNext()) {
|
||||
result.add(rs.next());
|
||||
rowNum++;
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTaskNames() {
|
||||
Set<String> result = new HashSet<>();
|
||||
for (Map.Entry<String, TaskExecution> entry : taskExecutions.entrySet()) {
|
||||
result.add(entry.getValue().getTaskName());
|
||||
}
|
||||
return Collections.unmodifiableList(new ArrayList(result));
|
||||
}
|
||||
|
||||
public Map<String, TaskExecution> getTaskExecutions() {
|
||||
return Collections.unmodifiableMap(taskExecutions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.springframework.cloud.task.repository.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.cloud.task.repository.TaskExecution;
|
||||
|
||||
/**
|
||||
@@ -38,4 +41,46 @@ public interface TaskExecutionDao {
|
||||
* @param taskExecution the taskExecution to be updated.
|
||||
*/
|
||||
void updateTaskExecution(TaskExecution taskExecution);
|
||||
|
||||
/**
|
||||
* Retrieves a task execution from the task repository.
|
||||
*
|
||||
* @param executionId the uuid associated with the task execution.
|
||||
* @return a fully qualified TaskExecution instance.
|
||||
*/
|
||||
TaskExecution getTaskExecution(String executionId);
|
||||
|
||||
/**
|
||||
* Retrieves current number of task executions for a taskName.
|
||||
*
|
||||
* @param taskName the name of the task to search for in the repository.
|
||||
* @return current number of task executions.
|
||||
*/
|
||||
long getTaskExecutionCount(String taskName);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return set of running task executions.
|
||||
*/
|
||||
Set<TaskExecution> findRunningTaskExecutions(String taskName);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return a list that contains task executions from the query bound by the start
|
||||
* position and count specified by the user.
|
||||
*/
|
||||
List<TaskExecution> getTaskExecutionsByName(String taskName, int start, int count);
|
||||
|
||||
/**
|
||||
* Retrieves a sorted list of distinct task names for the task executions.
|
||||
*
|
||||
* @return a list of distinct task names from the task repository..
|
||||
*/
|
||||
public List<String> getTaskNames();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.cloud.task.repository.support;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.cloud.task.repository.TaskExplorer;
|
||||
import org.springframework.cloud.task.repository.dao.JdbcTaskExecutionDao;
|
||||
import org.springframework.cloud.task.repository.dao.TaskExecutionDao;
|
||||
|
||||
/**
|
||||
* Automates the creation of a {@link SimpleTaskExplorer} which will retrieve task
|
||||
* execution data from a database.
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
public class JdbcTaskExplorerFactoryBean {
|
||||
|
||||
public static final String DEFAULT_TABLE_PREFIX = "TASK_";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JdbcTaskExplorerFactoryBean.class);
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
private String tablePrefix = DEFAULT_TABLE_PREFIX;
|
||||
|
||||
public JdbcTaskExplorerFactoryBean(){
|
||||
|
||||
}
|
||||
|
||||
public JdbcTaskExplorerFactoryBean(DataSource dataSource) {
|
||||
if(dataSource != null) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the table prefix for all the task meta-data tables.
|
||||
* @param tablePrefix prefix prepended to task meta-data tables
|
||||
*/
|
||||
public void setTablePrefix(String tablePrefix) {
|
||||
this.tablePrefix = tablePrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the a simpleTaskExplorer that utilizes a JdbcTaskExecutionDao
|
||||
* @return instance of task repository.
|
||||
*/
|
||||
public TaskExplorer getObject(){
|
||||
TaskExplorer taskExplorer = null;
|
||||
logger.debug(String.format("Creating SimpleTaskExplorer that will use a %s",
|
||||
JdbcTaskExecutionDao.class.getName()));
|
||||
taskExplorer = new SimpleTaskExplorer(createJdbcTaskExecutionDao());
|
||||
return taskExplorer;
|
||||
}
|
||||
|
||||
private TaskExecutionDao createJdbcTaskExecutionDao() {
|
||||
JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(dataSource);
|
||||
dao.setTablePrefix(tablePrefix);
|
||||
return dao;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -52,15 +52,15 @@ public class JdbcTaskRepositoryFactoryBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the table prefix for all the batch meta-data tables.
|
||||
* @param tablePrefix prefix prepended to batch meta-data tables
|
||||
* Sets the table prefix for all the task meta-data tables.
|
||||
* @param tablePrefix prefix prepended to task meta-data tables
|
||||
*/
|
||||
public void setTablePrefix(String tablePrefix) {
|
||||
this.tablePrefix = tablePrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the a simpleTaskRepository that utilizes a MapTaskExecutionDao
|
||||
* Returns the a simpleTaskRepository that utilizes a JdbcTaskExecutionDao
|
||||
* @return instance of task repository.
|
||||
*/
|
||||
public TaskRepository getObject(){
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.cloud.task.repository.support;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.cloud.task.repository.TaskExplorer;
|
||||
import org.springframework.cloud.task.repository.dao.MapTaskExecutionDao;
|
||||
|
||||
/**
|
||||
* Automates the creation of a {@link SimpleTaskExplorer} which will retrieve task
|
||||
* execution data from a in-memory map.
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
public class MapTaskExplorerFactoryBean {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(MapTaskExplorerFactoryBean.class);
|
||||
|
||||
public MapTaskExplorerFactoryBean(){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the a simpleTaskExplorer that utilizes a MapTaskExecutionDao
|
||||
* @return instance of task repository.
|
||||
*/
|
||||
public TaskExplorer getObject(){
|
||||
TaskExplorer taskExplorer = null;
|
||||
logger.debug(String.format("Creating SimpleTaskExplorer that will use a %s",
|
||||
MapTaskExecutionDao.class.getName()));
|
||||
taskExplorer = new SimpleTaskExplorer(new MapTaskExecutionDao());
|
||||
return taskExplorer;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,7 +30,7 @@ import org.springframework.cloud.task.repository.TaskExplorer;
|
||||
*/
|
||||
public class NoOpTaskExplorer implements TaskExplorer {
|
||||
|
||||
public TaskExecution getTaskExecution(Long executionId) {
|
||||
public TaskExecution getTaskExecution(String executionId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed 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.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;
|
||||
import org.springframework.cloud.task.repository.dao.TaskExecutionDao;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* TaskExplorer for that gathers task information from a task repository.
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
public class SimpleTaskExplorer implements TaskExplorer{
|
||||
|
||||
private TaskExecutionDao taskExecutionDao;
|
||||
|
||||
public SimpleTaskExplorer(TaskExecutionDao taskExecutionDao){
|
||||
Assert.notNull(taskExecutionDao, "taskExecutionDao must not be null");
|
||||
this.taskExecutionDao = taskExecutionDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskExecution getTaskExecution(String executionId) {
|
||||
return taskExecutionDao.getTaskExecution(executionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TaskExecution> findRunningTaskExecutions(String taskName) {
|
||||
return taskExecutionDao.findRunningTaskExecutions(taskName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTaskNames() {
|
||||
return taskExecutionDao.getTaskNames();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTaskExecutionCount(String taskName) {
|
||||
return taskExecutionDao.getTaskExecutionCount(taskName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TaskExecution> getTaskExecutionsByName(String taskName, int start, int count) {
|
||||
return taskExecutionDao.getTaskExecutionsByName(taskName, start, count);
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public class NoOpTaskExplorerTests {
|
||||
|
||||
@Test
|
||||
public void testGetTaskExecution() throws Exception {
|
||||
assertNull(taskExplorer.getTaskExecution(3l));
|
||||
assertNull(taskExplorer.getTaskExecution("abc"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.cloud.task.repository.support;
|
||||
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||
import org.springframework.cloud.task.annotation.EnableTask;
|
||||
import org.springframework.cloud.task.repository.TaskExecution;
|
||||
import org.springframework.cloud.task.repository.TaskExplorer;
|
||||
import org.springframework.cloud.task.repository.dao.JdbcTaskExecutionDao;
|
||||
import org.springframework.cloud.task.repository.dao.MapTaskExecutionDao;
|
||||
import org.springframework.cloud.task.repository.dao.TaskExecutionDao;
|
||||
import org.springframework.cloud.task.util.TestVerifierUtils;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class SimpleTaskExplorerTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
private TaskExecutionDao dao;
|
||||
|
||||
private TaskExplorer taskExplorer;
|
||||
|
||||
private DaoType testType;
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<Object> data() {
|
||||
return Arrays.asList(new Object[] {
|
||||
DaoType.jdbc , DaoType.map });
|
||||
}
|
||||
|
||||
public SimpleTaskExplorerTests(DaoType testType) {
|
||||
this.testType = testType;
|
||||
}
|
||||
@Rule
|
||||
public ExpectedException expected = ExpectedException.none();
|
||||
|
||||
@Before
|
||||
public void testDefaultContext() throws Exception {
|
||||
|
||||
if(testType == DaoType.jdbc){
|
||||
initializeJdbcExplorerTest();
|
||||
}else{
|
||||
initializeMapExplorerTest();
|
||||
}
|
||||
taskExplorer = new SimpleTaskExplorer(dao);
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTaskExecution() {
|
||||
final int TEST_COUNT = 5;
|
||||
Map<String, TaskExecution> expectedResults = new HashMap<>();
|
||||
for (int i = 0; i < TEST_COUNT; i++) {
|
||||
TaskExecution expectedTaskExecution = createAndSaveTaskExecution();
|
||||
expectedResults.put(expectedTaskExecution.getExecutionId(),
|
||||
expectedTaskExecution);
|
||||
}
|
||||
for (String taskExecutionId : expectedResults.keySet()) {
|
||||
TaskExecution actualTaskExecution =
|
||||
taskExplorer.getTaskExecution(taskExecutionId);
|
||||
assertNotNull(String.format(
|
||||
"expected a taskExecution but got null for test type %s", testType),
|
||||
actualTaskExecution);
|
||||
TestVerifierUtils.verifyTaskExecution(expectedResults.get(taskExecutionId),
|
||||
actualTaskExecution);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTaskCountByTaskName() {
|
||||
final int TEST_COUNT = 5;
|
||||
Map<String, TaskExecution> expectedResults = new HashMap<>();
|
||||
for (int i = 0; i < TEST_COUNT; i++) {
|
||||
TaskExecution expectedTaskExecution = createAndSaveTaskExecution();
|
||||
expectedResults.put(expectedTaskExecution.getExecutionId(),
|
||||
expectedTaskExecution);
|
||||
}
|
||||
for (Map.Entry<String, TaskExecution> entry : expectedResults.entrySet()) {
|
||||
String taskName = entry.getValue().getTaskName();
|
||||
assertEquals(String.format(
|
||||
"task count for task name did not match expected result for testType %s",
|
||||
testType),
|
||||
1, taskExplorer.getTaskExecutionCount(taskName));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findRunningTasks() {
|
||||
final int TEST_COUNT = 2;
|
||||
final int COMPLETE_COUNT = 5;
|
||||
final String TASK_NAME = "FOOBAR";
|
||||
|
||||
Map<String, TaskExecution> expectedResults = new HashMap<>();
|
||||
//Store completed jobs
|
||||
for (int i = 0; i < COMPLETE_COUNT; i++) {
|
||||
createAndSaveTaskExecution();
|
||||
}
|
||||
|
||||
for (int i = 0; i < TEST_COUNT; i++) {
|
||||
TaskExecution expectedTaskExecution = new TaskExecution();
|
||||
expectedTaskExecution.setStartTime(new Date());
|
||||
expectedTaskExecution.setExecutionId(UUID.randomUUID().toString());
|
||||
expectedTaskExecution.setTaskName(TASK_NAME);
|
||||
dao.saveTaskExecution(expectedTaskExecution);
|
||||
expectedResults.put(expectedTaskExecution.getExecutionId(), expectedTaskExecution);
|
||||
}
|
||||
Set<TaskExecution> actualResults = taskExplorer.findRunningTaskExecutions(TASK_NAME);
|
||||
assertEquals(String.format(
|
||||
"Running task count for task name did not match expected result for testType %s",
|
||||
testType), TEST_COUNT, actualResults.size());
|
||||
|
||||
for (TaskExecution result : actualResults) {
|
||||
assertTrue(String.format(
|
||||
"result returned from repo %s not expected for testType %s",
|
||||
result.getExecutionId(), testType),
|
||||
expectedResults.containsKey(result.getExecutionId()));
|
||||
assertNull(String.format("result had non null for endTime for the testType %s",
|
||||
testType), result.getEndTime());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
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<String, TaskExecution> expectedResults = new HashMap<>();
|
||||
//Store completed jobs
|
||||
for (int i = 0; i < COMPLETE_COUNT; i++) {
|
||||
createAndSaveTaskExecution();
|
||||
}
|
||||
|
||||
for (int i = 0; i < TEST_COUNT; i++) {
|
||||
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoParam();
|
||||
expectedTaskExecution.setTaskName(TASK_NAME);
|
||||
dao.saveTaskExecution(expectedTaskExecution);
|
||||
expectedResults.put(expectedTaskExecution.getExecutionId(), expectedTaskExecution);
|
||||
}
|
||||
List<TaskExecution> resultSet = taskExplorer.getTaskExecutionsByName(TASK_NAME, 1, RESULT_SET_SIZE);
|
||||
assertEquals(String.format(
|
||||
"Running task count for task name did not match expected result for testType %s",
|
||||
testType), RESULT_SET_SIZE, resultSet.size());
|
||||
|
||||
for (TaskExecution result : resultSet) {
|
||||
assertTrue(String.format("result returned from %s repo %s not expected",
|
||||
testType, result.getExecutionId()),
|
||||
expectedResults.containsKey(result.getExecutionId()));
|
||||
assertEquals(
|
||||
String.format("taskName for taskExecution is incorrect for testType %s",
|
||||
testType), TASK_NAME, result.getTaskName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTaskNames() {
|
||||
final int TEST_COUNT = 5;
|
||||
Set<String> expectedResults = new HashSet<>();
|
||||
for (int i = 0; i < TEST_COUNT; i++) {
|
||||
TaskExecution expectedTaskExecution = createAndSaveTaskExecution();
|
||||
expectedResults.add(expectedTaskExecution.getTaskName());
|
||||
}
|
||||
List<String> actualTaskNames = taskExplorer.getTaskNames();
|
||||
for (String taskName : actualTaskNames) {
|
||||
assertTrue(String.format("taskName was not in expected results for testType %s",
|
||||
testType), expectedResults.contains(taskName));
|
||||
}
|
||||
}
|
||||
|
||||
private TaskExecution createAndSaveTaskExecution() {
|
||||
TaskExecution taskExecution = TestVerifierUtils.createSampleTaskExecution();
|
||||
dao.saveTaskExecution(taskExecution);
|
||||
return taskExecution;
|
||||
}
|
||||
|
||||
@EnableTask
|
||||
protected static class TestConfiguration {
|
||||
}
|
||||
|
||||
private void initializeJdbcExplorerTest(){
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.register(TestConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
dataSource = this.context.getBean(DataSource.class);
|
||||
dao = new JdbcTaskExecutionDao(dataSource);
|
||||
}
|
||||
|
||||
private void initializeMapExplorerTest(){
|
||||
dao = new MapTaskExecutionDao();
|
||||
}
|
||||
|
||||
private enum DaoType{jdbc, map}
|
||||
}
|
||||
@@ -67,10 +67,9 @@ public class TaskDatabaseInitializerTests {
|
||||
.queryForList("select * from TASK_EXECUTION").size());
|
||||
}
|
||||
|
||||
// @Test
|
||||
@Test
|
||||
public void testNoDatabase() throws Exception {
|
||||
SimpleTaskRepository repository = new SimpleTaskRepository(new MapTaskExecutionDao());
|
||||
this.context.refresh();
|
||||
assertThat(repository.getTaskExecutionDao(), instanceOf(MapTaskExecutionDao.class));
|
||||
MapTaskExecutionDao dao = (MapTaskExecutionDao) repository.getTaskExecutionDao();
|
||||
assertEquals(0, dao.getTaskExecutions().size());
|
||||
|
||||
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.when;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@@ -45,6 +46,8 @@ import org.springframework.cloud.task.repository.TaskExecution;
|
||||
*/
|
||||
public class TestVerifierUtils {
|
||||
|
||||
public static final int PARAM_SIZE = 5;
|
||||
|
||||
/**
|
||||
* Creates a mock {@link Appender} to be added to the root logger.
|
||||
*
|
||||
@@ -94,6 +97,29 @@ public class TestVerifierUtils {
|
||||
exitMessage, new ArrayList<String>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fully populated TaskExecution for testing.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static TaskExecution createSampleTaskExecution() {
|
||||
Random randomGenerator = new Random();
|
||||
int exitCode = randomGenerator.nextInt();
|
||||
Date startTime = new Date();
|
||||
Date endTime = new Date();
|
||||
String executionId = UUID.randomUUID().toString();
|
||||
String taskName = UUID.randomUUID().toString();
|
||||
String exitMessage = UUID.randomUUID().toString();
|
||||
String statusCode = UUID.randomUUID().toString().substring(0, 9);
|
||||
List<String> params = new ArrayList<>(PARAM_SIZE);
|
||||
for (int i = 0 ; i < PARAM_SIZE ; i++){
|
||||
params.add(UUID.randomUUID().toString());
|
||||
}
|
||||
return new TaskExecution(executionId, exitCode, taskName,
|
||||
startTime, endTime, statusCode,
|
||||
exitMessage, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that all the fields in between the expected and actual are the same;
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user