/*
* Copyright 2006-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.configuration.support;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import org.junit.Test;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersIncrementer;
import org.springframework.batch.core.JobParametersValidator;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.DuplicateJobException;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.configuration.StepRegistry;
import org.springframework.batch.core.launch.NoSuchJobException;
import org.springframework.batch.core.step.NoSuchStepException;
import org.springframework.batch.core.step.StepLocator;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.test.util.ReflectionTestUtils;
/**
* @author Dave Syer
* @author Stephane Nicoll
*/
public class DefaultJobLoaderTests {
/**
* The name of the job as defined in the test context used in this test.
*/
private static final String TEST_JOB_NAME = "test-job";
/**
* The name of the step as defined in the test context used in this test.
*/
private static final String TEST_STEP_NAME = "test-step";
private JobRegistry jobRegistry = new MapJobRegistry();
private StepRegistry stepRegistry = new MapStepRegistry();
private DefaultJobLoader jobLoader = new DefaultJobLoader(jobRegistry, stepRegistry);
@Test
public void testClear() throws Exception {
GenericApplicationContextFactory factory = new GenericApplicationContextFactory(new ByteArrayResource(
JOB_XML.getBytes()));
jobLoader.load(factory);
assertEquals(1, ((Map) ReflectionTestUtils.getField(jobLoader, "contexts")).size());
assertEquals(1, ((Map) ReflectionTestUtils.getField(jobLoader, "contextToJobNames")).size());
jobLoader.clear();
assertEquals(0, ((Map) ReflectionTestUtils.getField(jobLoader, "contexts")).size());
assertEquals(0, ((Map) ReflectionTestUtils.getField(jobLoader, "contextToJobNames")).size());
}
@Test
public void testLoadWithExplicitName() throws Exception {
GenericApplicationContextFactory factory = new GenericApplicationContextFactory(new ByteArrayResource(
JOB_XML.getBytes()));
jobLoader.load(factory);
assertEquals(1, jobRegistry.getJobNames().size());
jobLoader.reload(factory);
assertEquals(1, jobRegistry.getJobNames().size());
}
@Test
public void createWithBothRegistries() {
final DefaultJobLoader loader = new DefaultJobLoader();
loader.setJobRegistry(jobRegistry);
loader.setStepRegistry(stepRegistry);
loader.afterPropertiesSet();
}
@Test
public void createWithOnlyJobRegistry() {
final DefaultJobLoader loader = new DefaultJobLoader();
loader.setJobRegistry(jobRegistry);
loader.afterPropertiesSet();
}
@Test
public void testRegistryUpdated() throws DuplicateJobException {
GenericApplicationContextFactory factory = new GenericApplicationContextFactory(
new ClassPathResource("trivial-context.xml", getClass()));
jobLoader.load(factory);
assertEquals(1, jobRegistry.getJobNames().size());
assertStepExist(TEST_JOB_NAME, TEST_STEP_NAME);
}
@Test
public void testMultipleJobsInTheSameContext() throws DuplicateJobException {
GenericApplicationContextFactory factory = new GenericApplicationContextFactory(
new ClassPathResource("job-context-with-steps.xml", getClass()));
jobLoader.load(factory);
assertEquals(2, jobRegistry.getJobNames().size());
assertStepExist("job1", "step11", "step12");
assertStepDoNotExist("job1", "step21", "step22");
assertStepExist("job2", "step21", "step22");
assertStepDoNotExist("job2", "step11", "step12");
}
@Test
public void testMultipleJobsInTheSameContextWithSeparateSteps() throws DuplicateJobException {
GenericApplicationContextFactory factory = new GenericApplicationContextFactory(
new ClassPathResource("job-context-with-separate-steps.xml", getClass()));
jobLoader.load(factory);
assertEquals(2, jobRegistry.getJobNames().size());
assertStepExist("job1", "step11", "step12", "genericStep1", "genericStep2");
assertStepDoNotExist("job1", "step21", "step22");
assertStepExist("job2", "step21", "step22", "genericStep1", "genericStep2");
assertStepDoNotExist("job2", "step11", "step12");
}
@Test
public void testNoStepRegistryAvailable() throws DuplicateJobException {
final JobLoader loader = new DefaultJobLoader(jobRegistry);
GenericApplicationContextFactory factory = new GenericApplicationContextFactory(
new ClassPathResource("job-context-with-steps.xml", getClass()));
loader.load(factory);
// No step registry available so just registering the jobs
assertEquals(2, jobRegistry.getJobNames().size());
}
@Test
public void testLoadWithJobThatIsNotAStepLocator() throws DuplicateJobException {
GenericApplicationContextFactory factory = new GenericApplicationContextFactory(
new ByteArrayResource(BASIC_JOB_XML.getBytes()));
try {
jobLoader.load(factory);
fail("Should have failed with a ["+UnsupportedOperationException.class.getName()+"] as job does not" +
"implement StepLocator.");
} catch (UnsupportedOperationException e) {
// Job is not a step locator, can't register steps
}
}
@Test
public void testLoadWithJobThatIsNotAStepLocatorNoStepRegistry() throws DuplicateJobException {
final JobLoader loader = new DefaultJobLoader(jobRegistry);
GenericApplicationContextFactory factory = new GenericApplicationContextFactory(
new ByteArrayResource(BASIC_JOB_XML.getBytes()));
try {
loader.load(factory);
} catch (UnsupportedOperationException e) {
fail("Should not have failed with a [" + UnsupportedOperationException.class.getName() + "] as " +
"stepRegistry is not available for this JobLoader instance.");
}
}
@Test
public void testReload() throws Exception {
GenericApplicationContextFactory factory = new GenericApplicationContextFactory(new ClassPathResource(
"trivial-context.xml", getClass()));
jobLoader.load(factory);
assertEquals(1, jobRegistry.getJobNames().size());
assertStepExist(TEST_JOB_NAME, TEST_STEP_NAME);
jobLoader.reload(factory);
assertEquals(1, jobRegistry.getJobNames().size());
assertStepExist(TEST_JOB_NAME, TEST_STEP_NAME);
}
@Test
public void testReloadWithAutoRegister() throws Exception {
GenericApplicationContextFactory factory = new GenericApplicationContextFactory(new ClassPathResource(
"trivial-context-autoregister.xml", getClass()));
jobLoader.load(factory);
assertEquals(1, jobRegistry.getJobNames().size());
assertStepExist(TEST_JOB_NAME, TEST_STEP_NAME);
jobLoader.reload(factory);
assertEquals(1, jobRegistry.getJobNames().size());
assertStepExist(TEST_JOB_NAME, TEST_STEP_NAME);
}
protected void assertStepExist(String jobName, String... stepNames) {
for (String stepName : stepNames) {
try {
stepRegistry.getStep(jobName, stepName);
} catch (NoSuchJobException e) {
fail("Job with name [" + jobName + "] should have been found.");
} catch (NoSuchStepException e) {
fail("Step with name [" + stepName + "] for job [" + jobName + "] should have been found.");
}
}
}
protected void assertStepDoNotExist(String jobName, String... stepNames) {
for (String stepName : stepNames) {
try {
final Step step = stepRegistry.getStep(jobName, stepName);
fail("Step with name [" + stepName + "] for job [" + jobName + "] should " +
"not have been found but got [" + step + "]");
} catch (NoSuchJobException e) {
fail("Job with name [" + jobName + "] should have been found.");
} catch (NoSuchStepException e) {
// OK
}
}
}
private static final String BASIC_JOB_XML = String
.format(
"<beans xmlns='http://www.springframework.org/schema/beans' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
+ "xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd'><bean class='%s$BasicStubJob'/></beans>",
DefaultJobLoaderTests.class.getName());
private static final String JOB_XML = String
.format(
"<beans xmlns='http://www.springframework.org/schema/beans' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
+ "xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd'><bean class='%s$StubJob'/></beans>",
DefaultJobLoaderTests.class.getName());
public static class BasicStubJob implements Job {
@Override
public void execute(JobExecution execution) {
}
@Override
public JobParametersIncrementer getJobParametersIncrementer() {
return null;
}
@Override
public String getName() {
return "job";
}
@Override
public boolean isRestartable() {
return false;
}
@Override
public JobParametersValidator getJobParametersValidator() {
return null;
}
}
public static class StubJob extends BasicStubJob implements StepLocator {
@Override
public Collection<String> getStepNames() {
return Collections.emptyList();
}
@Override
public Step getStep(String stepName) throws NoSuchStepException {
throw new NoSuchStepException("Step [" + stepName + "] does not exist");
}
}
}