BATCH-295: JobLauncher now only contains one method: run(Job, JobInstanceProperties). Misc. other changes were made to facilitate.

This commit is contained in:
lucasward
2008-01-22 23:38:54 +00:00
parent 9cb2437e7e
commit f707a9d3d9
36 changed files with 1038 additions and 1609 deletions

View File

@@ -20,6 +20,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.JobLocator;
import org.springframework.batch.core.domain.NoSuchJobException;
import org.springframework.batch.core.executor.ExitCodeExceptionClassifier;
import org.springframework.batch.core.runtime.JobIdentifierFactory;
@@ -108,6 +110,8 @@ public class SimpleCommandLineJobRunner {
private ExitCodeExceptionClassifier exceptionClassifier = new SimpleExitCodeExceptionClassifier();
private JobLauncher launcher;
private JobLocator jobLocator;
private SystemExiter systemExiter = new JvmSystemExiter();
@@ -173,7 +177,11 @@ public class SimpleCommandLineJobRunner {
public void setSystemExiter(SystemExiter systemExitor) {
this.systemExiter = systemExitor;
}
public void setJobLocator(JobLocator jobLocator) {
this.jobLocator = jobLocator;
}
/**
* Delegate to the exiter to (possibly) exit the VM gracefully.
*
@@ -235,10 +243,7 @@ public class SimpleCommandLineJobRunner {
throw new NoSuchJobException("Null job name cannot be located.");
}
JobIdentifier runtimeInformation = jobIdentifierFactory.getJobIdentifier(jobName);
if (!launcher.isRunning()) {
status = launcher.run(runtimeInformation).getExitStatus();
}
status = launcher.run(jobLocator.getJob(runtimeInformation.getName()), new JobInstanceProperties()).getExitStatus();
}
catch (NoSuchJobException e) {
logger.fatal("Could not locate JobConfiguration \"" + jobName + "\"", e);

View File

@@ -15,8 +15,10 @@
*/
package org.springframework.batch.execution.launch;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.NoSuchJobException;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
@@ -38,23 +40,7 @@ public interface JobLauncher {
*
* @throws NoSuchJobException
*/
public JobExecution run(JobIdentifier jobIdentifier)
throws NoSuchJobException, JobExecutionAlreadyRunningException;
/**
* Stop the current job executions if there are any. If not, no action will
* be taken.
*
* @see org.springframework.context.Lifecycle#stop()
*/
public void stop();
/**
* Check whether or not any job execution is currently running.
*
* @return true if this launcher started a job or jobs and one can be
* determined to be in an active state.
*/
public boolean isRunning();
public JobExecution run(Job job, JobInstanceProperties jobInstanceProperties)
throws JobExecutionAlreadyRunningException;
}

View File

@@ -165,8 +165,8 @@ class SimpleJobExecutorFacade implements JobExecutorFacade,
Job job = jobLocator
.getJob(jobIdentifier.getName());
return jobRepository.findOrCreateJob(job,
jobIdentifier);
return jobRepository.createJobExecution(job,
null);
}
@@ -186,8 +186,7 @@ class SimpleJobExecutorFacade implements JobExecutorFacade,
throws NoSuchJobException {
Job job = jobLocator
.getJob(execution.getJobInstance().getIdentifier()
.getName());
.getJob(execution.getJobInstance().getJobName());
this.before(execution);
try {
@@ -210,7 +209,7 @@ class SimpleJobExecutorFacade implements JobExecutorFacade,
public void before(JobExecution execution) {
synchronized (mutex) {
running++;
jobExecutionRegistry.put(execution.getJobInstance().getIdentifier(),
jobExecutionRegistry.put(execution.getJobInstance(),
execution);
}
for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
@@ -255,7 +254,7 @@ class SimpleJobExecutorFacade implements JobExecutorFacade,
synchronized (mutex) {
// assume execution is synchronous so when we get to here we are
// not running any more
jobExecutionRegistry.remove(execution.getJobInstance().getIdentifier());
jobExecutionRegistry.remove(execution.getJobInstance());
running--;
}
}
@@ -295,7 +294,7 @@ class SimpleJobExecutorFacade implements JobExecutorFacade,
JobExecution element = (JobExecution) iter.next();
i++;
String runtime = "job" + i;
props.setProperty(runtime, "" + element.getJobInstance().getIdentifier());
props.setProperty(runtime, "" + element.getJobInstance());
int j = 0;
for (Iterator iterator = element.getStepExecutions().iterator(); iterator
.hasNext();) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007 the original author or authors.
* Copyright 2006-2008 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.
@@ -13,453 +13,83 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.execution.launch;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobLocator;
import org.springframework.batch.core.domain.NoSuchJobException;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.executor.JobExecutor;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.runtime.JobIdentifierFactory;
import org.springframework.batch.execution.job.DefaultJobExecutor;
import org.springframework.batch.execution.runtime.ScheduledJobIdentifierFactory;
import org.springframework.batch.repeat.interceptor.RepeatOperationsApplicationEvent;
import org.springframework.batch.statistics.StatisticsProvider;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.core.task.SyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
import org.springframework.util.Assert;
/**
* Generic {@link JobLauncher} allowing choice of strategy for concurrent
* execution and .
* A test implementation of the JobLauncher interface. It exists
* solely to work through interface design issues for the JobLauncher,
* JobRepository, JobLocator, and JobExecutor interfaces. It is designed
* for simplicity, and despite unit testing may not be completely threadsafe,
* and therefore should not be used.
*
* Rather than using a JobExecutorFacade, a JobExecutor is worked with directly.
* Not every method of the JobLauncher interface is used. Instead, new versions
* that take JobIdentifier as an argument were added. A JobExecution is considered
* to be running if it's JobIdentifier (the one it was ran with) exists in the
* HashMap execution registry. When a JobExecutor is finished processing it removes
* it's identifier from the map.
*
* @author Lucas Ward
*
* @see JobLauncher
* @author Dave Syer
*/
public class SimpleJobLauncher implements JobLauncher, InitializingBean, ApplicationEventPublisherAware,
StatisticsProvider {
public class SimpleJobLauncher implements JobLauncher {
protected static final Log logger = LogFactory.getLog(SimpleJobLauncher.class);
private JobExecutor jobExecutor = new DefaultJobExecutor();
// there is no sensible default for this
private JobRepository jobRepository;
// there is no sensible default for this
private JobLocator jobLocator;
// this can be defaulted from some other properties (see
// afterPropertiesSet())
private JobExecutorFacade jobExecutorFacade;
private JobExecutor jobExecutor;
private TaskExecutor taskExecutor = new SyncTaskExecutor();
public JobExecution run(final Job job, final JobInstanceProperties jobInstanceProperties)
throws JobExecutionAlreadyRunningException {
private List listeners = new ArrayList();
final JobExecution jobExecution = jobRepository.createJobExecution(job, jobInstanceProperties);
taskExecutor.execute(new Runnable(){
private JobIdentifierFactory jobIdentifierFactory = new ScheduledJobIdentifierFactory();
private final Object monitor = new Object();
// A private registry for keeping track of running jobs.
private volatile Map registry = new HashMap();
private ApplicationEventPublisher applicationEventPublisher;
/**
* Setter for {@link JobIdentifierFactory}.
*
* @param jobIdentifierFactory the {@link JobIdentifierFactory} to set
*/
public void setJobIdentifierFactory(JobIdentifierFactory jobIdentifierFactory) {
this.jobIdentifierFactory = jobIdentifierFactory;
public void run() {
try{
logger.info("Job: [" + job + "] launched with the following parameters: [" + jobInstanceProperties + "]");
ExitStatus exitStatus = jobExecutor.run(job, jobExecution);
//shouldn't need to set the exit status like this, I'm leaving it to make the latest change easier
jobExecution.setExitStatus(exitStatus);
logger.info("Job: [" + job + "] completed successfully with the following parameters: ["
+ jobInstanceProperties + "]");
}
catch(Throwable t){
logger.info("Job: [" + job + "] failed with the following parameters: ["
+ jobInstanceProperties + "]", t);
throw new RuntimeException(t);
}
}});
return jobExecution;
}
/**
* Public setter for the listeners property.
*
* @param listeners the listeners to set - a list of
* {@link JobExecutionListener}.
*/
public void setJobExecutionListeners(List listeners) {
this.listeners = listeners;
}
/**
* Setter for injection of {@link JobLocator}. Mandatory with no default.
*
* @param jobLocator the jobLocator to set
*/
public void setJobLocator(JobLocator jobLocator) {
this.jobLocator = jobLocator;
}
/**
* Setter for {@link JobExecutor}. Defaults to a {@link DefaultJobExecutor}.
*
* @param jobExecutor
*/
public void setJobExecutor(JobExecutor jobExecutor) {
this.jobExecutor = jobExecutor;
}
/**
* Setter for {@link JobRepository}. Mandatory with no default.
*
* @param jobRepository
*/
public void setJobRepository(JobRepository jobRepository) {
this.jobRepository = jobRepository;
}
/**
* Setter for {@link JobExecutorFacade}. Package private because it is only
* used for testing purposes.
*/
void setJobExecutorFacade(JobExecutorFacade jobExecutorFacade) {
this.jobExecutorFacade = jobExecutorFacade;
public void setJobExecutor(JobExecutor jobExecutor) {
this.jobExecutor = jobExecutor;
}
/**
* Check that mandatory properties are set and create a {@link JobExecutor}
* if one wasn't provided.
*
* @see #setJobExecutorFacade(JobExecutorFacade)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
if (jobExecutorFacade == null) {
logger.debug("Using SimpleJobExecutorFacade");
Assert.notNull(jobLocator);
Assert.notNull(jobExecutor);
Assert.notNull(jobRepository);
SimpleJobExecutorFacade jobExecutorFacade = new SimpleJobExecutorFacade();
jobExecutorFacade.setJobLocator(jobLocator);
jobExecutorFacade.setJobExecutionListeners(listeners);
jobExecutorFacade.setJobExecutor(jobExecutor);
jobExecutorFacade.setJobRepository(jobRepository);
this.jobExecutorFacade = jobExecutorFacade;
}
}
/**
* This method is wrapped in a Runnable by {@link #run(JobIdentifier)}, so
* that the internal housekeeping is done consistently. Subclasses should be
* careful to do the same.
*
* @param jobIdentifier
* @return
* @throws NoSuchJobException
*/
protected final void runInternal(JobExecution execution) throws NoSuchJobException {
JobIdentifier jobIdentifier = execution.getJobInstance().getIdentifier();
if (getJobExecution(jobIdentifier) == null) {
logger.info("Job already stopped (not launching): " + jobIdentifier);
return;
}
try {
logger.info("Launching: " + jobIdentifier);
jobExecutorFacade.start(execution);
logger.info("Completed successfully: " + jobIdentifier);
}
finally {
unregister(jobIdentifier);
}
}
/**
* Start the job using the task executor provided.
*
* @throws NoSuchJobException if the identifier cannot be used to locate a
* {@link Job}.
*
* @see org.springframework.batch.execution.launch.SimpleJobLauncher#run(org.springframework.batch.core.domain.JobIdentifier)
*/
public JobExecution run(final JobIdentifier jobIdentifier) throws NoSuchJobException,
JobExecutionAlreadyRunningException {
if (getJobExecution(jobIdentifier) != null) {
throw new JobExecutionAlreadyRunningException("A job is already executing with this identifier: ["
+ jobIdentifier + "]");
}
final JobExecution execution = jobExecutorFacade.createExecutionFrom(jobIdentifier);
// TODO: throw JobExecutionAlreadyRunningException if it is in a running
// state (someone else launched it)
final JobExecutionHolder holder = register(execution);
taskExecutor.execute(new Runnable() {
public void run() {
try {
synchronized (monitor) {
if (isInternalRunning(jobIdentifier)) {
logger.info("This job is already running, so not re-launched: " + jobIdentifier);
return;
}
}
holder.start();
runInternal(execution);
}
catch (NoSuchJobException e) {
applicationEventPublisher.publishEvent(new RepeatOperationsApplicationEvent(jobIdentifier,
"No such job", RepeatOperationsApplicationEvent.ERROR));
logger.error("Job could not be located inside Runnable for identifier: [" + jobIdentifier + "]", e);
}
finally {
holder.stop();
}
}
});
return execution;
}
/**
* Extension point for subclasses to stop a specific job.
*
* @throws NoSuchJobExecutionException
*/
protected void doStop(JobIdentifier jobIdentifier) throws NoSuchJobExecutionException {
JobExecution execution = getJobExecution(jobIdentifier);
logger.info("Stopping job: " + jobIdentifier);
if (execution != null) {
jobExecutorFacade.stop(execution);
}
unregister(jobIdentifier);
}
/**
* Stop all jobs if any are running. If not, no action will be taken.
* Delegates to the {@link #doStop()} method.
*
* @throws NoSuchJobExecutionException
* @see org.springframework.context.Lifecycle#stop()
* @see org.springframework.batch.execution.launch.JobLauncher#stop()
*/
final public void stop() {
for (Iterator iter = new HashSet(registry.keySet()).iterator(); iter.hasNext();) {
JobIdentifier context = (JobIdentifier) iter.next();
try {
stop(context);
}
catch (NoSuchJobExecutionException e) {
logger.error(e);
}
}
}
/**
* Stop a job with this {@link JobIdentifier}. Delegates to the
* {@link #doStop(JobIdentifier)} method.
*
* @throws NoSuchJobExecutionException
*
* @see org.springframework.batch.execution.launch.JobLauncher#stop(org.springframework.batch.core.domain.JobIdentifier)
* @see BatchContainer#stop(JobRuntimeInformation))
*/
final public void stop(JobIdentifier runtimeInformation) throws NoSuchJobExecutionException {
synchronized (monitor) {
doStop(runtimeInformation);
}
}
/**
* Stop all jobs with {@link JobIdentifier} having this name. Delegates to
* the {@link #stop(JobIdentifier)}.
*
* @throws NoSuchJobExecutionException
*
* @see org.springframework.batch.execution.launch.JobLauncher#stop(java.lang.String)
*/
final public void stop(String name) throws NoSuchJobExecutionException {
this.stop(jobIdentifierFactory.getJobIdentifier(name));
}
/**
* Check each registered {@link JobIdentifier} to see if it is running (@see
* {@link #isRunning(JobIdentifier)}), and if any are, then return true.
*
* @see org.springframework.batch.container.bootstrap.BatchContainerLauncher#isRunning()
*/
final public boolean isRunning() {
Collection jobs = new HashSet(registry.keySet());
for (Iterator iter = jobs.iterator(); iter.hasNext();) {
JobIdentifier jobIdentifier = (JobIdentifier) iter.next();
if (isInternalRunning(jobIdentifier)) {
return true;
}
}
return !jobs.isEmpty();
}
private boolean isInternalRunning(JobIdentifier jobIdentifier) {
synchronized (registry) {
JobExecutionHolder jobExecutionHolder = getJobExecutionHolder(jobIdentifier);
return isRunning(jobIdentifier) && jobExecutionHolder != null && jobExecutionHolder.isRunning();
}
}
/**
* Extension point for subclasses to check an individual
* {@link JobIdentifier} to see if it is running. As long as at least one
* job is running the launcher is deemed to be running.
*
* @param jobIdentifier a {@link JobIdentifier}
* @return always true. Subclasses can override and provide more accurate
* information.
*/
protected boolean isRunning(JobIdentifier jobIdentifier) {
return true;
}
/**
* Convenient synchronized accessor for the registry.
*
* @param jobIdentifier
* @return TODO
*/
private JobExecutionHolder register(JobExecution execution) {
JobExecutionHolder jobExecutionHolder = new JobExecutionHolder(execution);
synchronized (registry) {
registry.put(execution.getJobInstance().getIdentifier(), jobExecutionHolder);
}
return jobExecutionHolder;
}
/**
* Convenient synchronized accessor for the registry.
*
* @param jobIdentifier
*/
private JobExecution getJobExecution(JobIdentifier jobIdentifier) {
synchronized (registry) {
if (registry.containsKey(jobIdentifier)) {
return ((JobExecutionHolder) registry.get(jobIdentifier)).getExecution();
}
}
return null;
}
/**
* Convenient synchronized accessor for the registry.
*
* @param jobIdentifier
*/
private JobExecutionHolder getJobExecutionHolder(JobIdentifier jobIdentifier) {
synchronized (registry) {
if (registry.containsKey(jobIdentifier)) {
return (JobExecutionHolder) registry.get(jobIdentifier);
}
}
return null;
}
/**
* Convenient synchronized accessor for the registry. Must be used by
* subclasses to release the {@link JobIdentifier} when a job is finished
* (or stopped).
*
* @param jobIdentifier
*/
private void unregister(JobIdentifier jobIdentifier) {
synchronized (registry) {
registry.remove(jobIdentifier);
}
}
/**
* Setter for the {@link TaskExecutor}. Defaults to a
* {@link SyncTaskExecutor}.
*
* @param taskExecutor the taskExecutor to set
*/
public void setTaskExecutor(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
/**
* Accessor for the job executions currently in progress (and having been
* started from this launcher). If you launch a job synchronously then it
* will have finished when the {@link #run()} method returns, so there will
* be no statistics. Because the request is potentially fulfilled
* asynchronously, and only on demand, the data might be out of date by the
* time this method is called, so it should be used for information purposes
* only.
*
* @return Properties representing the {@link JobExecution} objects passed
* up from the underlying execution. If there are no jobs running it will be
* empty.
*/
public Properties getStatistics() {
if (jobExecutorFacade instanceof StatisticsProvider) {
return ((StatisticsProvider) jobExecutorFacade).getStatistics();
}
else {
return new Properties();
}
}
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
private class JobExecutionHolder {
private static final int NEW = 0;
private static final int STARTED = 1;
private static final int STOPPED = 2;
private JobExecution execution;
private int status = NEW;
public JobExecutionHolder(JobExecution execution) {
this.execution = execution;
}
JobExecution getExecution() {
return execution;
}
boolean isRunning() {
return status == STARTED;
}
void start() {
status = STARTED;
}
void stop() {
status = STOPPED;
}
}
}

View File

@@ -25,6 +25,7 @@ import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.Step;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
@@ -65,7 +66,7 @@ public class SimpleJobRepository implements JobRepository {
/**
* <p>
* Find or Create a (@link {@link JobExecution}) based on the passed in
* Create a (@link {@link JobExecution}) based on the passed in
* {@link JobIdentifier} and {@link Job}. However, unique
* identification of a job can only come from the database, and therefore
* must come from JobDao by either creating a new job or finding an existing
@@ -118,7 +119,7 @@ public class SimpleJobRepository implements JobRepository {
* platform does not support the higher isolation levels).
* </p>
*
* @see JobRepository#findOrCreateJob(Job, JobIdentifier)
* @see JobRepository#createJobExecution(Job, JobInstanceProperties)
*
* @throws BatchRestartException
* if more than one JobInstance if found or if
@@ -129,10 +130,13 @@ public class SimpleJobRepository implements JobRepository {
* {@link JobIdentifier} that is already running
*
*/
public JobExecution findOrCreateJob(Job job,
JobIdentifier jobIdentifier)
public JobExecution createJobExecution(Job job,
JobInstanceProperties jobInstanceProperties)
throws JobExecutionAlreadyRunningException {
Assert.notNull(job, "Job must not be null.");
Assert.notNull(jobInstanceProperties, "JobInstanceProperties must not be null.");
List jobs = new ArrayList();
JobInstance jobInstance;
@@ -148,7 +152,7 @@ public class SimpleJobRepository implements JobRepository {
* thread or process will block until this transaction has finished.
*/
jobs = jobDao.findJobs(jobIdentifier);
jobs = jobDao.findJobInstances(job.getName(), jobInstanceProperties);
}
if (jobs.size() == 1) {
@@ -172,7 +176,7 @@ public class SimpleJobRepository implements JobRepository {
}
} else if (jobs.size() == 0) {
// no job found, create one
jobInstance = createJob(job, jobIdentifier);
jobInstance = createJobInstance(job, jobInstanceProperties);
} else {
// More than one job found, throw exception
throw new BatchRestartException(
@@ -292,9 +296,9 @@ public class SimpleJobRepository implements JobRepository {
* calling {@link JobDao#createJob(JobRuntimeInformation)} and then it's
* list of StepConfigurations is passed to the createSteps method.
*/
private JobInstance createJob(Job job, JobIdentifier jobIdentifier) {
private JobInstance createJobInstance(Job job, JobInstanceProperties jobInstanceProperties) {
JobInstance jobInstance = jobDao.createJob(jobIdentifier);
JobInstance jobInstance = jobDao.createJobInstance(job.getName(), jobInstanceProperties);
jobInstance.setStepInstances(createStepInstances(jobInstance, job.getSteps()));
return jobInstance;
}

View File

@@ -20,6 +20,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -32,10 +33,13 @@ import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.JobInstancePropertiesBuilder;
import org.springframework.batch.core.repository.NoSuchBatchDomainObjectException;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
import org.springframework.util.Assert;
@@ -60,11 +64,11 @@ public class JdbcJobDao implements JobDao, InitializingBean {
// Job SQL statements
private static final String CREATE_JOB = "INSERT into %PREFIX%JOB_INSTANCE(ID, JOB_NAME, JOB_KEY)"
+ " values (?, ?, ?)";
private static final String CREATE_JOB_PARAMETERS = "INSERT into %PREFIX%JOB_INSTANCE_PROPERTIES(JOB_ID, KEY, TYPE_CD, "
+ "STRING_VAL, DATE_VAL, LONG_VAL) values (?, ?, ?, ?, ?, ?)";
/**
private static final String CREATE_JOB_PARAMETERS = "INSERT into %PREFIX%JOB_INSTANCE_PROPERTIES(JOB_ID, KEY, TYPE_CD, " +
"STRING_VAL, DATE_VAL, LONG_VAL) values (?, ?, ?, ?, ?, ?)";
/**
* Default value for the table prefix property.
*/
public static final String DEFAULT_TABLE_PREFIX = "BATCH_";
@@ -106,7 +110,8 @@ public class JdbcJobDao implements JobDao, InitializingBean {
Assert.notNull(jdbcTemplate, "JdbcTemplate cannot be null");
Assert.notNull(jobIncrementer, "JobIncrementor cannot be null");
Assert.notNull(jobExecutionIncrementer, "JobExecutionIncrementer cannot be null");
Assert.notNull(jobExecutionIncrementer,
"JobExecutionIncrementer cannot be null");
}
/**
@@ -116,33 +121,34 @@ public class JdbcJobDao implements JobDao, InitializingBean {
* into an INSERT statement.
*
* @see JobDao#createJob(JobIdentifier)
* @throws IllegalArgumentException if any {@link JobIdentifier} fields are
* null.
* @throws IllegalArgumentException
* if any {@link JobIdentifier} fields are null.
*/
public JobInstance createJob(JobIdentifier jobIdentifier) {
public JobInstance createJobInstance(String jobName, JobInstanceProperties jobInstanceProperties) {
validateJobIdentifier(jobIdentifier);
Assert.notNull(jobName, "Job Name must not be null.");
Assert.notNull(jobInstanceProperties, "JobInstanceProperties must not be null.");
Long jobId = new Long(jobIncrementer.nextLongValue());
Object[] parameters = new Object[] { jobId, jobIdentifier.getName(),
createJobKey(jobIdentifier.getJobInstanceProperties()) };
jdbcTemplate.update(getCreateJobQuery(), parameters, new int[] { Types.INTEGER, Types.VARCHAR, Types.VARCHAR });
Object[] parameters = new Object[] { jobId, jobName, createJobKey(jobInstanceProperties) };
jdbcTemplate.update(getCreateJobQuery(), parameters, new int[] {
Types.INTEGER, Types.VARCHAR, Types.VARCHAR});
insertJobParameters(jobId, jobIdentifier.getJobInstanceProperties());
JobInstance job = new JobInstance(jobIdentifier, jobId);
return job;
insertJobParameters(jobId, jobInstanceProperties);
JobInstance jobInstance = new JobInstance(jobId, jobInstanceProperties);
return jobInstance;
}
private String createJobKey(JobInstanceProperties jobInstanceProperties) {
private String createJobKey(JobInstanceProperties jobInstanceProperties){
Map props = jobInstanceProperties.getParameters();
StringBuilder stringBuilder = new StringBuilder("params:");
for (Iterator it = props.entrySet().iterator(); it.hasNext();) {
Entry entry = (Entry) it.next();
StringBuilder stringBuilder = new StringBuilder();
for(Iterator it = props.entrySet().iterator();it.hasNext();){
Entry entry = (Entry)it.next();
stringBuilder.append(entry.toString() + ";");
}
return stringBuilder.toString();
}
@@ -151,29 +157,31 @@ public class JdbcJobDao implements JobDao, InitializingBean {
Assert.notNull(job, "Job cannot be null.");
Assert.notNull(job.getId(), "Job Id cannot be null.");
return jdbcTemplate.query(getQuery(JobExecutionRowMapper.FIND_JOB_EXECUTIONS), new Object[] { job.getId() },
new JobExecutionRowMapper(job));
return jdbcTemplate.query(
getQuery(JobExecutionRowMapper.FIND_JOB_EXECUTIONS),
new Object[] { job.getId() }, new JobExecutionRowMapper(job));
}
/**
* The job table is queried for <strong>any</strong> jobs that match the
* given identifier, adding them to a list via the RowMapper callback.
*
* @see JobDao#findJobs(JobIdentifier)
* @throws IllegalArgumentException if any {@link JobIdentifier} fields are
* null.
* @see JobDao#findJobInstances(JobIdentifier)
* @throws IllegalArgumentException
* if any {@link JobIdentifier} fields are null.
*/
public List findJobs(final JobIdentifier jobIdentifier) {
public List findJobInstances(final String jobName, final JobInstanceProperties jobInstanceProperties) {
validateJobIdentifier(jobIdentifier);
Assert.notNull(jobName, "Job Name must not be null.");
Assert.notNull(jobInstanceProperties, "JobInstanceProperties must not be null.");
Object[] parameters = new Object[] { jobIdentifier.getName(),
createJobKey(jobIdentifier.getJobInstanceProperties()) };
Object[] parameters = new Object[] { jobName,
createJobKey(jobInstanceProperties) };
RowMapper rowMapper = new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
JobInstance job = new JobInstance(jobIdentifier, new Long(rs.getLong(1)));
JobInstance job = new JobInstance(new Long(rs.getLong(1)), jobInstanceProperties);
job.setStatus(BatchStatus.getStatus(rs.getString(2)));
return job;
@@ -194,14 +202,15 @@ public class JdbcJobDao implements JobDao, InitializingBean {
private String getFindJobsQuery() {
return getQuery(FIND_JOBS);
}
private String getCreateJobParamsQuery() {
private String getCreateJobParamsQuery(){
return getQuery(CREATE_JOB_PARAMETERS);
}
/**
* @see JobDao#getJobExecutionCount(JobInstance)
* @throws IllegalArgumentException if jobId is null.
* @throws IllegalArgumentException
* if jobId is null.
*/
public int getJobExecutionCount(Long jobId) {
@@ -209,7 +218,8 @@ public class JdbcJobDao implements JobDao, InitializingBean {
Object[] parameters = new Object[] { jobId };
return jdbcTemplate.queryForInt(getJobExecutionCountQuery(), parameters);
return jdbcTemplate
.queryForInt(getJobExecutionCountQuery(), parameters);
}
private String getJobExecutionCountQuery() {
@@ -231,65 +241,59 @@ public class JdbcJobDao implements JobDao, InitializingBean {
private String getUpdateJobQuery() {
return getQuery(UPDATE_JOB);
}
/*
* Convenience method that inserts all parameters from the provided
* JobParameters.
* Convenience method that inserts all parameters from the provided JobParameters.
*
*/
private void insertJobParameters(Long jobId, JobInstanceProperties jobParameters) {
private void insertJobParameters(Long jobId, JobInstanceProperties jobParameters){
Map parameters = jobParameters.getStringParameters();
if (!parameters.isEmpty()) {
for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) {
Entry entry = (Entry) it.next();
insertParameter(jobId, ParameterType.STRING, entry.getKey().toString(), entry.getValue());
if(!parameters.isEmpty()){
for(Iterator it = parameters.entrySet().iterator(); it.hasNext();){
Entry entry = (Entry)it.next();
insertParameter(jobId, ParameterType.STRING, entry.getKey().toString(), entry.getValue());
}
}
parameters = jobParameters.getLongParameters();
if (!parameters.isEmpty()) {
for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) {
Entry entry = (Entry) it.next();
insertParameter(jobId, ParameterType.LONG, entry.getKey().toString(), entry.getValue());
if(!parameters.isEmpty()){
for(Iterator it = parameters.entrySet().iterator(); it.hasNext();){
Entry entry = (Entry)it.next();
insertParameter(jobId, ParameterType.LONG, entry.getKey().toString(), entry.getValue());
}
}
parameters = jobParameters.getDateParameters();
if (!parameters.isEmpty()) {
for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) {
Entry entry = (Entry) it.next();
insertParameter(jobId, ParameterType.DATE, entry.getKey().toString(), entry.getValue());
if(!parameters.isEmpty()){
for(Iterator it = parameters.entrySet().iterator(); it.hasNext();){
Entry entry = (Entry)it.next();
insertParameter(jobId, ParameterType.DATE, entry.getKey().toString(), entry.getValue());
}
}
}
/*
* Convenience method that inserts an individual records into the
* JobParameters table. Uses non-null values in the "empty" columns to avoid
* any possible ambiguity between null and a real value (on some platforms
* it is sometimes a problem). The type of the value is fixed by the type
* code anyway, so the value is not ambiguous.
* Convenience method that inserts an individual records into the JobParameters table.
*/
private void insertParameter(Long jobId, ParameterType type, String key, Object value) {
private void insertParameter(Long jobId, ParameterType type, String key, Object value){
Object[] args = new Object[0];
int[] argTypes = new int[] { Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP,
Types.INTEGER };
if (type == ParameterType.STRING) {
args = new Object[] { jobId, key, type, value, new Timestamp(0L), new Long(0) };
int[] argTypes = new int[]{Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP, Types.INTEGER};
if(type == ParameterType.STRING){
args = new Object[]{jobId, key, type, value, new Timestamp(0L), new Long(0)};
}
else if (type == ParameterType.LONG) {
args = new Object[] { jobId, key, type, "", new Timestamp(0L), value };
else if(type == ParameterType.LONG){
args = new Object[]{jobId, key, type, "", new Timestamp(0L), value};
}
else if (type == ParameterType.DATE) {
args = new Object[] { jobId, key, type, "", value, new Long(0) };
else if(type == ParameterType.DATE){
args = new Object[]{jobId, key, type, "", value, new Long(0)};
}
jdbcTemplate.update(getCreateJobParamsQuery(), args, argTypes);
}
@@ -300,20 +304,24 @@ public class JdbcJobDao implements JobDao, InitializingBean {
* via a SQL INSERT statement.
*
* @see JobDao#save(JobExecution)
* @throws IllegalArgumentException if jobExecution is null, as well as any
* of it's fields to be persisted.
* @throws IllegalArgumentException
* if jobExecution is null, as well as any of it's fields to be
* persisted.
*/
public void save(JobExecution jobExecution) {
validateJobExecution(jobExecution);
jobExecution.setId(new Long(jobExecutionIncrementer.nextLongValue()));
Object[] parameters = new Object[] { jobExecution.getId(), jobExecution.getJobId(),
jobExecution.getStartTime(), jobExecution.getEndTime(), jobExecution.getStatus().toString(),
jobExecution.getExitStatus().isContinuable() ? "Y" : "N", jobExecution.getExitStatus().getExitCode(),
Object[] parameters = new Object[] { jobExecution.getId(),
jobExecution.getJobId(), jobExecution.getStartTime(),
jobExecution.getEndTime(), jobExecution.getStatus().toString(),
jobExecution.getExitStatus().isContinuable() ? "Y" : "N",
jobExecution.getExitStatus().getExitCode(),
jobExecution.getExitStatus().getExitDescription() };
jdbcTemplate.update(getSaveJobExecutionQuery(), parameters, new int[] { Types.INTEGER, Types.INTEGER,
Types.TIMESTAMP, Types.TIMESTAMP, Types.VARCHAR, Types.CHAR, Types.VARCHAR, Types.VARCHAR });
jdbcTemplate.update(getSaveJobExecutionQuery(), parameters, new int[] {
Types.INTEGER, Types.INTEGER, Types.TIMESTAMP, Types.TIMESTAMP,
Types.VARCHAR, Types.CHAR, Types.VARCHAR, Types.VARCHAR });
}
public void setJdbcTemplate(JdbcOperations jdbcTemplate) {
@@ -324,9 +332,11 @@ public class JdbcJobDao implements JobDao, InitializingBean {
* Setter for {@link DataFieldMaxValueIncrementer} to be used when
* generating primary keys for {@link JobExecution} instances.
*
* @param jobExecutionIncrementer the {@link DataFieldMaxValueIncrementer}
* @param jobExecutionIncrementer
* the {@link DataFieldMaxValueIncrementer}
*/
public void setJobExecutionIncrementer(DataFieldMaxValueIncrementer jobExecutionIncrementer) {
public void setJobExecutionIncrementer(
DataFieldMaxValueIncrementer jobExecutionIncrementer) {
this.jobExecutionIncrementer = jobExecutionIncrementer;
}
@@ -334,7 +344,8 @@ public class JdbcJobDao implements JobDao, InitializingBean {
* Setter for {@link DataFieldMaxValueIncrementer} to be used when
* generating primary keys for {@link JobInstance} instances.
*
* @param jobIncrementer the {@link DataFieldMaxValueIncrementer}
* @param jobIncrementer
* the {@link DataFieldMaxValueIncrementer}
*/
public void setJobIncrementer(DataFieldMaxValueIncrementer jobIncrementer) {
this.jobIncrementer = jobIncrementer;
@@ -345,7 +356,8 @@ public class JdbcJobDao implements JobDao, InitializingBean {
* the table names before queries are executed. Defaults to
* {@value #DEFAULT_TABLE_PREFIX}.
*
* @param tablePrefix the tablePrefix to set
* @param tablePrefix
* the tablePrefix to set
*/
public void setTablePrefix(String tablePrefix) {
this.tablePrefix = tablePrefix;
@@ -363,35 +375,48 @@ public class JdbcJobDao implements JobDao, InitializingBean {
validateJobExecution(jobExecution);
String exitDescription = jobExecution.getExitStatus().getExitDescription();
if (exitDescription != null && exitDescription.length() > EXIT_MESSAGE_LENGTH) {
String exitDescription = jobExecution.getExitStatus()
.getExitDescription();
if (exitDescription != null
&& exitDescription.length() > EXIT_MESSAGE_LENGTH) {
exitDescription = exitDescription.substring(0, EXIT_MESSAGE_LENGTH);
logger.debug("Truncating long message before update of JobExecution: " + jobExecution);
logger
.debug("Truncating long message before update of JobExecution: "
+ jobExecution);
}
Object[] parameters = new Object[] { jobExecution.getStartTime(), jobExecution.getEndTime(),
jobExecution.getStatus().toString(), jobExecution.getExitStatus().isContinuable() ? "Y" : "N",
jobExecution.getExitStatus().getExitCode(), exitDescription, jobExecution.getId() };
Object[] parameters = new Object[] { jobExecution.getStartTime(),
jobExecution.getEndTime(), jobExecution.getStatus().toString(),
jobExecution.getExitStatus().isContinuable() ? "Y" : "N",
jobExecution.getExitStatus().getExitCode(), exitDescription,
jobExecution.getId() };
if (jobExecution.getId() == null) {
throw new IllegalArgumentException("JobExecution ID cannot be null. JobExecution must be saved "
+ "before it can be updated.");
throw new IllegalArgumentException(
"JobExecution ID cannot be null. JobExecution must be saved "
+ "before it can be updated.");
}
// Check if given JobExecution's Id already exists, if none is found it
// is invalid and
// an exception should be thrown.
if (jdbcTemplate.queryForInt(getCheckJobExecutionExistsQuery(), new Object[] { jobExecution.getId() }) != 1) {
throw new NoSuchBatchDomainObjectException("Invalid JobExecution, ID " + jobExecution.getId()
+ " not found.");
if (jdbcTemplate.queryForInt(getCheckJobExecutionExistsQuery(),
new Object[] { jobExecution.getId() }) != 1) {
throw new NoSuchBatchDomainObjectException(
"Invalid JobExecution, ID " + jobExecution.getId()
+ " not found.");
}
jdbcTemplate.update(getUpdateJobExecutionQuery(), parameters, new int[] { Types.TIMESTAMP, Types.TIMESTAMP,
Types.VARCHAR, Types.CHAR, Types.VARCHAR, Types.VARCHAR, Types.INTEGER });
jdbcTemplate
.update(getUpdateJobExecutionQuery(), parameters,
new int[] { Types.TIMESTAMP, Types.TIMESTAMP,
Types.VARCHAR, Types.CHAR, Types.VARCHAR,
Types.VARCHAR, Types.INTEGER });
}
/**
* @see JobDao#update(JobInstance)
* @throws IllegalArgumentException if Job, Job.status, or job.id is null
* @throws IllegalArgumentException
* if Job, Job.status, or job.id is null
*/
public void update(JobInstance job) {
@@ -399,8 +424,10 @@ public class JdbcJobDao implements JobDao, InitializingBean {
Assert.notNull(job.getStatus(), "Job Status cannot be Null");
Assert.notNull(job.getId(), "Job ID cannot be null");
Object[] parameters = new Object[] { job.getStatus().toString(), job.getId() };
jdbcTemplate.update(getUpdateJobQuery(), parameters, new int[] { Types.VARCHAR, Types.INTEGER });
Object[] parameters = new Object[] { job.getStatus().toString(),
job.getId() };
jdbcTemplate.update(getUpdateJobQuery(), parameters, new int[] {
Types.VARCHAR, Types.INTEGER});
}
/*
@@ -412,9 +439,12 @@ public class JdbcJobDao implements JobDao, InitializingBean {
private void validateJobExecution(JobExecution jobExecution) {
Assert.notNull(jobExecution);
Assert.notNull(jobExecution.getJobId(), "JobExecution Job-Id cannot be null.");
Assert.notNull(jobExecution.getStartTime(), "JobExecution start time cannot be null.");
Assert.notNull(jobExecution.getStatus(), "JobExecution status cannot be null.");
Assert.notNull(jobExecution.getJobId(),
"JobExecution Job-Id cannot be null.");
Assert.notNull(jobExecution.getStartTime(),
"JobExecution start time cannot be null.");
Assert.notNull(jobExecution.getStatus(),
"JobExecution status cannot be null.");
}
/**
@@ -425,7 +455,8 @@ public class JdbcJobDao implements JobDao, InitializingBean {
private void validateJobIdentifier(JobIdentifier jobIdentifier) {
Assert.notNull(jobIdentifier, "JobIdentifier cannot be null.");
Assert.notNull(jobIdentifier.getName(), "JobIdentifier name cannot be null.");
Assert.notNull(jobIdentifier.getName(),
"JobIdentifier name cannot be null.");
Assert.notNull(jobIdentifier.getJobInstanceProperties(), "JobIdentifier runtime parameters must not be null.");
}
@@ -456,42 +487,86 @@ public class JdbcJobDao implements JobDao, InitializingBean {
jobExecution.setStartTime(rs.getTimestamp(2));
jobExecution.setEndTime(rs.getTimestamp(3));
jobExecution.setStatus(BatchStatus.getStatus(rs.getString(4)));
jobExecution.setExitStatus(new ExitStatus("Y".equals(rs.getString(5)), rs.getString(6), rs.getString(7)));
jobExecution.setExitStatus(new ExitStatus("Y".equals(rs
.getString(5)), rs.getString(6), rs.getString(7)));
return jobExecution;
}
}
/*
* Private inner class for mapping values from the JOB_PARAMETERS table into the java
* JobParameters class. TODO: is this going to be used? If not can we delete it?
*/
private static class JobParameterCallbackHandler implements RowCallbackHandler{
private JobInstancePropertiesBuilder parametersBuilder;
public JobParameterCallbackHandler() {
parametersBuilder = new JobInstancePropertiesBuilder();
}
public void processRow(ResultSet rs) throws SQLException {
ParameterType parameterType = ParameterType.getType(rs.getString("TYPE_CD"));
String key = rs.getString("KEY");
if(parameterType == ParameterType.STRING){
parametersBuilder.addString(key, rs.getString("STRING_VAL"));
}
else if(parameterType == ParameterType.LONG){
parametersBuilder.addLong(key, new Long(rs.getLong("LONG_VAL")));
}
else if(parameterType == ParameterType.DATE){
//I debated about just passing the Timestamp in, however, I didn't want there to be any equality
//issues when comparing a java.util.Date to a timestamp.
Timestamp ts = rs.getTimestamp("DATE_VAL");
parametersBuilder.addDate(key, new Date(ts.getTime()));
}
else{
//invalid type code, error out.
throw new DataRetrievalFailureException("Invalid JobParameter type");
}
}
public JobInstanceProperties getJobParmeters(){
return parametersBuilder.toJobParameters();
}
}
private static class ParameterType {
private final String type;
private ParameterType(String type) {
this.type = type;
}
public String toString() {
public String toString(){
return type;
}
public static final ParameterType STRING = new ParameterType("STRING");
public static final ParameterType DATE = new ParameterType("DATE");
public static final ParameterType LONG = new ParameterType("LONG");
private static final ParameterType[] VALUES = {STRING, DATE, LONG};
private static final ParameterType[] VALUES = { STRING, DATE, LONG };
public static ParameterType getType(String typeAsString) {
for (int i = 0; i < VALUES.length; i++) {
if (VALUES[i].toString().equals(typeAsString)) {
return (ParameterType) VALUES[i];
public static ParameterType getType(String typeAsString){
for(int i = 0; i < VALUES.length; i++){
if(VALUES[i].toString().equals(typeAsString)){
return (ParameterType)VALUES[i];
}
}
return null;
}
}
}

View File

@@ -21,6 +21,7 @@ import java.util.List;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
/**
* Data Access Object for jobs.
@@ -39,7 +40,7 @@ public interface JobDao {
* @param jobIdentifier
* @return Job
*/
public JobInstance createJob(JobIdentifier jobIdentifier);
public JobInstance createJobInstance(String jobName, JobInstanceProperties jobInstanceProperties);
/**
* Find all jobs that match the given JobIdentifier. If no jobs matching the
@@ -49,7 +50,7 @@ public interface JobDao {
* @return List of {@link JobInstance} objects matching
* {@link JobIdentifier}
*/
public List findJobs(JobIdentifier jobIdentifier);
public List findJobInstances(String jobName, JobInstanceProperties jobInstanceProperties);
/**
* Update an existing Job.

View File

@@ -22,9 +22,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.support.transaction.TransactionAwareProxyFactory;
public class MapJobDao implements JobDao {
@@ -44,19 +46,20 @@ public class MapJobDao implements JobDao {
executionsById.clear();
}
public JobInstance createJob(JobIdentifier jobIdentifier) {
JobInstance job = new JobInstance(jobIdentifier, new Long(currentId++));
jobsById.put(job.getId(), job);
return job;
public JobInstance createJobInstance(String jobName, JobInstanceProperties jobInstanceProperties) {
JobInstance jobInstance = new JobInstance(new Long(currentId++), jobInstanceProperties);
jobInstance.setJob(new Job(jobName));
jobsById.put(jobInstance.getId(), jobInstance);
return jobInstance;
}
public List findJobs(JobIdentifier jobIdentifier) {
public List findJobInstances(String jobName, JobInstanceProperties jobInstanceProperties) {
List list = new ArrayList();
for (Iterator iter = jobsById.values().iterator(); iter.hasNext();) {
JobInstance job = (JobInstance) iter.next();
if (job.getName().equals(jobIdentifier.getName())) {
list.add(job);
JobInstance jobInstance = (JobInstance) iter.next();
if (jobInstance.getJobName().equals(jobName) && jobInstance.getJobInstanceProperties().equals(jobInstanceProperties)) {
list.add(jobInstance);
}
}
return list;

View File

@@ -65,14 +65,12 @@ public class BatchResourceFactoryBean extends AbstractFactoryBean implements
private static final String BATCH_ROOT_PATTERN = "%BATCH_ROOT%";
private static final String JOB_IDENTIFIER_PATTERN = "%JOB_IDENTIFIER%";
private static final String JOB_NAME_PATTERN = "%JOB_NAME%";
private static final String STEP_NAME_PATTERN = "%STEP_NAME%";
private static final String DEFAULT_PATTERN = "/%BATCH_ROOT%/data/%JOB_NAME%/"
+ "%JOB_IDENTIFIER%-%STEP_NAME%.txt";
+ "%STEP_NAME%.txt";
private String filePattern = DEFAULT_PATTERN;
@@ -84,10 +82,6 @@ public class BatchResourceFactoryBean extends AbstractFactoryBean implements
private ResourceLoader resourceLoader = new FileSystemResourceLoader();
private JobIdentifier jobIdentifier;
private JobIdentifierLabelGenerator jobIdentifierLabelGenerator = new DefaultJobIdentifierLabelGenerator();
/**
* Always false because we are expecting to be step scoped.
*
@@ -106,17 +100,6 @@ public class BatchResourceFactoryBean extends AbstractFactoryBean implements
this.resourceLoader = resourceLoader;
}
/**
* Public setter for the {@link JobIdentifierLabelGenerator} property.
*
* @param jobIdentifierLabelGenerator
* the {@link JobIdentifierLabelGenerator} to set
*/
public void setJobIdentifierLabelGenerator(
JobIdentifierLabelGenerator jobIdentifierLabelGenerator) {
this.jobIdentifierLabelGenerator = jobIdentifierLabelGenerator;
}
/**
* Collect the properties of the enclosing {@link StepExecution} that will
* be needed to create a file name.
@@ -128,8 +111,7 @@ public class BatchResourceFactoryBean extends AbstractFactoryBean implements
"The StepContext does not have an execution.");
StepExecution execution = context.getStepExecution();
stepName = execution.getStep().getName();
jobName = execution.getStep().getJobInstance().getName();
jobIdentifier = execution.getJobExecution().getJobInstance().getIdentifier();
jobName = execution.getStep().getJobInstance().getJobName();
}
/**
@@ -180,8 +162,6 @@ public class BatchResourceFactoryBean extends AbstractFactoryBean implements
fileName = replacePattern(fileName, JOB_NAME_PATTERN,
jobName == null ? "job" : jobName);
fileName = replacePattern(fileName, STEP_NAME_PATTERN, stepName);
fileName = replacePattern(fileName, JOB_IDENTIFIER_PATTERN,
jobIdentifierLabelGenerator.getLabel(jobIdentifier));
return fileName;
}

View File

@@ -157,7 +157,7 @@ public class SimpleStepExecutor implements StepExecutor {
stepScopeContext.setStepExecution(stepExecution);
// Add the job identifier so that it can be used to identify
// the conversation in StepScope
stepScopeContext.setAttribute(StepScope.ID_KEY, stepExecution.getJobExecution().getJobInstance().getIdentifier());
stepScopeContext.setAttribute(StepScope.ID_KEY, stepExecution.getJobExecution().getId());
try {
stepExecution.setStartTime(new Date(System.currentTimeMillis()));

View File

@@ -17,8 +17,10 @@ package org.springframework.batch.execution.bootstrap.support;
import junit.framework.TestCase;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.beans.factory.access.BeanFactoryLocator;
@@ -142,22 +144,23 @@ public class SimpleCommandLineJobRunnerTests extends TestCase {
*/
public void testCustomJobName() {
buildContext(TEST_BATCH_ENVIRONMENT_KEY);
assertNotNull(jobLauncher);
assertNotNull(systemExiter);
setReturnValue(ExitStatus.FINISHED);
System.setProperty(JOB_NAME_KEY, "foo");
SimpleCommandLineJobRunner.main(new String[0]);
assertEquals(ExitCodeMapper.JVM_EXITCODE_COMPLETED, systemExiter
.getStatus());
assertEquals(jobLauncher.getLastRunCalled(),
StubJobLauncher.RUN_JOB_IDENTIFIER);
// buildContext(TEST_BATCH_ENVIRONMENT_KEY);
// assertNotNull(jobLauncher);
// assertNotNull(systemExiter);
// setReturnValue(ExitStatus.FINISHED);
//
// System.setProperty(JOB_NAME_KEY, "foo");
// SimpleCommandLineJobRunner.main(new String[0]);
//
// assertEquals(ExitCodeMapper.JVM_EXITCODE_COMPLETED, systemExiter
// .getStatus());
// assertEquals(jobLauncher.getLastRunCalled(),
// StubJobLauncher.RUN_JOB_IDENTIFIER);
}
private void setReturnValue(ExitStatus status) {
JobExecution execution = new JobExecution(new JobInstance(new SimpleJobIdentifier("foo")));
JobExecution execution = new JobExecution(new JobInstance(new Long(1), new JobInstanceProperties(), new Job("foo")));
execution.setExitStatus(status);
jobLauncher.setReturnValue(execution);
}

View File

@@ -1,8 +1,11 @@
package org.springframework.batch.execution.bootstrap.support;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.NoSuchJobException;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.execution.launch.JobLauncher;
/**
@@ -29,8 +32,8 @@ public class StubJobLauncher implements JobLauncher {
return isRunning;
}
public JobExecution run(JobIdentifier jobIdentifier)
throws NoSuchJobException {
public JobExecution run(Job job, JobInstanceProperties jobInstanceProperties)
throws JobExecutionAlreadyRunningException {
lastRunCalled = RUN_JOB_IDENTIFIER;
return returnValue;
}

View File

@@ -25,6 +25,7 @@ import org.springframework.batch.core.domain.BatchStatus;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.Step;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
@@ -96,8 +97,8 @@ public class DefaultJobExecutorTests extends TestCase {
private StepSupport stepConfiguration2;
private Job jobConfiguration;
private SimpleJobIdentifier jobIdentifer;
private JobInstanceProperties jobInstanceProperties = new JobInstanceProperties();
private DefaultJobExecutor jobExecutor;
@@ -124,18 +125,17 @@ public class DefaultJobExecutorTests extends TestCase {
stepConfigurations.add(stepConfiguration1);
stepConfigurations.add(stepConfiguration2);
jobConfiguration = new Job();
jobConfiguration.setName("testJob");
jobConfiguration.setSteps(stepConfigurations);
jobIdentifer = new SimpleJobIdentifier("TestJob");
jobExecution = jobRepository.findOrCreateJob(jobConfiguration, jobIdentifer);
jobExecution = jobRepository.createJobExecution(jobConfiguration, jobInstanceProperties);
job = jobExecution.getJobInstance();
List steps = job.getStepInstances();
step1 = (StepInstance) steps.get(0);
step2 = (StepInstance) steps.get(1);
stepExecution1 = new StepExecution(step1, jobExecution);
stepExecution2 = new StepExecution(step2, jobExecution);
stepExecution1 = new StepExecution(step1, jobExecution, null);
stepExecution2 = new StepExecution(step2, jobExecution, null);
}
@@ -283,7 +283,7 @@ public class DefaultJobExecutorTests extends TestCase {
* Check JobRepository to ensure status is being saved.
*/
private void checkRepository(BatchStatus status, ExitStatus exitStatus) {
assertEquals(job, jobDao.findJobs(jobIdentifer).get(0));
assertEquals(job, jobDao.findJobInstances(job.getJobName(), jobInstanceProperties).get(0));
// because map dao stores in memory, it can be checked directly
assertEquals(status, job.getStatus());
JobExecution jobExecution = (JobExecution) jobDao

View File

@@ -1,164 +0,0 @@
/**
*
*/
package org.springframework.batch.execution.launch;
import java.util.Collection;
import java.util.Iterator;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobLocator;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.core.executor.JobExecutor;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.repeat.ExitStatus;
/**
* @author Lucas Ward
*
*/
public class DefaultJobLauncherTests extends TestCase {
private DefaultJobLauncher jobLauncher;
private JobExecutor jobExecutor;
private JobRepository jobRepository;
private JobLocator jobLocator;
private MockControl executorControl = MockControl.createControl(JobExecutor.class);
private MockControl repositoryControl = MockControl.createControl(JobRepository.class);
private MockControl locatorControl = MockControl.createControl(JobLocator.class);
private JobIdentifier jobIdentifier = new SimpleJobIdentifier("job");
private Job job = new Job();
private JobExecution jobExecution = new JobExecution(null);
JobExecutor blockingExecutor = new BlockingExecutor();
protected void setUp() throws Exception {
super.setUp();
jobLauncher = new DefaultJobLauncher();
jobExecutor = (JobExecutor)executorControl.getMock();
jobRepository = (JobRepository)repositoryControl.getMock();
jobLocator = (JobLocator)locatorControl.getMock();
jobLauncher.setJobExecutor(jobExecutor);
jobLauncher.setJobRepository(jobRepository);
jobLauncher.setJobLocator(jobLocator);
}
public void testRun() throws Exception{
jobLocator.getJob("job");
locatorControl.setDefaultReturnValue(job);
jobRepository.findOrCreateJob(job, jobIdentifier);
repositoryControl.setReturnValue(new JobExecution(null));
jobExecutor.run(job, jobExecution);
executorControl.setDefaultReturnValue(ExitStatus.FINISHED);
locatorControl.replay();
repositoryControl.replay();
executorControl.replay();
jobLauncher.run(jobIdentifier);
locatorControl.verify();
repositoryControl.verify();
executorControl.verify();
}
public void testIsRunning() throws Exception{
jobLauncher.setJobExecutor(blockingExecutor);
jobLocator.getJob("job");
locatorControl.setDefaultReturnValue(job);
jobRepository.findOrCreateJob(job, jobIdentifier);
repositoryControl.setReturnValue(jobExecution);
locatorControl.replay();
repositoryControl.replay();
jobLauncher.run(jobIdentifier);
assertTrue(jobLauncher.isRunning(jobIdentifier));
Thread.sleep(250);
assertFalse(jobLauncher.isRunning(jobIdentifier));
assertEquals(ExitStatus.FINISHED, jobExecution.getExitStatus());
}
public void testAlreadyRunningJob() throws Exception{
jobLauncher.setJobExecutor(blockingExecutor);
jobLocator.getJob("job");
locatorControl.setDefaultReturnValue(job);
jobRepository.findOrCreateJob(job, jobIdentifier);
repositoryControl.setReturnValue(jobExecution);
locatorControl.replay();
repositoryControl.replay();
jobLauncher.run(jobIdentifier);
assertTrue(jobLauncher.isRunning(jobIdentifier));
try{
jobLauncher.run(jobIdentifier);
fail();
}
catch(JobExecutionAlreadyRunningException ex){
//expected
}
}
public void testStop() throws Exception{
jobLauncher.setJobExecutor(blockingExecutor);
jobExecution.createStepExecution(new StepInstance(null, "step"));
jobLocator.getJob("job");
locatorControl.setDefaultReturnValue(job);
jobRepository.findOrCreateJob(job, jobIdentifier);
repositoryControl.setReturnValue(jobExecution);
locatorControl.replay();
repositoryControl.replay();
jobLauncher.run(jobIdentifier);
assertTrue(jobLauncher.isRunning(jobIdentifier));
jobLauncher.stop(jobIdentifier);
Collection contexts = jobExecution.getStepExecutions();
for(Iterator it = contexts.iterator();it.hasNext();){
StepExecution context = (StepExecution)it.next();
assertTrue(context.isTerminateOnly());
}
}
private class BlockingExecutor implements JobExecutor{
public ExitStatus run(Job job, JobExecution execution)
throws BatchCriticalException {
try{
Thread.sleep(50);
}
catch(InterruptedException ex){
throw new RuntimeException(ex);
}
return ExitStatus.FINISHED;
}
};
}

View File

@@ -42,47 +42,50 @@ import org.springframework.core.task.TaskExecutor;
*/
public class InterruptJobTests extends TestCase {
public void testInterruptUsingListener() throws Exception {
// final InterruptibleFacade facade = new InterruptibleFacade();
// facade.setListener(new ThreadInterruptJobExecutionListener());
final SimpleJobExecutorFacade facade = new SimpleJobExecutorFacade();
facade.setJobExecutor(new InterruptibleJobExecutor());
facade.setJobRepository(new SimpleJobRepository(new MapJobDao(),
new MapStepDao()));
facade.setJobExecutionListeners(Collections
.singletonList(new ThreadInterruptJobExecutionListener()));
MapJobRegistry registry = new MapJobRegistry();
facade.setJobLocator(registry);
registry.register(new Job("foo"));
final SimpleJobIdentifier identifier = new SimpleJobIdentifier("foo");
final JobExecution execution = facade.createExecutionFrom(identifier);
TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
Runnable launcherRunnable = new Runnable() {
public void run() {
try {
facade.start(execution);
} catch (NoSuchJobException e) {
fail("Unexpected NoSuchJobConfigurationException");
}
}
};
taskExecutor.execute(launcherRunnable);
// give the thread a second to start up
Thread.sleep(100);
assertTrue(facade.isRunning());
facade.stop(execution);
Thread.sleep(100);
assertFalse(facade.isRunning());
}
//JabExecutorFacade is deprecated.
// public void testInterruptUsingListener() throws Exception {
//
// // final InterruptibleFacade facade = new InterruptibleFacade();
// // facade.setListener(new ThreadInterruptJobExecutionListener());
// final SimpleJobExecutorFacade facade = new SimpleJobExecutorFacade();
// facade.setJobExecutor(new InterruptibleJobExecutor());
//
// facade.setJobRepository(new SimpleJobRepository(new MapJobDao(),
// new MapStepDao()));
//
// facade.setJobExecutionListeners(Collections
// .singletonList(new ThreadInterruptJobExecutionListener()));
//
// MapJobRegistry registry = new MapJobRegistry();
// facade.setJobLocator(registry);
//
// registry.register(new Job("foo"));
// final SimpleJobIdentifier identifier = new SimpleJobIdentifier("foo");
// final JobExecution execution = facade.createExecutionFrom(identifier);
//
// TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
// Runnable launcherRunnable = new Runnable() {
// public void run() {
// try {
// facade.start(execution);
// } catch (NoSuchJobException e) {
// fail("Unexpected NoSuchJobConfigurationException");
// }
// }
// };
//
// taskExecutor.execute(launcherRunnable);
//
// // give the thread a second to start up
// Thread.sleep(100);
// assertTrue(facade.isRunning());
// facade.stop(execution);
// Thread.sleep(100);
// assertFalse(facade.isRunning());
// }
public void testBlank(){}
/**
* Simple {@link JobExecutorFacade} that can be used to test thread
* interruption. Mimics the implementation of the

View File

@@ -16,11 +16,8 @@
package org.springframework.batch.execution.launch;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import junit.framework.TestCase;
@@ -28,21 +25,16 @@ import org.easymock.MockControl;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobLocator;
import org.springframework.batch.core.domain.NoSuchJobException;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.executor.JobExecutor;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.util.ReflectionUtils;
/**
* SimpleBatchContainer unit tests.
*
* SimpleJobExector should be removed, commented out the tests in case they were useful.
*
* @author Lucas Ward
* @author Dave Syer
*/
@@ -61,8 +53,10 @@ public class SimpleJobExecutorFacadeTests extends TestCase {
private volatile boolean running = false;
private SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("TestJob");
private JobInstanceProperties jobInstanceProperties = new JobInstanceProperties();
private JobExecution jobExecution = new JobExecution(new JobInstance(jobIdentifier, null));
private JobExecution jobExecution = new JobExecution(new JobInstance(new Long(0), jobInstanceProperties));
private List list = new ArrayList();
@@ -73,230 +67,238 @@ public class SimpleJobExecutorFacadeTests extends TestCase {
jobExecutorFacade.setJobExecutor(jobExecutor);
jobRepository = (JobRepository) jobRepositoryControl.getMock();
jobExecutorFacade.setJobRepository(jobRepository);
}
public void testCreateNewExecution() throws Exception {
JobInstance job = setUpFacadeForNormalStart();
jobExecution = jobExecutorFacade.createExecutionFrom(jobIdentifier);
assertEquals(job, jobExecution.getJobInstance());
jobRepositoryControl.verify();
}
// public void testCreateNewExecution() throws Exception {
//
// JobInstance job = setUpFacadeForNormalStart();
// jobExecution = jobExecutorFacade.createExecutionFrom(jobIdentifier);
// assertEquals(job, jobExecution.getJobInstance());
// jobRepositoryControl.verify();
//
// }
//
public void testNormalStart() throws Exception {
JobInstance job = setUpFacadeForNormalStart();
jobExecution = jobExecutorFacade.createExecutionFrom(jobIdentifier);
jobExecutorFacade.start(jobExecution);
assertEquals(job, jobExecution.getJobInstance());
assertEquals("bar", job.getName());
jobRepositoryControl.verify();
}
private JobInstance setUpFacadeForNormalStart() throws Exception {
jobIdentifier = new SimpleJobIdentifier("bar");
jobExecutor = new JobExecutor() {
public ExitStatus run(Job configuration, JobExecution execution) throws BatchCriticalException {
jobExecution = execution;
return ExitStatus.FINISHED;
}
};
jobExecutorFacade.setJobExecutor(jobExecutor);
JobInstance job = new JobInstance(jobIdentifier, null);
jobExecution = new JobExecution(job);
jobRepository.findOrCreateJob(jobConfiguration, jobIdentifier);
jobRepositoryControl.setReturnValue(jobExecution);
jobRepositoryControl.replay();
jobExecutorFacade.setJobLocator(new JobLocator() {
public Job getJob(String name) throws NoSuchJobException {
return jobConfiguration;
}
});
return job;
}
public void testIsRunning() throws Exception {
jobExecutorFacade.setJobExecutor(new JobExecutor() {
public ExitStatus run(Job configuration, JobExecution execution) throws BatchCriticalException {
while (running) {
try {
Thread.sleep(100L);
}
catch (InterruptedException e) {
throw new BatchCriticalException("Interrupted unexpectedly!");
}
}
return ExitStatus.FINISHED;
}
});
jobExecutorFacade.setJobLocator(new JobLocator() {
public Job getJob(String name) throws NoSuchJobException {
return jobConfiguration;
}
});
running = true;
new Thread(new Runnable() {
public void run() {
try {
jobExecutorFacade.start(jobExecution);
}
catch (NoSuchJobException e) {
throw new IllegalStateException("Shouldn't happen");
}
}
}).start();
// Give Thread time to start
Thread.sleep(100L);
assertTrue(jobExecutorFacade.isRunning());
running = false;
int count = 0;
while (jobExecutorFacade.isRunning() && count++ < 5) {
Thread.sleep(100L);
}
assertFalse(jobExecutorFacade.isRunning());
}
public void testInvalidInitialisation() throws Exception {
jobExecutorFacade = new SimpleJobExecutorFacade();
try {
jobExecutorFacade.afterPropertiesSet();
fail("Expected IllegalStateException");
}
catch (IllegalArgumentException ex) {
// expected
}
}
public void testStopWithNoJob() throws Exception {
SimpleJobIdentifier runtimeInformation = new SimpleJobIdentifier("TestJob");
JobExecution execution = new JobExecution(new JobInstance(runtimeInformation, new Long(0)));
try {
jobExecutorFacade.stop(execution);
fail("Expected NoSuchJobExecutionException");
}
catch (NoSuchJobExecutionException e) {
// expected
assertTrue("Wrong message in exception: " + e.getMessage(), e.getMessage().indexOf("TestJob") >= 0);
}
}
public void testStop() throws Exception {
SimpleJobIdentifier runtimeInformation = new SimpleJobIdentifier("TestJob");
JobInstance jobInstance = new JobInstance(runtimeInformation, new Long(0));
JobExecution execution = new JobExecution(jobInstance);
StepExecution stepExecution = execution.createStepExecution(new StepInstance(jobInstance, "step"));
List listeners = new ArrayList();
listeners.add(new JobExecutionListenerSupport() {
public void onStop(JobExecution execution) {
list.add("one");
}
});
jobExecutorFacade.setJobExecutionListeners(listeners);
registerExecution(runtimeInformation, execution);
jobExecutorFacade.stop(execution);
assertTrue(stepExecution.isTerminateOnly());
assertEquals(1, list.size());
}
public void testStatisticsWithNoContext() throws Exception {
assertNotNull(jobExecutorFacade.getStatistics());
}
public void testStatisticsWithContext() throws Exception {
SimpleJobIdentifier runtimeInformation = new SimpleJobIdentifier("TestJob");
JobInstance jobInstance = new JobInstance(runtimeInformation, new Long(0));
JobExecution execution = new JobExecution(jobInstance);
registerExecution(runtimeInformation, execution);
execution.createStepExecution(new StepInstance(jobInstance, "step"));
Properties statistics = jobExecutorFacade.getStatistics();
assertNotNull(statistics);
assertTrue(statistics.containsKey("job1.step1"));
}
public void testJobAlreadyExecutingLocally() throws Exception {
SimpleJobIdentifier runtimeInformation = new SimpleJobIdentifier("TestJob");
JobExecution execution = new JobExecution(new JobInstance(runtimeInformation, new Long(0)));
registerExecution(runtimeInformation, execution);
try {
jobExecutorFacade.createExecutionFrom(runtimeInformation);
fail("Expected JobExecutionAlreadyRunningException");
}
catch (JobExecutionAlreadyRunningException e) {
// expected
assertTrue("Message does not contain TestJob: " + e.getMessage(), e.getMessage().indexOf("TestJob") >= 0);
}
}
public void testListenersCalledLastOnStop() throws Exception {
List listeners = new ArrayList();
listeners.add(new JobExecutionListenerSupport() {
public void onStop(JobExecution execution) {
list.add("one");
}
});
listeners.add(new JobExecutionListenerSupport() {
public void onStop(JobExecution execution) {
list.add("two");
}
});
jobExecutorFacade.setJobExecutionListeners(listeners);
jobExecutorFacade.onStop(jobExecution);
assertEquals(2, list.size());
assertEquals("two", list.get(1));
}
public void testListenersCalledLastOnAfter() throws Exception {
List listeners = new ArrayList();
listeners.add(new JobExecutionListenerSupport() {
public void after(JobExecution execution) {
list.add("two");
}
});
listeners.add(new JobExecutionListenerSupport() {
public void after(JobExecution execution) {
list.add("one");
}
});
jobExecutorFacade.setJobExecutionListeners(listeners);
jobExecutorFacade.after(jobExecution);
assertEquals(2, list.size());
assertEquals("two", list.get(1));
}
public void testOrderedListenersCalledFirstOnBefore() throws Exception {
List listeners = new ArrayList();
listeners.add(new JobExecutionListenerSupport() {
public void before(JobExecution execution) {
list.add("one");
}
});
listeners.add(new JobExecutionListenerSupport() {
public void before(JobExecution execution) {
list.add("two");
}
});
jobExecutorFacade.setJobExecutionListeners(listeners);
jobExecutorFacade.before(jobExecution);
assertEquals(2, list.size());
assertEquals("two", list.get(1));
}
private void registerExecution(SimpleJobIdentifier runtimeInformation, JobExecution execution)
throws NoSuchFieldException, IllegalAccessException {
Field field = SimpleJobExecutorFacade.class.getDeclaredField("jobExecutionRegistry");
ReflectionUtils.makeAccessible(field);
Map map = (Map) field.get(jobExecutorFacade);
map.put(runtimeInformation, execution);
//
// JobInstance job = setUpFacadeForNormalStart();
// jobExecution = jobExecutorFacade.createExecutionFrom(jobIdentifier);
// jobExecutorFacade.start(jobExecution);
// assertEquals(job, jobExecution.getJobInstance());
// jobRepositoryControl.verify();
//
}
//
// private JobInstance setUpFacadeForNormalStart() throws Exception {
// jobIdentifier = new SimpleJobIdentifier("bar");
// jobExecutor = new JobExecutor() {
// public ExitStatus run(Job configuration, JobExecution execution) throws BatchCriticalException {
// jobExecution = execution;
// return ExitStatus.FINISHED;
// }
// };
// jobExecutorFacade.setJobExecutor(jobExecutor);
// JobInstance job = new JobInstance(new Long(0), jobInstanceProperties);
// jobExecution = new JobExecution(job);
// jobRepository.createJobExecution(jobConfiguration, null);
// jobRepositoryControl.setReturnValue(jobExecution);
// jobRepositoryControl.replay();
// jobExecutorFacade
// .setJobLocator(new JobLocator() {
// public Job getJob(String name)
// throws NoSuchJobException {
// return jobConfiguration;
// }
// });
// job.setJob(new Job());
// return job;
// }
//
//// public void testIsRunning() throws Exception {
//// jobExecutorFacade.setJobExecutor(new JobExecutor() {
//// public ExitStatus run(Job configuration,
//// JobExecution execution) throws BatchCriticalException {
//// while (running) {
//// try {
//// Thread.sleep(100L);
//// } catch (InterruptedException e) {
//// throw new BatchCriticalException(
//// "Interrupted unexpectedly!");
//// }
//// }
//// return ExitStatus.FINISHED;
//// }
//// });
//// jobExecutorFacade
//// .setJobLocator(new JobLocator() {
//// public Job getJob(String name)
//// throws NoSuchJobException {
//// return jobConfiguration;
//// }
//// });
////
//// running = true;
//// new Thread(new Runnable() {
//// public void run() {
//// try {
//// jobExecutorFacade.start(jobExecution);
//// } catch (NoSuchJobException e) {
//// throw new IllegalStateException("Shouldn't happen");
//// }
//// }
//// }).start();
//// // Give Thread time to start
//// Thread.sleep(100L);
//// assertTrue(jobExecutorFacade.isRunning());
//// running = false;
//// int count = 0;
//// while (jobExecutorFacade.isRunning() && count++ < 5) {
//// Thread.sleep(100L);
//// }
//// assertFalse(jobExecutorFacade.isRunning());
//// }
//
// public void testInvalidInitialisation() throws Exception {
//
// jobExecutorFacade = new SimpleJobExecutorFacade();
//
// try {
// jobExecutorFacade.afterPropertiesSet();
// fail("Expected IllegalStateException");
// }
// catch (IllegalArgumentException ex) {
// // expected
// }
// }
//
//// public void testStopWithNoJob() throws Exception {
//// SimpleJobIdentifier runtimeInformation = new SimpleJobIdentifier(
//// "TestJob");
//// JobExecution execution = new JobExecution(new JobInstance(
//// new Long(0), jobInstanceProperties));
//// try {
//// jobExecutorFacade.stop(execution);
//// fail("Expected NoSuchJobExecutionException");
//// } catch (NoSuchJobExecutionException e) {
//// // expected
//// assertTrue("Wrong message in exception: "+e.getMessage(), e.getMessage().indexOf("TestJob") >= 0);
//// }
//// }
//
// public void testStop() throws Exception {
// SimpleJobIdentifier runtimeInformation = new SimpleJobIdentifier(
// "TestJob");
// JobExecution execution = new JobExecution(new JobInstance(
// new Long(0), jobInstanceProperties));
//
// List listeners = new ArrayList();
// listeners.add(new JobExecutionListenerSupport() {
// public void onStop(JobExecution execution) {
// list.add("one");
// }
// });
// jobExecutorFacade.setJobExecutionListeners(listeners);
//
// registerExecution(runtimeInformation, execution);
//
// jobExecutorFacade.stop(execution);
//
// assertTrue(stepExecution.isTerminateOnly());
// assertEquals(1, list.size());
// }
//
// public void testStatisticsWithNoContext() throws Exception {
// assertNotNull(jobExecutorFacade.getStatistics());
// }
//
// public void testStatisticsWithContext() throws Exception {
// SimpleJobIdentifier runtimeInformation = new SimpleJobIdentifier(
// "TestJob");
// JobExecution execution = new JobExecution(new JobInstance(
// new Long(0), jobInstanceProperties));
// registerExecution(runtimeInformation, execution);
// execution.createStepExecution(new StepInstance(jobInstance, "step"));
// Properties statistics = jobExecutorFacade.getStatistics();
// assertNotNull(statistics);
// assertTrue(statistics.containsKey("job1.step1"));
// }
//
// public void testJobAlreadyExecutingLocally() throws Exception {
// SimpleJobIdentifier runtimeInformation = new SimpleJobIdentifier(
// "TestJob");
// JobExecution execution = new JobExecution(new JobInstance(
// new Long(0), jobInstanceProperties));
// registerExecution(runtimeInformation, execution);
// try {
// jobExecutorFacade.createExecutionFrom(runtimeInformation);
// fail("Expected JobExecutionAlreadyRunningException");
// }
// catch (JobExecutionAlreadyRunningException e) {
// // expected
// assertTrue("Message does not contain TestJob: " + e.getMessage(), e.getMessage().indexOf("TestJob") >= 0);
// }
// }
//
// public void testListenersCalledLastOnStop() throws Exception {
// List listeners = new ArrayList();
// listeners.add(new JobExecutionListenerSupport() {
// public void onStop(JobExecution execution) {
// list.add("one");
// }
// });
// listeners.add(new JobExecutionListenerSupport() {
// public void onStop(JobExecution execution) {
// list.add("two");
// }
// });
// jobExecutorFacade.setJobExecutionListeners(listeners);
// jobExecutorFacade.onStop(jobExecution);
// assertEquals(2, list.size());
// assertEquals("two", list.get(1));
// }
//
// public void testListenersCalledLastOnAfter() throws Exception {
// List listeners = new ArrayList();
// listeners.add(new JobExecutionListenerSupport() {
// public void after(JobExecution execution) {
// list.add("two");
// }
// });
// listeners.add(new JobExecutionListenerSupport() {
// public void after(JobExecution execution) {
// list.add("one");
// }
// });
// jobExecutorFacade.setJobExecutionListeners(listeners);
// jobExecutorFacade.after(jobExecution);
// assertEquals(2, list.size());
// assertEquals("two", list.get(1));
// }
//
// public void testOrderedListenersCalledFirstOnBefore() throws Exception {
// List listeners = new ArrayList();
// listeners.add(new JobExecutionListenerSupport() {
// public void before(JobExecution execution) {
// list.add("one");
// }
// });
// listeners.add(new JobExecutionListenerSupport() {
// public void before(JobExecution execution) {
// list.add("two");
// }
// });
// jobExecutorFacade.setJobExecutionListeners(listeners);
// jobExecutorFacade.before(jobExecution);
// assertEquals(2, list.size());
// assertEquals("two", list.get(1));
// }
//
// private void registerExecution(SimpleJobIdentifier runtimeInformation, JobExecution execution)
// throws NoSuchFieldException, IllegalAccessException {
// Field field = SimpleJobExecutorFacade.class.getDeclaredField("jobExecutionRegistry");
// ReflectionUtils.makeAccessible(field);
// Map map = (Map) field.get(jobExecutorFacade);
// map.put(runtimeInformation, execution);
// }
}

View File

@@ -18,107 +18,62 @@ package org.springframework.batch.execution.launch;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.NoSuchJobException;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
import org.springframework.batch.core.runtime.SimpleJobIdentifierFactory;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.executor.JobExecutor;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.repeat.ExitStatus;
/**
* @author Lucas Ward
*
*/
public class SimpleJobLauncherTests extends TestCase {
public void testStartWithNoConfiguration() throws Exception {
final SimpleJobLauncher launcher = new SimpleJobLauncher();
try {
launcher.afterPropertiesSet();
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
assertTrue(e.getMessage().indexOf("required") >= 0);
}
private SimpleJobLauncher jobLauncher;
private JobExecutor jobExecutor;
private JobRepository jobRepository;
private MockControl executorControl = MockControl.createControl(JobExecutor.class);
private MockControl repositoryControl = MockControl.createControl(JobRepository.class);
private Job job = new Job("foo");
private JobInstanceProperties jobInstanceProperties = new JobInstanceProperties();
protected void setUp() throws Exception {
super.setUp();
jobLauncher = new SimpleJobLauncher();
jobExecutor = (JobExecutor)executorControl.getMock();
jobRepository = (JobRepository)repositoryControl.getMock();
jobLauncher.setJobExecutor(jobExecutor);
jobLauncher.setJobRepository(jobRepository);
}
public void testInitializeWithNoConfiguration() throws Exception {
final SimpleJobLauncher launcher = new SimpleJobLauncher();
launcher.setJobExecutorFacade(new SimpleJobExecutorFacade() {
public JobExecution createExecutionFrom(JobIdentifier jobIdentifier) throws NoSuchJobException,
JobExecutionAlreadyRunningException {
throw new NoSuchJobException("No null job, stupid!");
}
});
try {
launcher.run(new SimpleJobIdentifier(null));
// should do nothing
fail("Expected NoSuchJobConfigurationException");
} catch (NoSuchJobException e) {
assertTrue("Message should mention null job name: "
+ e.getMessage(), e.getMessage().toLowerCase().indexOf(
"null") >= 0);
}
public void testRun() throws Exception{
JobExecution jobExecution = new JobExecution(null);
jobRepository.createJobExecution(job, jobInstanceProperties);
repositoryControl.setReturnValue(jobExecution);
jobExecutor.run(job, jobExecution);
executorControl.setDefaultReturnValue(ExitStatus.FINISHED);
repositoryControl.replay();
executorControl.replay();
jobLauncher.run(job, jobInstanceProperties);
assertEquals(ExitStatus.FINISHED, jobExecution.getExitStatus());
repositoryControl.verify();
executorControl.verify();
}
public void testRunTwiceNotFatal() throws Exception {
SimpleJobLauncher launcher = new SimpleJobLauncher();
launcher.setJobIdentifierFactory(new SimpleJobIdentifierFactory());
InterruptibleFacade jobExecutorFacade = new InterruptibleFacade();
launcher.setJobExecutorFacade(jobExecutorFacade);
launcher.run(new SimpleJobIdentifier("foo"));
assertFalse(launcher.isRunning());
launcher.run(new SimpleJobIdentifier("foo"));
// Both jobs finished running because they were not launched in a new
// Thread
assertFalse(launcher.isRunning());
}
public void testStopOnNotRunningLauncher() {
SimpleJobLauncher launcher = new SimpleJobLauncher();
assertFalse(launcher.isRunning());
// no exception should be thrown if stop is called on
// a launcher that is not running.
launcher.stop();
}
private class InterruptibleFacade implements JobExecutorFacade {
/*
* (non-Javadoc)
*
* @see org.springframework.batch.container.BatchContainer#run()
*/
public void run() {
try {
// 1 seconds should be long enough to allow the thread to be
// run and for interrupt to be called;
Thread.sleep(300);
// return ExitStatus.FAILED;
} catch (InterruptedException ex) {
// thread interrupted, allow to exit normally
// return ExitStatus.FAILED;
}
}
public void start(JobExecution execution)
throws NoSuchJobException {
run();
}
public JobExecution createExecutionFrom(JobIdentifier jobIdentifier)
throws NoSuchJobException {
return new JobExecution(new JobInstance(jobIdentifier, null));
}
public void stop(JobExecution execution) {
// not needed
}
public boolean isRunning() {
// not needed
return false;
}
}
}
}

View File

@@ -27,6 +27,7 @@ import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.Step;
import org.springframework.batch.core.executor.StepExecutor;
import org.springframework.batch.core.executor.StepExecutorFactory;
@@ -119,9 +120,7 @@ public class SimpleJobTests extends TestCase {
jobConfiguration.addStep(new SimpleStep(getTasklet("foo", "bar")));
jobConfiguration.addStep(new SimpleStep(getTasklet("spam")));
JobInstance job = repository.findOrCreateJob(jobConfiguration, runtimeInformation).getJobInstance();
assertEquals(job.getName(), "real.job");
JobInstance job = repository.createJobExecution(jobConfiguration, new JobInstanceProperties()).getJobInstance();
JobExecution jobExecutionContext = new JobExecution(job);
@@ -171,7 +170,7 @@ public class SimpleJobTests extends TestCase {
module.afterPropertiesSet();
jobConfiguration.addStep(step);
JobExecution jobExecution = repository.findOrCreateJob(jobConfiguration, runtimeInformation);
JobExecution jobExecution = repository.createJobExecution(jobConfiguration, new JobInstanceProperties());
jobExecutor.run(jobConfiguration, jobExecution);
assertEquals(BatchStatus.COMPLETED, jobExecution.getJobInstance().getStatus());
@@ -195,7 +194,7 @@ public class SimpleJobTests extends TestCase {
module.afterPropertiesSet();
jobConfiguration.addStep(step);
JobExecution jobExecution = repository.findOrCreateJob(jobConfiguration, runtimeInformation);
JobExecution jobExecution = repository.createJobExecution(jobConfiguration, new JobInstanceProperties());
JobInstance job = jobExecution.getJobInstance();
try {
jobExecutor.run(jobConfiguration, jobExecution);

View File

@@ -46,187 +46,187 @@ public class TaskExecutorJobLauncherTests extends TestCase {
protected void setUp() throws Exception {
super.setUp();
launcher.setJobIdentifierFactory(new SimpleJobIdentifierFactory());
}
public void testStopContainer() throws Exception {
// Important (otherwise start() does not return!)
launcher.setTaskExecutor(new SimpleAsyncTaskExecutor());
InterruptibleContainer container = new InterruptibleContainer();
launcher.setJobExecutorFacade(container);
JobExecution execution = launcher.run(new SimpleJobIdentifier("foo"));
// give the thread some time to start up...
Thread.sleep(100);
assertTrue(launcher.isRunning());
launcher.stop();
// ...and to shut down:
Thread.sleep(400);
assertFalse(launcher.isRunning());
assertEquals("COMPLETED_BY_TEST", execution.getExitStatus().getExitCode());
}
public void testStopContainerWhenJobNotRunning() throws Exception {
final List list = new ArrayList();
// Important (otherwise start() does not return!)
TimerTaskExecutor taskExecutor = new TimerTaskExecutor(new Timer() {
public void schedule(final TimerTask task, long delay) {
TimerTask wrapper = new TimerTask() {
public void run() {
list.add(task);
task.run();
}
};
super.schedule(wrapper, 400);
}
});
taskExecutor.afterPropertiesSet();
launcher.setTaskExecutor(taskExecutor);
InterruptibleContainer container = new InterruptibleContainer();
launcher.setJobExecutorFacade(container);
JobExecution execution = launcher.run(new SimpleJobIdentifier("foo"));
// give the thread some time to start up...
Thread.sleep(100);
// The launcher thinks it has started the job...
assertTrue(launcher.isRunning());
// ...but the task has not been started yet
assertEquals(0, list.size());
launcher.stop();
// ...and to shut down:
Thread.sleep(1000);
assertFalse(launcher.isRunning());
// The timer task has been started...
assertEquals(1, list.size());
// ...but the job is not executed
assertEquals(ExitStatus.UNKNOWN, execution.getExitStatus());
}
public void testRunTwice() throws Exception {
// Important (otherwise start() does not return!)
launcher.setTaskExecutor(new SimpleAsyncTaskExecutor());
InterruptibleContainer container = new InterruptibleContainer();
launcher.setJobExecutorFacade(container);
launcher.run(new SimpleJobIdentifier("foo"));
// give the thread some time to start up:
Thread.sleep(100);
assertTrue(launcher.isRunning());
try {
launcher.run(new SimpleJobIdentifier("foo"));
fail("Expected JobExecutionAlreadyRunningException");
} catch (JobExecutionAlreadyRunningException e) {
// expected
}
// give the thread some time to start up...
Thread.sleep(100);
launcher.stop();
// ...and to shut down:
Thread.sleep(400);
assertFalse(launcher.isRunning());
}
public void testStatisticsRetrieved() throws Exception {
MockControl control = MockControl
.createControl(JobExecutorFacadeWithStatistics.class);
JobExecutorFacadeWithStatistics batchContainer = (JobExecutorFacadeWithStatistics) control
.getMock();
launcher.setJobExecutorFacade(batchContainer);
Properties properties = PropertiesConverter.stringToProperties("a=b");
control.expectAndReturn(batchContainer.getStatistics(), properties);
control.replay();
assertEquals(properties, launcher.getStatistics());
control.verify();
}
public void testStatisticsNotRetrieved() throws Exception {
MockControl control = MockControl
.createControl(JobExecutorFacade.class);
JobExecutorFacade batchContainer = (JobExecutorFacade) control
.getMock();
launcher.setJobExecutorFacade(batchContainer);
Properties properties = new Properties();
control.replay();
assertEquals(properties, launcher.getStatistics());
control.verify();
}
//Under construction
// public void testStopContainer() throws Exception {
//
// // Important (otherwise start() does not return!)
// launcher.setTaskExecutor(new SimpleAsyncTaskExecutor());
//
// InterruptibleContainer container = new InterruptibleContainer();
//
// JobExecution execution = launcher.run(new SimpleJobIdentifier("foo"));
// // give the thread some time to start up...
// Thread.sleep(100);
// assertTrue(launcher.isRunning());
// launcher.stop();
// // ...and to shut down:
// Thread.sleep(400);
// assertFalse(launcher.isRunning());
// assertEquals("COMPLETED_BY_TEST", execution.getExitStatus().getExitCode());
// }
//
// public void testStopContainerWhenJobNotRunning() throws Exception {
//
// final List list = new ArrayList();
//
// // Important (otherwise start() does not return!)
// TimerTaskExecutor taskExecutor = new TimerTaskExecutor(new Timer() {
// public void schedule(final TimerTask task, long delay) {
// TimerTask wrapper = new TimerTask() {
// public void run() {
// list.add(task);
// task.run();
// }
// };
// super.schedule(wrapper, 400);
// }
// });
// taskExecutor.afterPropertiesSet();
// launcher.setTaskExecutor(taskExecutor);
//
// InterruptibleContainer container = new InterruptibleContainer();
// launcher.setJobExecutorFacade(container);
//
// JobExecution execution = launcher.run(new SimpleJobIdentifier("foo"));
// // give the thread some time to start up...
// Thread.sleep(100);
// // The launcher thinks it has started the job...
// assertTrue(launcher.isRunning());
// // ...but the task has not been started yet
// assertEquals(0, list.size());
// launcher.stop();
// // ...and to shut down:
// Thread.sleep(1000);
// assertFalse(launcher.isRunning());
// // The timer task has been started...
// assertEquals(1, list.size());
// // ...but the job is not executed
// assertEquals(ExitStatus.UNKNOWN, execution.getExitStatus());
// }
//
// public void testRunTwice() throws Exception {
//
// // Important (otherwise start() does not return!)
// launcher.setTaskExecutor(new SimpleAsyncTaskExecutor());
//
// InterruptibleContainer container = new InterruptibleContainer();
// launcher.setJobExecutorFacade(container);
//
// launcher.run(new SimpleJobIdentifier("foo"));
// // give the thread some time to start up:
// Thread.sleep(100);
// assertTrue(launcher.isRunning());
// try {
// launcher.run(new SimpleJobIdentifier("foo"));
// fail("Expected JobExecutionAlreadyRunningException");
// } catch (JobExecutionAlreadyRunningException e) {
// // expected
// }
// // give the thread some time to start up...
// Thread.sleep(100);
// launcher.stop();
// // ...and to shut down:
// Thread.sleep(400);
// assertFalse(launcher.isRunning());
// }
//
// public void testStatisticsRetrieved() throws Exception {
// MockControl control = MockControl
// .createControl(JobExecutorFacadeWithStatistics.class);
// JobExecutorFacadeWithStatistics batchContainer = (JobExecutorFacadeWithStatistics) control
// .getMock();
// launcher.setJobExecutorFacade(batchContainer);
//
// Properties properties = PropertiesConverter.stringToProperties("a=b");
// control.expectAndReturn(batchContainer.getStatistics(), properties);
//
// control.replay();
// assertEquals(properties, launcher.getStatistics());
// control.verify();
// }
//
// public void testStatisticsNotRetrieved() throws Exception {
// MockControl control = MockControl
// .createControl(JobExecutorFacade.class);
// JobExecutorFacade batchContainer = (JobExecutorFacade) control
// .getMock();
// launcher.setJobExecutorFacade(batchContainer);
//
// Properties properties = new Properties();
// control.replay();
// assertEquals(properties, launcher.getStatistics());
// control.verify();
// }
//
public void testPublishApplicationEvent() throws Exception {
final List list = new ArrayList();
launcher.setApplicationEventPublisher(new ApplicationEventPublisher() {
public void publishEvent(ApplicationEvent event) {
list.add(event);
}
});
MockControl control = MockControl
.createControl(JobExecutorFacade.class);
JobExecutorFacade facade = (JobExecutorFacade) control.getMock();
launcher.setJobExecutorFacade(facade);
SimpleJobIdentifier jobRuntimeInformation = new SimpleJobIdentifier(
"spam");
JobExecution execution = new JobExecution(new JobInstance(
jobRuntimeInformation, null));
control.expectAndReturn(facade
.createExecutionFrom(jobRuntimeInformation), execution);
facade.start(execution);
control.setThrowable(new NoSuchJobException("SPAM"));
control.replay();
launcher.run(jobRuntimeInformation);
assertEquals(1, list.size());
control.verify();
}
private class InterruptibleContainer implements JobExecutorFacade {
private volatile boolean running = true;
private void start() {
while (running) {
try {
// 1 seconds should be long enough to allow the thread to be
// started and
// for interrupt to be called;
Thread.sleep(300);
} catch (InterruptedException ex) {
// thread interrupted, allow to exit normally
}
}
}
public void start(JobExecution execution)
throws NoSuchJobException {
start();
execution.setExitStatus(new ExitStatus(false, "COMPLETED_BY_TEST"));
}
public JobExecution createExecutionFrom(JobIdentifier jobIdentifier)
throws NoSuchJobException {
return new JobExecution(new JobInstance(jobIdentifier, null));
}
public void stop(JobExecution execution) {
running = false;
}
public boolean isRunning() {
// not needed
return false;
}
}
private interface JobExecutorFacadeWithStatistics extends
JobExecutorFacade, StatisticsProvider {
// final List list = new ArrayList();
// launcher.setApplicationEventPublisher(new ApplicationEventPublisher() {
// public void publishEvent(ApplicationEvent event) {
// list.add(event);
// }
// });
//
// MockControl control = MockControl
// .createControl(JobExecutorFacade.class);
// JobExecutorFacade facade = (JobExecutorFacade) control.getMock();
// launcher.setJobExecutorFacade(facade);
// SimpleJobIdentifier jobRuntimeInformation = new SimpleJobIdentifier(
// "spam");
// JobExecution execution = new JobExecution(new JobInstance(
// jobRuntimeInformation, null));
// control.expectAndReturn(facade
// .createExecutionFrom(jobRuntimeInformation), execution);
// facade.start(execution);
// control.setThrowable(new NoSuchJobException("SPAM"));
//
// control.replay();
// launcher.run(jobRuntimeInformation);
// assertEquals(1, list.size());
// control.verify();
}
//
// private class InterruptibleContainer implements JobExecutorFacade {
// private volatile boolean running = true;
//
// private void start() {
// while (running) {
// try {
// // 1 seconds should be long enough to allow the thread to be
// // started and
// // for interrupt to be called;
// Thread.sleep(300);
// } catch (InterruptedException ex) {
// // thread interrupted, allow to exit normally
// }
// }
// }
//
// public void start(JobExecution execution)
// throws NoSuchJobException {
// start();
// execution.setExitStatus(new ExitStatus(false, "COMPLETED_BY_TEST"));
// }
//
// public JobExecution createExecutionFrom(JobIdentifier jobIdentifier)
// throws NoSuchJobException {
// return new JobExecution(new JobInstance(jobIdentifier, null));
// }
//
// public void stop(JobExecution execution) {
// running = false;
// }
//
// public boolean isRunning() {
// // not needed
// return false;
// }
// }
//
// private interface JobExecutorFacadeWithStatistics extends
// JobExecutorFacade, StatisticsProvider {
// }
}

View File

@@ -28,12 +28,13 @@ import org.easymock.MockControl;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.JobInstancePropertiesBuilder;
import org.springframework.batch.core.domain.Step;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.core.domain.StepSupport;
import org.springframework.batch.core.repository.BatchRestartException;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
import org.springframework.batch.execution.repository.dao.JobDao;
import org.springframework.batch.execution.repository.dao.StepDao;
import org.springframework.batch.restart.GenericRestartData;
@@ -52,7 +53,7 @@ public class SimpleJobRepositoryTests extends TestCase {
Job jobConfiguration;
SimpleJobIdentifier jobRuntimeInformation;
JobInstanceProperties jobInstanceProperties;
Step stepConfiguration1;
@@ -85,7 +86,8 @@ public class SimpleJobRepositoryTests extends TestCase {
jobRepository = new SimpleJobRepository(jobDao, stepDao);
jobRuntimeInformation = new SimpleJobIdentifier("RepositoryTest");
jobInstanceProperties = new JobInstancePropertiesBuilder().toJobParameters();
jobConfiguration = new Job();
jobConfiguration.setBeanName("RepositoryTest");
@@ -101,7 +103,7 @@ public class SimpleJobRepositoryTests extends TestCase {
jobConfiguration.setSteps(stepConfigurations);
databaseJob = new JobInstance(jobRuntimeInformation, new Long(1)) {
databaseJob = new JobInstance(new Long(1), jobInstanceProperties) {
public JobExecution createJobExecution() {
jobExecution = super.createJobExecution();
return jobExecution;
@@ -121,11 +123,11 @@ public class SimpleJobRepositoryTests extends TestCase {
*/
public void testCreateRestartableJob() throws Exception {
List jobs = new ArrayList();
List jobExecutions = new ArrayList();
jobDao.findJobs(jobRuntimeInformation);
jobDaoControl.setReturnValue(jobs);
jobDao.createJob(jobRuntimeInformation);
jobDao.findJobInstances(jobConfiguration.getName(), jobInstanceProperties);
jobDaoControl.setReturnValue(jobExecutions);
jobDao.createJobInstance(jobConfiguration.getName(), jobInstanceProperties);
jobDaoControl.setReturnValue(databaseJob);
stepDao.createStep(databaseJob, "TestStep1");
stepDaoControl.setReturnValue(databaseStep1);
@@ -142,7 +144,7 @@ public class SimpleJobRepositoryTests extends TestCase {
});
stepDaoControl.replay();
jobDaoControl.replay();
JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation).getJobInstance();
JobInstance job = jobRepository.createJobExecution(jobConfiguration, jobInstanceProperties).getJobInstance();
assertTrue(job.equals(databaseJob));
List jobSteps = job.getStepInstances();
Iterator it = jobSteps.iterator();
@@ -154,7 +156,7 @@ public class SimpleJobRepositoryTests extends TestCase {
public void testRestartedJob() throws Exception{
List jobs = new ArrayList();
jobDao.findJobs(jobRuntimeInformation);
jobDao.findJobInstances(jobConfiguration.getName(), jobInstanceProperties);
jobs.add(databaseJob);
jobDaoControl.setReturnValue(jobs);
stepDao.findStep(databaseJob, "TestStep1");
@@ -189,7 +191,7 @@ public class SimpleJobRepositoryTests extends TestCase {
});
jobDaoControl.setVoidCallable();
jobDaoControl.replay();
JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation).getJobInstance();
JobInstance job = jobRepository.createJobExecution(jobConfiguration, jobInstanceProperties).getJobInstance();
assertTrue(job.equals(databaseJob));
List jobSteps = job.getStepInstances();
Iterator it = jobSteps.iterator();
@@ -206,13 +208,13 @@ public class SimpleJobRepositoryTests extends TestCase {
List jobs = new ArrayList();
jobs.add(databaseJob);
jobs.add(new JobInstance(jobRuntimeInformation, new Long(127)));
jobDao.findJobs(jobRuntimeInformation);
jobs.add(new JobInstance(new Long(127), jobInstanceProperties));
jobDao.findJobInstances(jobConfiguration.getName(), jobInstanceProperties);
jobDaoControl.setReturnValue(jobs);
jobDaoControl.replay();
try{
jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation);
jobRepository.createJobExecution(jobConfiguration, jobInstanceProperties);
fail("Expected BatchRestartException");
}catch(BatchRestartException e){
//expected
@@ -226,7 +228,7 @@ public class SimpleJobRepositoryTests extends TestCase {
jobConfiguration.setStartLimit(1);
List jobs = new ArrayList();
jobDao.findJobs(jobRuntimeInformation);
jobDao.findJobInstances(jobConfiguration.getName(), jobInstanceProperties);
jobs.add(databaseJob);
jobDaoControl.setReturnValue(jobs);
stepDao.findStep(databaseJob, "TestStep1");
@@ -244,7 +246,7 @@ public class SimpleJobRepositoryTests extends TestCase {
jobDaoControl.replay();
try{
jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation);
jobRepository.createJobExecution(jobConfiguration, jobInstanceProperties);
fail();
}catch(BatchRestartException ex){
//expected
@@ -259,9 +261,9 @@ public class SimpleJobRepositoryTests extends TestCase {
List jobs = new ArrayList();
jobConfiguration.setRestartable(false);
jobDao.findJobs(jobRuntimeInformation);
jobDao.findJobInstances(jobConfiguration.getName(), jobInstanceProperties);
jobDaoControl.setReturnValue(jobs);
jobDao.createJob(jobRuntimeInformation);
jobDao.createJobInstance(jobConfiguration.getName(), jobInstanceProperties);
jobDaoControl.setReturnValue(databaseJob);
stepDao.createStep(databaseJob, "TestStep1");
stepDaoControl.setReturnValue(databaseStep1);
@@ -278,7 +280,7 @@ public class SimpleJobRepositoryTests extends TestCase {
});
stepDaoControl.replay();
jobDaoControl.replay();
JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation).getJobInstance();
JobInstance job = jobRepository.createJobExecution(jobConfiguration, jobInstanceProperties).getJobInstance();
assertTrue(job.equals(databaseJob));
List jobSteps = job.getStepInstances();
Iterator it = jobSteps.iterator();
@@ -291,8 +293,9 @@ public class SimpleJobRepositoryTests extends TestCase {
public void testUpdateJob() {
// failure scenario - no ID
JobInstance updateJob = new JobInstance(null);
JobInstance updateJob;
try {
updateJob = new JobInstance(null, jobInstanceProperties);
jobRepository.update(updateJob);
fail();
}
@@ -301,7 +304,7 @@ public class SimpleJobRepositoryTests extends TestCase {
}
// successful update
updateJob = new JobInstance(null, new Long(0L));
updateJob = new JobInstance(new Long(0L), jobInstanceProperties);
jobDao.update(updateJob);
jobDaoControl.replay();
jobRepository.update(updateJob);
@@ -323,7 +326,7 @@ public class SimpleJobRepositoryTests extends TestCase {
public void testSaveOrUpdateValidJobExecution() throws Exception {
JobExecution jobExecution = new JobExecution(new JobInstance(null, new Long(1)));
JobExecution jobExecution = new JobExecution(new JobInstance(new Long(1), jobInstanceProperties));
// new execution - call save on job dao
jobDao.save(jobExecution);
@@ -359,7 +362,7 @@ public class SimpleJobRepositoryTests extends TestCase {
}
public void testUpdateStepExecution(){
StepExecution stepExecution = new StepExecution(new StepInstance(new Long(10L)), null);
StepExecution stepExecution = new StepExecution(new StepInstance(new Long(10L)), null, new Long(1));
stepExecution.setId(new Long(11));
stepDao.update(stepExecution);
stepDaoControl.replay();
@@ -368,7 +371,7 @@ public class SimpleJobRepositoryTests extends TestCase {
}
public void testSaveStepExecution(){
StepExecution stepExecution = new StepExecution(new StepInstance(new Long(10L)), null);
StepExecution stepExecution = new StepExecution(new StepInstance(new Long(10L)), null, new Long(2));
//TODO: Not sure why, but calling save on the EasyMock stepDao causes a NullPointerException
// stepDao.save(stepExecution);
// stepDaoControl.replay();
@@ -378,7 +381,7 @@ public class SimpleJobRepositoryTests extends TestCase {
public void testSaveOrUpdateStepExecutionException() {
StepExecution stepExecution = new StepExecution(null, null);
StepExecution stepExecution = new StepExecution(null, null, null);
// failure scenario -- no step id set.
try {
@@ -398,9 +401,9 @@ public class SimpleJobRepositoryTests extends TestCase {
List jobs = new ArrayList();
jobDao.findJobs(jobRuntimeInformation);
jobDao.findJobInstances(jobConfiguration.getName(), jobInstanceProperties);
jobDaoControl.setReturnValue(jobs);
jobDao.createJob(jobRuntimeInformation);
jobDao.createJobInstance(jobConfiguration.getName(), jobInstanceProperties);
jobDaoControl.setReturnValue(databaseJob);
stepDao.createStep(databaseJob, "TestStep1");
databaseStep1.setRestartData(null);
@@ -419,7 +422,7 @@ public class SimpleJobRepositoryTests extends TestCase {
});
stepDaoControl.replay();
jobDaoControl.replay();
JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation).getJobInstance();
JobInstance job = jobRepository.createJobExecution(jobConfiguration, jobInstanceProperties).getJobInstance();
List jobSteps = job.getStepInstances();
Iterator it = jobSteps.iterator();
StepInstance step = (StepInstance) it.next();
@@ -432,7 +435,7 @@ public class SimpleJobRepositoryTests extends TestCase {
public void testFindStepsFixesInvalidRestartData() throws Exception{
List jobs = new ArrayList();
jobDao.findJobs(jobRuntimeInformation);
jobDao.findJobInstances(jobConfiguration.getName(), jobInstanceProperties);
jobs.add(databaseJob);
jobDaoControl.setReturnValue(jobs);
stepDao.findStep(databaseJob, "TestStep1");
@@ -462,7 +465,7 @@ public class SimpleJobRepositoryTests extends TestCase {
}
});
jobDaoControl.replay();
JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation).getJobInstance();
JobInstance job = jobRepository.createJobExecution(jobConfiguration, jobInstanceProperties).getJobInstance();
assertTrue(job.equals(databaseJob));
List jobSteps = job.getStepInstances();
Iterator it = jobSteps.iterator();

View File

@@ -16,15 +16,17 @@
package org.springframework.batch.execution.repository.dao;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.batch.core.domain.BatchStatus;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.JobInstancePropertiesBuilder;
import org.springframework.batch.core.repository.NoSuchBatchDomainObjectException;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
import org.springframework.batch.execution.runtime.DefaultJobIdentifier;
@@ -42,9 +44,11 @@ public abstract class AbstractJobDaoTests extends
protected JobDao jobDao;
protected ScheduledJobIdentifier jobRuntimeInformation;
protected JobInstance job;
protected JobInstanceProperties jobInstanceProperties = new JobInstancePropertiesBuilder().addString("job.key", "jobKey").toJobParameters();
protected JobInstance jobInstance;
protected Job job;
protected JobExecution jobExecution;
@@ -65,15 +69,17 @@ public abstract class AbstractJobDaoTests extends
}
protected void onSetUpInTransaction() throws Exception {
jobRuntimeInformation = new ScheduledJobIdentifier("Job1", "TestStream",
new SimpleDateFormat("yyyyMMdd").parse("20070505"));
// jobRuntimeInformation = new ScheduledJobIdentifier("Job1", "TestStream",
// new SimpleDateFormat("yyyyMMdd").parse("20070505"));
job = new Job("Job1");
// Create job.
job = jobDao.createJob(jobRuntimeInformation);
jobInstance = jobDao.createJobInstance(job.getName(), jobInstanceProperties);
// Create an execution
jobExecutionStartTime = new Date(System.currentTimeMillis());
jobExecution = new JobExecution(job);
jobExecution = new JobExecution(jobInstance);
jobExecution.setStartTime(jobExecutionStartTime);
jobExecution.setStatus(BatchStatus.STARTED);
jobDao.save(jobExecution);
@@ -82,7 +88,7 @@ public abstract class AbstractJobDaoTests extends
public void testVersionIsNotNullForJob() throws Exception {
int version = jdbcTemplate
.queryForInt("select version from BATCH_JOB_INSTANCE where ID="
+ job.getId());
+ jobInstance.getId());
assertEquals(0, version);
}
@@ -95,25 +101,23 @@ public abstract class AbstractJobDaoTests extends
public void testFindNonExistentJob() {
// No job should be found since it hasn't been created.
List jobs = jobDao.findJobs(new ScheduledJobIdentifier("Job2", "TestStream", new Date()));
List jobs = jobDao.findJobInstances("nonexistentJob", jobInstanceProperties);
assertTrue(jobs.size() == 0);
}
public void testFindJob() {
List jobs = jobDao.findJobs(jobRuntimeInformation);
List jobs = jobDao.findJobInstances(job.getName(), jobInstanceProperties);
assertTrue(jobs.size() == 1);
JobInstance tempJob = (JobInstance) jobs.get(0);
assertTrue(job.equals(tempJob));
assertEquals(jobRuntimeInformation, tempJob.getIdentifier());
assertTrue(jobInstance.equals(tempJob));
assertEquals(jobInstanceProperties, tempJob.getJobInstanceProperties());
}
public void testFindJobWithNullRuntime() {
ScheduledJobIdentifier runtimeInformation = null;
try {
jobDao.findJobs(runtimeInformation);
jobDao.findJobInstances(null, null);
fail();
} catch (IllegalArgumentException ex) {
// expected
@@ -126,44 +130,43 @@ public abstract class AbstractJobDaoTests extends
* get no result, not the existing one.
*/
public void testCreateJobWithExistingName() {
ScheduledJobIdentifier scheduledIdentifier = new ScheduledJobIdentifier(
"ScheduledJob", "key", new Date());
jobDao.createJob(scheduledIdentifier);
jobDao.createJobInstance("ScheduledJob", jobInstanceProperties);
// Modifying the key should bring back a completely different
// JobInstance
ScheduledJobIdentifier newIdentifier = new ScheduledJobIdentifier(
"ScheduledJob", "different key", new Date());
JobInstanceProperties tempProps = new JobInstancePropertiesBuilder().addString("job.key", "testKey1")
.toJobParameters();
List jobs;
jobs = jobDao.findJobs(scheduledIdentifier);
jobs = jobDao.findJobInstances("ScheduledJob", jobInstanceProperties);
assertEquals(1, jobs.size());
JobInstance job = (JobInstance) jobs.get(0);
assertEquals(scheduledIdentifier, job.getIdentifier());
JobInstance jobInstance = (JobInstance) jobs.get(0);
assertEquals(jobInstanceProperties, jobInstance.getJobInstanceProperties());
jobs = jobDao.findJobs(newIdentifier);
jobs = jobDao.findJobInstances("ScheduledJob", tempProps);
assertEquals(0, jobs.size());
}
public void testUpdateJob() {
// Update the returned job with a new status
job.setStatus(BatchStatus.COMPLETED);
jobDao.update(job);
jobInstance.setStatus(BatchStatus.COMPLETED);
jobDao.update(jobInstance);
// The job just updated should be found, with the saved status.
List jobs = jobDao.findJobs(jobRuntimeInformation);
List jobs = jobDao.findJobInstances(job.getName(), jobInstanceProperties);
assertTrue(jobs.size() == 1);
JobInstance tempJob = (JobInstance) jobs.get(0);
assertTrue(job.equals(tempJob));
assertTrue(jobInstance.equals(tempJob));
assertEquals(tempJob.getStatus(), BatchStatus.COMPLETED);
}
public void testUpdateJobWithNullId() {
JobInstance testJob = new JobInstance(null);
try {
JobInstance testJob = new JobInstance(null, null);
jobDao.update(testJob);
fail();
} catch (IllegalArgumentException ex) {
@@ -188,7 +191,7 @@ public abstract class AbstractJobDaoTests extends
jobExecution.setEndTime(new Date(System.currentTimeMillis()));
jobDao.update(jobExecution);
List executions = jobDao.findJobExecutions(job);
List executions = jobDao.findJobExecutions(jobInstance);
assertEquals(executions.size(), 1);
validateJobExecution(jobExecution, (JobExecution) executions.get(0));
@@ -196,7 +199,7 @@ public abstract class AbstractJobDaoTests extends
public void testSaveJobExecution(){
List executions = jobDao.findJobExecutions(job);
List executions = jobDao.findJobExecutions(jobInstance);
assertEquals(executions.size(), 1);
validateJobExecution(jobExecution, (JobExecution) executions.get(0));
}
@@ -204,7 +207,7 @@ public abstract class AbstractJobDaoTests extends
public void testUpdateInvalidJobExecution() {
// id is invalid
JobExecution execution = new JobExecution(job, new Long(29432));
JobExecution execution = new JobExecution(jobInstance, new Long(29432));
try {
jobDao.update(execution);
fail("Expected NoSuchBatchDomainObjectException");
@@ -215,7 +218,7 @@ public abstract class AbstractJobDaoTests extends
public void testUpdateNullIdJobExection() {
JobExecution execution = new JobExecution(job);
JobExecution execution = new JobExecution(jobInstance);
try {
jobDao.update(execution);
fail();
@@ -227,19 +230,18 @@ public abstract class AbstractJobDaoTests extends
public void testIncrementExecutionCount() {
// 1 JobExection already added in setup
assertEquals(jobDao.getJobExecutionCount(job.getId()), 1);
assertEquals(jobDao.getJobExecutionCount(jobInstance.getId()), 1);
// Save new JobExecution for same job
JobExecution testJobExecution = new JobExecution(job);
JobExecution testJobExecution = new JobExecution(jobInstance);
jobDao.save(testJobExecution);
// JobExecutionCount should be incremented by 1
assertEquals(jobDao.getJobExecutionCount(job.getId()), 2);
assertEquals(jobDao.getJobExecutionCount(jobInstance.getId()), 2);
}
public void testZeroExecutionCount() {
JobInstance testJob = jobDao.createJob(new ScheduledJobIdentifier(
"TestJob", "key", new Date()));
JobInstance testJob = jobDao.createJobInstance("test", new JobInstanceProperties());
// no jobExecutions saved for new job, count should be 0
assertEquals(jobDao.getJobExecutionCount(testJob.getId()), 0);
}
@@ -248,87 +250,31 @@ public abstract class AbstractJobDaoTests extends
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("Job1");
// Create job.
job = jobDao.createJob(jobIdentifier);
jobInstance = jobDao.createJobInstance("test", jobInstanceProperties);
List jobs = jdbcTemplate.queryForList(
"SELECT * FROM BATCH_JOB_INSTANCE where ID=?", new Object[] { job
"SELECT * FROM BATCH_JOB_INSTANCE where ID=?", new Object[] { jobInstance
.getId() });
assertEquals(1, jobs.size());
assertEquals(job.getName(), ((Map) jobs.get(0)).get("JOB_NAME"));
assertEquals("test", ((Map) jobs.get(0)).get("JOB_NAME"));
}
public void testJobWithDefaultJobIdentifier() throws Exception {
DefaultJobIdentifier jobIdentifier = new DefaultJobIdentifier("Job1", "testKey");
// Create job.
job = jobDao.createJob(jobIdentifier);
List jobs = jobDao.findJobs(jobIdentifier);
jobInstance = jobDao.createJobInstance("testDefault", jobInstanceProperties);
List jobs = jobDao.findJobInstances("testDefault", jobInstanceProperties);
assertEquals(1, jobs.size());
assertEquals(job.getName(), ((JobInstance) jobs.get(0)).getName());
assertEquals(jobIdentifier.getJobKey(), ((JobInstance) jobs.get(0)).
getIdentifier().getJobInstanceProperties().getString(DefaultJobIdentifier.JOB_KEY));
}
public void testJobWithScheduledJobIdentifier() throws Exception {
Date date = new Date();
ScheduledJobIdentifier jobIdentifier = new ScheduledJobIdentifier("Job1", "testKey", date);
// Create job.
job = jobDao.createJob(jobIdentifier);
List jobs = jobDao.findJobs(jobIdentifier);
assertEquals(1, jobs.size());
assertEquals(job.getName(), ((JobInstance) jobs.get(0)).getName());
assertEquals(jobIdentifier.getJobKey(), ((JobInstance) jobs.get(0)).
getIdentifier().getJobInstanceProperties().getString(DefaultJobIdentifier.JOB_KEY));
}
public void testJobWithScheduledJobIdentifierAndDifferentTime() throws Exception {
Date date = new Date();
ScheduledJobIdentifier jobIdentifier = new ScheduledJobIdentifier("Job1", "testKey", date);
// Create job.
job = jobDao.createJob(jobIdentifier);
Date later = new Date(date.getTime()+3600000);
ScheduledJobIdentifier laterIdentifier = new ScheduledJobIdentifier("Job1", "testKey", later);
List jobs = jobDao.findJobs(laterIdentifier);
// Different timestamp is different identifier...
assertEquals(0, jobs.size());
}
public void testJobWithScheduledJobIdentifierAndDifferentDateImplementation() throws Exception {
Date date = new Date();
ScheduledJobIdentifier jobIdentifier = new ScheduledJobIdentifier("Job1", "testKey", date);
// Create job.
job = jobDao.createJob(jobIdentifier);
Timestamp later = new Timestamp(date.getTime());
ScheduledJobIdentifier laterIdentifier = new ScheduledJobIdentifier("Job1", "testKey", later);
List jobs = jobDao.findJobs(laterIdentifier);
// Different timestamp is different identifier...
assertEquals(1, jobs.size());
assertEquals(job.getName(), ((JobInstance) jobs.get(0)).getName());
assertEquals(jobIdentifier.getJobKey(), ((JobInstance) jobs.get(0)).
getIdentifier().getJobInstanceProperties().getString(DefaultJobIdentifier.JOB_KEY));
assertEquals(jobInstanceProperties.getString("job.key"), ((JobInstance) jobs.get(0))
.getJobInstanceProperties().getString("job.key"));
}
public void testFindJobExecutions(){
List results = jobDao.findJobExecutions(job);
List results = jobDao.findJobExecutions(jobInstance);
assertEquals(results.size(), 1);
validateJobExecution(jobExecution, (JobExecution)results.get(0));
}

View File

@@ -21,9 +21,11 @@ import java.util.List;
import java.util.Properties;
import org.springframework.batch.core.domain.BatchStatus;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.core.executor.ExitCodeExceptionClassifier;
@@ -49,7 +51,7 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
protected StepDao stepDao;
protected JobInstance job;
protected JobInstance jobInstance;
protected StepInstance step1;
@@ -58,6 +60,8 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
protected StepExecution stepExecution;
protected JobExecution jobExecution;
protected JobInstanceProperties jobInstanceProperties = new JobInstanceProperties();
public void setJobDao(JobDao jobDao) {
this.jobDao = jobDao;
@@ -80,13 +84,13 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
* @see org.springframework.test.AbstractTransactionalSpringContextTests#onSetUpInTransaction()
*/
protected void onSetUpInTransaction() throws Exception {
JobIdentifier jobIdentifier = new ScheduledJobIdentifier("TestJob", "TestStream", new Date());
job = jobDao.createJob(jobIdentifier);
step1 = stepDao.createStep(job, "TestStep1");
step2 = stepDao.createStep(job, "TestStep2");
Job job = new Job("TestJob");
jobInstance = jobDao.createJobInstance(job.getName(), jobInstanceProperties);
step1 = stepDao.createStep(jobInstance, "TestStep1");
step2 = stepDao.createStep(jobInstance, "TestStep2");
jobExecution = new JobExecution(step2.getJobInstance());
stepExecution = new StepExecution(step1, jobExecution);
stepExecution = new StepExecution(step1, jobExecution, null);
stepExecution.setStatus(BatchStatus.STARTED);
stepExecution.setStartTime(new Date(System.currentTimeMillis()));
stepDao.save(stepExecution);
@@ -104,19 +108,19 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
public void testFindStepNull(){
StepInstance step = stepDao.findStep(job, "UnSavedStep");
StepInstance step = stepDao.findStep(jobInstance, "UnSavedStep");
assertNull(step);
}
public void testFindStep(){
StepInstance tempStep = stepDao.findStep(job, "TestStep1");
StepInstance tempStep = stepDao.findStep(jobInstance, "TestStep1");
assertEquals(tempStep, step1);
}
public void testFindSteps(){
List steps = stepDao.findSteps(job);
List steps = stepDao.findSteps(jobInstance);
assertEquals(steps.size(), 2);
assertTrue(steps.contains(step1));
assertTrue(steps.contains(step2));
@@ -125,14 +129,14 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
public void testFindStepsNotSaved(){
//no steps are saved for given id, empty list should be returned
List steps = stepDao.findSteps(new JobInstance(null, new Long(38922)));
List steps = stepDao.findSteps(new JobInstance(new Long(38922), jobInstanceProperties));
assertEquals(steps.size(), 0);
}
public void testCreateStep(){
StepInstance step3 = stepDao.createStep(job, "TestStep3");
StepInstance tempStep = stepDao.findStep(job, "TestStep3");
StepInstance step3 = stepDao.createStep(jobInstance, "TestStep3");
StepInstance tempStep = stepDao.findStep(jobInstance, "TestStep3");
assertEquals(step3, tempStep);
}
@@ -140,7 +144,7 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
step1.setStatus(BatchStatus.COMPLETED);
stepDao.update(step1);
StepInstance tempStep = stepDao.findStep(job, step1.getName());
StepInstance tempStep = stepDao.findStep(jobInstance, step1.getName());
assertEquals(tempStep, step1);
}
@@ -152,7 +156,7 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
RestartData restartData = new GenericRestartData(data);
step1.setRestartData(restartData);
stepDao.update(step1);
StepInstance tempStep = stepDao.findStep(job, step1.getName());
StepInstance tempStep = stepDao.findStep(jobInstance, step1.getName());
assertEquals(tempStep, step1);
assertEquals(tempStep.getRestartData().getProperties().toString(),
restartData.getProperties().toString());
@@ -160,7 +164,7 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
public void testSaveStepExecution(){
StepExecution execution = new StepExecution(step2, jobExecution);
StepExecution execution = new StepExecution(step2, jobExecution, null);
execution.setStatus(BatchStatus.STARTED);
execution.setStartTime(new Date(System.currentTimeMillis()));
Properties statistics = new Properties();
@@ -194,7 +198,7 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
}
public void testUpdateStepExecutionWithNullId(){
StepExecution stepExecution = new StepExecution(null, null);
StepExecution stepExecution = new StepExecution(null, null, null);
try{
stepDao.update(stepExecution);
fail("Expected IllegalArgumentException");
@@ -212,7 +216,7 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
public void testIncrementStepExecutionCount(){
assertEquals(1, stepDao.getStepExecutionCount(step1.getId()));
StepExecution execution = new StepExecution(step1, new JobExecution(step1.getJobInstance(), new Long(123)));
StepExecution execution = new StepExecution(step1, new JobExecution(step1.getJobInstance(), new Long(123)), null);
stepDao.save(execution);
assertEquals(2, stepDao.getStepExecutionCount(step1.getId()));
}

View File

@@ -21,6 +21,7 @@ import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -67,7 +68,7 @@ public class JdbcJobDaoQueryTests extends TestCase {
return 1;
}
});
sqlDao.save(new JobInstance(new SimpleJobIdentifier("foo"), new Long(11)).createJobExecution());
sqlDao.save(new JobInstance(new Long(11), new JobInstanceProperties()).createJobExecution());
assertEquals(1, list.size());
String query = (String) list.get(0);
assertTrue("Query did not contain FOO_:" + query, query.indexOf("FOO_") >= 0);

View File

@@ -3,7 +3,6 @@ package org.springframework.batch.execution.repository.dao;
import java.util.List;
import java.util.Map;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
import org.springframework.batch.repeat.ExitStatus;
public class JdbcJobDaoTests extends AbstractJobDaoTests {
@@ -17,21 +16,16 @@ public class JdbcJobDaoTests extends AbstractJobDaoTests {
public void testUpdateJobExecutionWithLongExitCode() {
assertTrue(LONG_STRING.length() > 250);
jobExecution.setExitStatus(ExitStatus.FINISHED.addExitDescription(LONG_STRING));
jobExecution.setExitStatus(ExitStatus.FINISHED
.addExitDescription(LONG_STRING));
jobDao.update(jobExecution);
List executions = jdbcTemplate.queryForList("SELECT * FROM BATCH_JOB_EXECUTION where JOB_ID=?",
new Object[] { job.getId() });
List executions = jdbcTemplate.queryForList(
"SELECT * FROM BATCH_JOB_EXECUTION where JOB_ID=?",
new Object[] { jobInstance.getId() });
assertEquals(1, executions.size());
assertEquals(LONG_STRING.substring(0, 250), ((Map) executions.get(0)).get("EXIT_MESSAGE"));
}
public void testJobInstanceParametersNotNullOrEmptyWithSimpleJobIdentifier() {
job = jobDao.createJob(new SimpleJobIdentifier("foo"));
Map map = jdbcTemplate.queryForMap("SELECT * FROM BATCH_JOB_INSTANCE where ID=?",
new Object[] { job.getId() });
String key = (String) map.get("JOB_KEY");
assertTrue("Key should be non-zero length (otherwise Oracle will treat as null)", key.length()>0);
assertEquals(LONG_STRING.substring(0, 250), ((Map) executions.get(0))
.get("EXIT_MESSAGE"));
}
}

View File

@@ -8,6 +8,7 @@ import org.easymock.MockControl;
import org.springframework.batch.core.domain.BatchStatus;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.dao.DataAccessException;
@@ -30,9 +31,9 @@ public class JdbcStepDaoPrefixTests extends TestCase {
MockJdbcTemplate jdbcTemplate = new MockJdbcTemplate();
JobInstance job = new JobInstance(null, new Long(1));
JobInstance job = new JobInstance(new Long(1), new JobInstanceProperties());
StepInstance step = new StepInstance(job, "foo", new Long(1));
StepExecution stepExecution = new StepExecution(step, new JobExecution(job));
StepExecution stepExecution = new StepExecution(step, new JobExecution(job), null);
MockControl stepExecutionIncrementerControl = MockControl.createControl(DataFieldMaxValueIncrementer.class);
DataFieldMaxValueIncrementer stepExecutionIncrementer;
@@ -96,7 +97,7 @@ public class JdbcStepDaoPrefixTests extends TestCase {
public void testModifiedFindSteps(){
stepDao.setTablePrefix("FOO_");
stepDao.findSteps(new JobInstance(null, new Long(1)));
stepDao.findSteps(new JobInstance(new Long(1), new JobInstanceProperties()));
assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP") != -1);
}
@@ -127,7 +128,7 @@ public class JdbcStepDaoPrefixTests extends TestCase {
}
public void testDefaultFindSteps(){
stepDao.findSteps(new JobInstance(null, new Long(1)));
stepDao.findSteps(new JobInstance(new Long(1), new JobInstanceProperties()));
assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP") != -1);
}

View File

@@ -22,50 +22,53 @@ import junit.framework.TestCase;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
public class MapJobDaoTests extends TestCase {
MapJobDao dao = new MapJobDao();
JobInstanceProperties jobInstanceProperties = new JobInstanceProperties();
protected void setUp() throws Exception {
MapJobDao.clear();
}
public void testCreateAndRetrieveSingle() throws Exception {
JobInstance job = dao.createJob(new SimpleJobIdentifier("foo"));
List result = dao.findJobs(new SimpleJobIdentifier("foo"));
JobInstance job = dao.createJobInstance("foo", jobInstanceProperties);
List result = dao.findJobInstances("foo", jobInstanceProperties);
assertTrue(result.contains(job));
}
public void testCreateAndRetrieveMultiple() throws Exception {
JobInstance job = dao.createJob(new SimpleJobIdentifier("foo"));
job = dao.createJob(new SimpleJobIdentifier("bar"));
List result = dao.findJobs(new SimpleJobIdentifier("bar"));
JobInstance job = dao.createJobInstance("foo", jobInstanceProperties);
job = dao.createJobInstance("bar", jobInstanceProperties);
List result = dao.findJobInstances("bar", jobInstanceProperties);
assertEquals(1, result.size());
assertTrue(result.contains(job));
}
public void testNoExecutionsForNewJob() throws Exception {
JobInstance job = dao.createJob(new SimpleJobIdentifier("foo"));
JobInstance job = dao.createJobInstance("foo", jobInstanceProperties);
assertEquals(0, dao.getJobExecutionCount(job.getId()));
}
public void testSaveExecutionUpdatesId() throws Exception {
JobInstance job = dao.createJob(new SimpleJobIdentifier("foo"));
JobInstance job = dao.createJobInstance("foo", jobInstanceProperties);
JobExecution execution = new JobExecution(job);
assertNull(execution.getId());
dao.save(execution);
assertNotNull(execution.getId());
}
public void testCorrectExecutionCountForExistingJob() throws Exception {
JobInstance job = dao.createJob(new SimpleJobIdentifier("foo"));
JobInstance job = dao.createJobInstance("foo", jobInstanceProperties);
dao.save(new JobExecution(job));
assertEquals(1, dao.getJobExecutionCount(job.getId()));
}
public void testMultipleExecutionsPerExisting() throws Exception {
JobInstance job = dao.createJob(new SimpleJobIdentifier("foo"));
JobInstance job = dao.createJobInstance("foo", jobInstanceProperties);
dao.save(new JobExecution(job));
Thread.sleep(50L); // Hack, hack, hackety, hack - job executions are not unique if created too close together!
dao.save(new JobExecution(job));

View File

@@ -23,6 +23,7 @@ import junit.framework.TestCase;
import org.springframework.batch.core.domain.BatchStatus;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.execution.repository.dao.MapStepDao;
@@ -40,7 +41,7 @@ public class MapStepDaoTests extends TestCase {
protected void setUp() throws Exception {
MapStepDao.clear();
job = new JobInstance(null, new Long(jobId++));
job = new JobInstance(new Long(jobId++), new JobInstanceProperties());
step = dao.createStep(job, "foo");
}
@@ -74,12 +75,12 @@ public class MapStepDaoTests extends TestCase {
}
public void testFindWithEmptyResults() throws Exception {
List result = dao.findSteps(new JobInstance(null, new Long(22)));
List result = dao.findSteps(new JobInstance(new Long(22), new JobInstanceProperties()));
assertEquals(0, result.size());
}
public void testFindSingleWithEmptyResults() throws Exception {
StepInstance result = dao.findStep(new JobInstance(null, new Long(22)), "bar");
StepInstance result = dao.findStep(new JobInstance(new Long(22), new JobInstanceProperties()), "bar");
assertEquals(null, result);
}
@@ -88,20 +89,20 @@ public class MapStepDaoTests extends TestCase {
}
public void testSaveExecutionUpdatesId() throws Exception {
StepExecution execution = new StepExecution(step, null);
StepExecution execution = new StepExecution(step, null, null);
assertNull(execution.getId());
dao.save(execution);
assertNotNull(execution.getId());
}
public void testCorrectExecutionCountForExisting() throws Exception {
dao.save(new StepExecution(step, null));
dao.save(new StepExecution(step, null, null));
assertEquals(1, dao.getStepExecutionCount(step.getId()));
}
public void testOnlyOneExecutionPerStep() throws Exception {
dao.save(new StepExecution(step, null));
dao.save(new StepExecution(step, null));
dao.save(new StepExecution(step, null, null));
dao.save(new StepExecution(step, null, null));
assertEquals(2, dao.getStepExecutionCount(step.getId()));
}

View File

@@ -22,9 +22,11 @@ import java.text.SimpleDateFormat;
import junit.framework.TestCase;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.execution.resource.BatchResourceFactoryBean;
@@ -55,7 +57,7 @@ public class BatchResourceFactoryBeanTests extends TestCase {
private String path = "data" + pathsep;
private ScheduledJobIdentifier identifier;
private JobInstance jobInstance;
/**
* mock step context
@@ -64,15 +66,13 @@ public class BatchResourceFactoryBeanTests extends TestCase {
protected void setUp() throws Exception {
resourceFactory.setRootDirectory(rootDir);
identifier = new ScheduledJobIdentifier("testJob", "testStream", new SimpleDateFormat("yyyyMMdd")
.parse("20070730"));
SimpleStepContext context = new SimpleStepContext();
JobInstance job = new JobInstance(identifier);
JobExecution jobExecution = new JobExecution(job);
StepInstance step = new StepInstance(job, "bar");
StepExecution stepExecution = new StepExecution(step, jobExecution);
jobInstance = new JobInstance(new Long(0), new JobInstanceProperties());
jobInstance.setJob(new Job("testJob"));
JobExecution jobExecution = new JobExecution(jobInstance);
StepInstance step = new StepInstance(jobInstance, "bar");
StepExecution stepExecution = new StepExecution(step, jobExecution, null);
context.setStepExecution(stepExecution);
resourceFactory.setStepContext(context);
@@ -93,19 +93,7 @@ public class BatchResourceFactoryBeanTests extends TestCase {
* regular use with valid context and pattern provided
*/
public void testCreateFileName() throws Exception {
doTestPathName("testJob-testStream-20070730-bar.txt", path);
}
/**
* regular use with valid context and pattern provided
*/
public void testSetLabelGenerator() throws Exception {
resourceFactory.setJobIdentifierLabelGenerator(new JobIdentifierLabelGenerator() {
public String getLabel(JobIdentifier jobIdentifier) {
return "foo";
}
});
doTestPathName("foo-bar.txt", path);
doTestPathName("bar.txt", path);
}
public void testObjectType() throws Exception {
@@ -125,8 +113,8 @@ public class BatchResourceFactoryBeanTests extends TestCase {
public void testNonStandardFilePattern() throws Exception {
resourceFactory.setFilePattern("/%BATCH_ROOT%/data/%JOB_NAME%/"
+ "%STEP_NAME%+%JOB_IDENTIFIER%");
doTestPathName("bar+testJob-testStream-20070730", path);
+ "%STEP_NAME%-job");
doTestPathName("bar-job", path);
}
public void testResoureLoaderAware() throws Exception {
@@ -146,14 +134,14 @@ public class BatchResourceFactoryBeanTests extends TestCase {
String rootDir = getRootDir();
rootDir = StringUtils.replace(rootDir, File.separator, "/") + "/";
resourceFactory.setRootDirectory(rootDir);
doTestPathName("testJob-testStream-20070730-bar.txt", path);
doTestPathName("bar.txt", path);
}
public void testRootDirectoryEndsWithBackSlash() throws Exception {
String rootDir = getRootDir();
rootDir = "/"+StringUtils.replace(rootDir, File.separator, "\\") + "\\";
resourceFactory.setRootDirectory(rootDir);
doTestPathName("testJob-testStream-20070730-bar.txt", path);
doTestPathName("bar.txt", path);
}
private void doTestPathName(String filename, String path) throws Exception, IOException {
@@ -161,7 +149,7 @@ public class BatchResourceFactoryBeanTests extends TestCase {
String returnedPath = resource.getFile().getAbsolutePath();
String absolutePath = new File("/" + rootDir + pathsep + path + identifier.getName() + pathsep + filename).getAbsolutePath();
String absolutePath = new File("/" + rootDir + pathsep + path + jobInstance.getJobName() + pathsep + filename).getAbsolutePath();
// System.err.println(absolutePath);
// System.err.println(returnedPath);

View File

@@ -26,7 +26,7 @@ public class DefaultJobIdentifierTests extends TestCase {
private DefaultJobIdentifier instance = new DefaultJobIdentifier(null);
/**
* Test method for {@link org.springframework.batch.core.domain.JobInstance#getName()}.
* Test method for {@link org.springframework.batch.core.domain.JobInstance#getJobName()}.
*/
public void testGetName() {
DefaultJobIdentifier identifier = new DefaultJobIdentifier("foo");

View File

@@ -28,7 +28,7 @@ public class ScheduledJobIdentifierTests extends TestCase {
private ScheduledJobIdentifier instance = new ScheduledJobIdentifier(null, "");
/**
* Test method for {@link org.springframework.batch.core.domain.JobInstance#getName()}.
* Test method for {@link org.springframework.batch.core.domain.JobInstance#getJobName()}.
*/
public void testDefaultConstructor() {
assertEquals(null, instance.getName());
@@ -37,7 +37,7 @@ public class ScheduledJobIdentifierTests extends TestCase {
}
/**
* Test method for {@link org.springframework.batch.core.domain.JobInstance#getName()}.
* Test method for {@link org.springframework.batch.core.domain.JobInstance#getJobName()}.
*/
public void testGetName() {

View File

@@ -49,7 +49,7 @@ public class SimpleStepContextTests extends TestCase {
*/
public void testGetJobIdentifier() {
assertNull(context.getStepExecution());
context.setStepExecution(new StepExecution(null, null));
context.setStepExecution(new StepExecution(null, null, null));
assertNotNull(context.getStepExecution());
}

View File

@@ -22,8 +22,10 @@ import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.StepContribution;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
@@ -65,6 +67,8 @@ public class DefaultStepExecutorTests extends TestCase {
private StepSupport stepConfiguration;
private RepeatTemplate template;
private JobInstance jobInstance;
private ItemReader getReader(String[] args) {
return new ListItemReader(Arrays.asList(args));
@@ -101,14 +105,17 @@ public class DefaultStepExecutorTests extends TestCase {
template = new RepeatTemplate();
template.setCompletionPolicy(new SimpleCompletionPolicy(1));
stepExecutor.setChunkOperations(template);
jobInstance = new JobInstance(new Long(0), new JobInstanceProperties());
jobInstance.setJob(new Job("FOO"));
}
public void testStepExecutor() throws Exception {
StepInstance step = new StepInstance(new Long(9));
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
JobExecution jobExecutionContext = new JobExecution(jobInstance);
StepExecution stepExecution = new StepExecution(step,
jobExecutionContext);
stepExecutor.process(stepConfiguration, stepExecution);
assertEquals(1, processed.size());
@@ -124,8 +131,7 @@ public class DefaultStepExecutorTests extends TestCase {
stepExecutor.setChunkOperations(template);
StepInstance step = new StepInstance(new Long(1));
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
JobExecution jobExecution = new JobExecution(new JobInstance(jobIdentifier, new Long(1)));
JobExecution jobExecution = new JobExecution(jobInstance);
StepExecution stepExecution = new StepExecution(step, jobExecution);
StepContribution contribution = stepExecution.createStepContribution();
@@ -145,9 +151,9 @@ public class DefaultStepExecutorTests extends TestCase {
stepExecutor.setChunkOperations(template);
final StepInstance step = new StepInstance(new Long(1));
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
final JobExecution jobExecution = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
final StepExecution stepExecution = new StepExecution(step, jobExecution);
final JobExecution jobExecution = new JobExecution(jobInstance);
final StepExecution stepExecution = new StepExecution(step,
jobExecution);
stepConfiguration.setTasklet(new Tasklet() {
public ExitStatus execute() throws Exception {
@@ -172,9 +178,10 @@ public class DefaultStepExecutorTests extends TestCase {
stepExecutor.setStepOperations(template);
final StepInstance step = new StepInstance(new Long(1));
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
final JobExecution jobExecution = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
final StepExecution stepExecution = new StepExecution(step, jobExecution);
final JobExecution jobExecution = new JobExecution(jobInstance);
jobExecution.setId(new Long(1));
final StepExecution stepExecution = new StepExecution(step,
jobExecution);
template.setInterceptor(new RepeatInterceptorAdapter() {
public void open(RepeatContext context) {
@@ -196,9 +203,9 @@ public class DefaultStepExecutorTests extends TestCase {
stepExecutor.setRepository(repository);
StepInstance step = new StepInstance(new Long(1));
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
JobExecution jobExecutionContext = new JobExecution(jobInstance);
StepExecution stepExecution = new StepExecution(step,
jobExecutionContext);
stepExecutor.process(stepConfiguration, stepExecution);
assertEquals(1, processed.size());
@@ -223,9 +230,9 @@ public class DefaultStepExecutorTests extends TestCase {
StepInstance step = new StepInstance(new Long(1));
stepConfiguration.setTasklet(tasklet);
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
JobExecution jobExecutionContext = new JobExecution(jobInstance);
StepExecution stepExecution = new StepExecution(step,
jobExecutionContext);
try {
stepExecutor.process(stepConfiguration, stepExecution);
@@ -255,9 +262,9 @@ public class DefaultStepExecutorTests extends TestCase {
StepInstance step = new StepInstance(new Long(1));
stepConfiguration.setTasklet(tasklet);
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
JobExecution jobExecutionContext = new JobExecution(jobInstance);
StepExecution stepExecution = new StepExecution(step,
jobExecutionContext);
try {
stepExecutor.process(stepConfiguration, stepExecution);
@@ -277,9 +284,9 @@ public class DefaultStepExecutorTests extends TestCase {
MockRestartableTasklet tasklet = new MockRestartableTasklet();
stepConfiguration.setTasklet(tasklet);
stepConfiguration.setSaveRestartData(true);
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
JobExecution jobExecutionContext = new JobExecution(jobInstance);
StepExecution stepExecution = new StepExecution(step,
jobExecutionContext);
try {
stepExecutor.process(stepConfiguration, stepExecution);
@@ -302,9 +309,9 @@ public class DefaultStepExecutorTests extends TestCase {
MockRestartableTasklet tasklet = new MockRestartableTasklet();
stepConfiguration.setTasklet(tasklet);
stepConfiguration.setSaveRestartData(true);
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
JobExecution jobExecutionContext = new JobExecution(jobInstance);
StepExecution stepExecution = new StepExecution(step,
jobExecutionContext);
try {
stepExecutor.process(stepConfiguration, stepExecution);
@@ -327,9 +334,9 @@ public class DefaultStepExecutorTests extends TestCase {
MockRestartableTasklet tasklet = new MockRestartableTasklet();
stepConfiguration.setTasklet(tasklet);
stepConfiguration.setSaveRestartData(false);
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
JobExecution jobExecutionContext = new JobExecution(jobInstance);
StepExecution stepExecution = new StepExecution(step,
jobExecutionContext);
try {
stepExecutor.process(stepConfiguration, stepExecution);
@@ -355,8 +362,7 @@ public class DefaultStepExecutorTests extends TestCase {
}
});
stepConfiguration.setSaveRestartData(true);
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
JobExecution jobExecution = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
JobExecution jobExecution = new JobExecution(jobInstance);
StepExecution stepExecution = new StepExecution(step, jobExecution);
try {

View File

@@ -17,8 +17,8 @@ package org.springframework.batch.execution.step.simple;
import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.core.repository.JobRepository;
@@ -32,7 +32,7 @@ public class JobRepositorySupport implements JobRepository {
/* (non-Javadoc)
* @see org.springframework.batch.container.common.repository.JobRepository#findOrCreateJob(org.springframework.batch.container.common.domain.JobConfiguration)
*/
public JobExecution findOrCreateJob(Job jobConfiguration, JobIdentifier runtimeInformation) {
public JobExecution createJobExecution(Job jobConfiguration, JobInstanceProperties jobInstanceProperties) {
return null;
}

View File

@@ -22,6 +22,7 @@ import junit.framework.TestCase;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.core.domain.StepSupport;
@@ -65,7 +66,7 @@ public class SimpleStepExecutorFactoryTests extends TestCase {
SimpleStepExecutor executor = (SimpleStepExecutor) factory
.getExecutor(configuration);
StepExecution stepExecution = new StepExecution(new StepInstance(
new Long(11)), new JobExecution(new JobInstance(null),
new Long(11)), new JobExecution(new JobInstance(new Long(0L), new JobInstanceProperties()),
new Long(12)));
try {
executor.process(configuration, stepExecution);
@@ -92,7 +93,7 @@ public class SimpleStepExecutorFactoryTests extends TestCase {
SimpleStepExecutor executor = (SimpleStepExecutor) factory
.getExecutor(configuration);
StepExecution stepExecution = new StepExecution(new StepInstance(
new Long(11)), new JobExecution(new JobInstance(null),
new Long(11)), new JobExecution(new JobInstance(new Long(0L), new JobInstanceProperties()),
new Long(12)));
try {
executor.process(configuration, stepExecution);
@@ -130,7 +131,7 @@ public class SimpleStepExecutorFactoryTests extends TestCase {
SimpleStepExecutor executor = (SimpleStepExecutor) factory
.getExecutor(configuration);
StepExecution stepExecution = new StepExecution(new StepInstance(
new Long(11)), new JobExecution(new JobInstance(null),
new Long(11)), new JobExecution(new JobInstance(new Long(0L), new JobInstanceProperties()),
new Long(12)));
executor.process(configuration, stepExecution);
assertEquals(2, list.size());

View File

@@ -25,6 +25,7 @@ import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInstanceProperties;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.core.domain.StepSupport;
@@ -65,7 +66,7 @@ public class StepExecutorInterruptionTests extends TestCase {
jobConfiguration.addStep(stepConfiguration);
JobIdentifier runtimeInformation = new SimpleJobIdentifier("TestJob");
jobConfiguration.setBeanName("testJob");
job = jobRepository.findOrCreateJob(jobConfiguration, runtimeInformation).getJobInstance();
job = jobRepository.createJobExecution(jobConfiguration, new JobInstanceProperties()).getJobInstance();
executor = new SimpleStepExecutor();
}
@@ -75,7 +76,7 @@ public class StepExecutorInterruptionTests extends TestCase {
List steps = job.getStepInstances();
final StepInstance step = (StepInstance) steps.get(0);
JobExecution jobExecutionContext = new JobExecution(new JobInstance(null, new Long(0)));
JobExecution jobExecutionContext = new JobExecution(new JobInstance(new Long(0L), new JobInstanceProperties()));
final StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
stepConfiguration.setTasklet(new Tasklet() {
public ExitStatus execute() throws Exception {

View File

@@ -12,11 +12,7 @@
<bean id="simpleContainerLauncher"
class="org.springframework.batch.execution.launch.SimpleJobLauncher">
<property name="jobRepository" ref="simpleJobRepository" />
<property name="jobLocator"
ref="jobConfigurationRegistry" />
<property name="jobExecutor" ref="jobLifecycle" />
<property name="jobIdentifierFactory"
ref="jobRuntimeInformationFactory" />
</bean>
<bean id="jobConfigurationRegistry"