diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/ExportedJobLauncher.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/ExportedJobLauncher.java deleted file mode 100644 index 3c1463ba0..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/ExportedJobLauncher.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2006-2007 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.launch.support; - -import java.util.Properties; - -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.launch.JobLauncher; - -/** - * Interface to expose for remote management of jobs. Similar to - * {@link JobLauncher}, but replaces {@link JobExecution} and - * {@link JobParameters} with Strings in return types and method parameters, so - * it can be inspected by remote clients like the jconsole from the JRE without - * any links to Spring Batch. - * - * @author Dave Syer - * - */ -public interface ExportedJobLauncher { - - /** - * Launch a job with the given name. - * - * @param name the name of the job to launch - * @return a representation of the {@link JobExecution} returned by a - * {@link JobLauncher}. - */ - String run(String name); - - /** - * Launch a job with the given name and parameters. - * - * @param name the name of the job to launch - * @return a representation of the {@link JobExecution} returned by a - * {@link JobLauncher}. - */ - String run(String name, String params); - - /** - * Stop all running jobs. - */ - void stop(); - - /** - * Stop running jobs with the supplied name. - */ - void stop(String name); - - /** - * Clear volatile memory of any jobs that are not running (and are therefore - * completed or failed). - */ - void clear(); - - /** - * Enquire if any jobs launched here are still running. - * - * @return true if any jobs are running. - */ - boolean isRunning(); - - /** - * Query statistics of jobs. - * - * @return properties representing last known state of jobs with this name - * (including those that may have finished) - */ - public Properties getStatistics(String name); -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/SimpleExportedJobLauncher.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/SimpleExportedJobLauncher.java deleted file mode 100644 index aaa21612f..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/SimpleExportedJobLauncher.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2006-2007 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.launch.support; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.Map.Entry; - -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobExecutionException; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.configuration.JobLocator; -import org.springframework.batch.core.converter.DefaultJobParametersConverter; -import org.springframework.batch.core.converter.JobParametersConverter; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.core.launch.NoSuchJobException; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.batch.support.PropertiesConverter; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; - -/** - * @author Dave Syer - * - */ -public class SimpleExportedJobLauncher implements ExportedJobLauncher, InitializingBean { - - private static final String SEPARATOR = "|"; - - private JobLauncher launcher; - - private JobLocator jobLocator; - - private Map registry = new HashMap(); - - private JobParametersConverter jobParametersConverter = new DefaultJobParametersConverter(); - - /* - * (non-Javadoc) - * - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - public void afterPropertiesSet() throws Exception { - Assert.notNull(launcher, "JobLauncher must be provided."); - Assert.notNull(jobLocator, "JobLocator must be provided."); - } - - /** - * Public setter for the {@link JobLauncher}. - * @param launcher the launcher to set - */ - public void setLauncher(JobLauncher launcher) { - this.launcher = launcher; - } - - /** - * Public setter for the JobLocator. - * @param jobLocator the jobLocator to set - */ - public void setJobLocator(JobLocator jobLocator) { - this.jobLocator = jobLocator; - } - - /** - * Public setter for the JobParametersFactory. - * @param jobParametersConverter the jobParametersFactory to set - */ - public void setJobParametersFactory(JobParametersConverter jobParametersConverter) { - this.jobParametersConverter = jobParametersConverter; - } - - /* - * (non-Javadoc) - * - * @see org.springframework.batch.execution.bootstrap.support.ExportedJobLauncher - * #getStatistics() - */ - public Properties getStatistics(String name) { - Properties result = new Properties(); - int i = 0; - Set keys = getKeyForName(name); - for (String key : keys) { - JobExecution execution = (JobExecution) registry.get(key); - addStatistics(result, execution, name + "." + i + "."); - i++; - } - return result; - } - - /** - * @param result - * @param execution - */ - private void addStatistics(Properties result, JobExecution execution, String prefix) { - int i = 0; - for (StepExecution stepExecution : execution.getStepExecutions()) { - ExecutionContext executionContext = stepExecution.getExecutionContext(); - for (Entry entry : executionContext.entrySet()) { - result.setProperty(prefix + "step" + i + "." + entry.getKey(), "" + entry.getValue()); - } - } - } - - /* - * (non-Javadoc) - * - * @see org.springframework.batch.execution.bootstrap.support.ExportedJobLauncher - * #isRunning() - */ - public boolean isRunning() { - for (String key : registry.keySet()) { - JobExecution execution = (JobExecution) registry.get(key); - if (execution.isRunning()) { - return true; - } - } - return false; - } - - /* - * (non-Javadoc) - * - * @see org.springframework.batch.execution.bootstrap.support.ExportedJobLauncher - * #run(java.lang.String) - */ - public String run(String name) { - return run(name, null); - } - - /* - * (non-Javadoc) - * - * @see org.springframework.batch.execution.bootstrap.support.ExportedJobLauncher - * #run(java.lang.String, java.lang.String) - */ - public String run(String name, String params) { - - Job job; - try { - job = jobLocator.getJob(name); - } - catch (NoSuchJobException e) { - return e.getClass().getName() + ": " + e.getMessage(); - } - - JobParameters jobParameters = new JobParameters(); - if (params != null) { - jobParameters = jobParametersConverter.getJobParameters(PropertiesConverter.stringToProperties(params)); - } - - JobExecution execution; - try { - execution = launcher.run(job, jobParameters); - } - catch (JobExecutionException e) { - return e.getClass().getName() + ": " + e.getMessage(); - } - registry.put(name + SEPARATOR + params, execution); - - return execution.toString(); - - } - - /* - * (non-Javadoc) - * - * @see org.springframework.batch.execution.bootstrap.support.ExportedJobLauncher - * #stop() - */ - public void stop() { - for (String key : registry.keySet()) { - JobExecution execution = (JobExecution) registry.get(key); - execution.stop(); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.batch.core.launch.support.ExportedJobLauncher#stop(java.lang.String) - */ - public void stop(String name) { - Set keys = getKeyForName(name); - for (String key : keys) { - JobExecution execution = (JobExecution) registry.get(key); - execution.stop(); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.batch.core.launch.support.ExportedJobLauncher#clear() - */ - public void clear() { - for (String key : registry.keySet()) { - JobExecution execution = (JobExecution) registry.get(key); - if (!execution.isRunning()) { - registry.remove(key); - } - } - } - - /** - * @param key - * @return - */ - private Set getKeyForName(String name) { - Set result = new HashSet(); - for (String key : registry.keySet()) { - if (key.startsWith(name + SEPARATOR)) { - result.add(key); - } - } - return result; - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleExportedJobLauncherTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleExportedJobLauncherTests.java deleted file mode 100644 index 5316cf804..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleExportedJobLauncherTests.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2006-2007 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.launch.support; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Properties; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.JobParametersBuilder; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.configuration.support.MapJobRegistry; -import org.springframework.batch.core.configuration.support.ReferenceJobFactory; -import org.springframework.batch.core.converter.JobParametersConverter; -import org.springframework.batch.core.job.JobSupport; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; -import org.springframework.batch.core.step.StepSupport; -import org.springframework.batch.item.ExecutionContext; - -/** - * @author Dave Syer - * - */ -public class SimpleExportedJobLauncherTests { - - private SimpleExportedJobLauncher launcher = new SimpleExportedJobLauncher(); - - private MapJobRegistry jobLocator = new MapJobRegistry(); - - private List parameters = new ArrayList(); - - private List executions = new ArrayList(); - - @Before - public void setUp() throws Exception { - launcher.setLauncher(new JobLauncher() { - public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException { - JobExecution result = new JobExecution(null); - StepExecution stepExecution = result.createStepExecution(new StepSupport("stepName")); - stepExecution.setExecutionContext(new ExecutionContext() { - { - put("foo", "bar"); - } - }); - parameters.add(jobParameters); - executions.add(result); - return result; - } - }); - launcher.setJobLocator(jobLocator); - } - - /** - * Test method for - * {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#afterPropertiesSet()} - * . - * - * @throws Exception - */ - @Test - public void testAfterPropertiesSet() throws Exception { - launcher = new SimpleExportedJobLauncher(); - try { - launcher.afterPropertiesSet(); - fail("Expected IllegalArgumentException"); - } - catch (IllegalArgumentException e) { - String message = e.getMessage(); - assertTrue("Message does not contain 'launcher': " + message, - contains(message.toLowerCase(), "joblauncher")); - } - } - - /** - * Test method for - * {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#afterPropertiesSet()} - * . - * - * @throws Exception - */ - @Test - public void testAfterPropertiesSetWithLauncher() throws Exception { - launcher = new SimpleExportedJobLauncher(); - launcher.setLauncher(new JobLauncher() { - public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException { - return null; - } - }); - try { - launcher.afterPropertiesSet(); - fail("Expected IllegalArgumentException"); - } - catch (IllegalArgumentException e) { - String message = e.getMessage(); - assertTrue("Message does not contain 'locator': " + message, contains(message.toLowerCase(), "joblocator")); - } - } - - @Test - public void testGetStatistics() { - Properties props = launcher.getStatistics("foo"); - assertNotNull(props); - assertEquals(0, props.entrySet().size()); - } - - @Test - public void testGetStatisticsWithContent() throws Exception { - jobLocator.register(new ReferenceJobFactory(new JobSupport("foo"))); - launcher.run("foo"); - Properties props = launcher.getStatistics("foo"); - assertNotNull(props); - assertEquals(1, props.entrySet().size()); - } - - /** - * Test method for - * {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#isRunning()} - * . - * - * @throws Exception - */ - @Test - public void testIsRunning() throws Exception { - jobLocator.register(new ReferenceJobFactory(new JobSupport("foo"))); - launcher.run("foo"); - assertTrue(launcher.isRunning()); - } - - /** - * Test method for - * {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#isRunning()} - * . - * - * @throws Exception - */ - @Test - public void testAlreadyRunning() throws Exception { - jobLocator.register(new ReferenceJobFactory(new JobSupport("foo"))); - launcher.setLauncher(new JobLauncher() { - public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException { - throw new JobExecutionAlreadyRunningException("Bad!"); - } - }); - String value = launcher.run("foo"); - assertTrue("Return value was not an exception: " + value, - contains(value, "JobExecutionAlreadyRunningException")); - } - - /** - * Test method for - * {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#run(java.lang.String)} - * . - */ - @Test - public void testRunNonExistentJob() { - String value = launcher.run("foo"); - assertTrue("Return value was not an exception: " + value, contains(value, "NoSuchJobException")); - } - - /** - * Test method for - * {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#run(java.lang.String)} - * . - * - * @throws Exception - */ - @Test - public void testRunJobWithParameters() throws Exception { - jobLocator.register(new ReferenceJobFactory(new JobSupport("foo"))); - String value = launcher.run("foo", "bar=spam,bucket=crap"); - assertTrue(launcher.isRunning()); - assertTrue("Return value was not a JobExecution: " + value, contains(value, "JobExecution")); - } - - /** - * Test method for - * {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#run(java.lang.String)} - * . - * - * @throws Exception - */ - @Test - public void testRunJobWithParametersAndFactory() throws Exception { - jobLocator.register(new ReferenceJobFactory(new JobSupport("foo"))); - launcher.setJobParametersFactory(new JobParametersConverter() { - public JobParameters getJobParameters(Properties properties) { - return new JobParametersBuilder().addString("foo", "spam").toJobParameters(); - } - - public Properties getProperties(JobParameters params) { - return null; - } - }); - launcher.run("foo", "bar=spam,bucket=crap"); - assertEquals(1, parameters.size()); - assertEquals("spam", parameters.get(0).getString("foo")); - } - - /** - * Test method for - * {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#stop()} - * . - * - * @throws Exception - */ - @Test - public void testStop() throws Exception { - jobLocator.register(new ReferenceJobFactory(new JobSupport("foo"))); - launcher.run("foo"); - assertTrue(launcher.isRunning()); - launcher.stop(); - assertEquals(BatchStatus.STOPPING, executions.get(0).getStatus()); - assertTrue(launcher.isRunning()); - } - - /** - * Test method for - * {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#stop()} - * . - * - * @throws Exception - */ - @Test - public void testStopWithName() throws Exception { - jobLocator.register(new ReferenceJobFactory(new JobSupport("foo"))); - launcher.run("foo"); - assertTrue(launcher.isRunning()); - launcher.stop("foo"); - assertEquals(BatchStatus.STOPPING, executions.get(0).getStatus()); - assertTrue(launcher.isRunning()); - } - - @Test - public void testClear() throws Exception { - jobLocator.register(new ReferenceJobFactory(new JobSupport("foo"))); - launcher.run("foo"); - // mark it as actually ended - executions.get(0).setEndTime(new Date()); - launcher.clear(); - assertFalse(launcher.isRunning()); - } - - private boolean contains(String str, String searchStr) { - return str.indexOf(searchStr) != -1; - } -} diff --git a/spring-batch-samples/src/main/resources/adhoc-job-launcher-context.xml b/spring-batch-samples/src/main/resources/adhoc-job-launcher-context.xml index 51ee8f133..a4b09c5d6 100644 --- a/spring-batch-samples/src/main/resources/adhoc-job-launcher-context.xml +++ b/spring-batch-samples/src/main/resources/adhoc-job-launcher-context.xml @@ -6,16 +6,10 @@ http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> - - - - - - - + @@ -24,7 +18,7 @@ - + @@ -33,10 +27,20 @@ - - - - + + + + + + + + + + + + + + diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/launch/RemoteLauncherTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/launch/RemoteLauncherTests.java index 5d6d1c514..2b622dc99 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/launch/RemoteLauncherTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/launch/RemoteLauncherTests.java @@ -16,8 +16,8 @@ package org.springframework.batch.sample.launch; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.List; @@ -29,7 +29,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Before; import org.junit.Test; -import org.springframework.batch.core.launch.support.ExportedJobLauncher; +import org.springframework.batch.core.launch.JobOperator; +import org.springframework.batch.core.launch.NoSuchJobException; import org.springframework.batch.core.launch.support.JobRegistryBackgroundJobRunner; import org.springframework.jmx.MBeanServerNotFoundException; import org.springframework.jmx.access.InvalidInvocationException; @@ -46,7 +47,7 @@ public class RemoteLauncherTests { private static List errors = new ArrayList(); - private static ExportedJobLauncher launcher; + private static JobOperator launcher; private static JobLoader loader; @@ -61,21 +62,19 @@ public class RemoteLauncherTests { public void testLaunchBadJob() throws Exception { assertEquals(0, errors.size()); assertTrue(isConnected()); - String result = launcher.run("foo"); - assertTrue("Should contain 'NoSuchJobException': " + result, result.indexOf("NoSuchJobException") >= 0); + try { + launcher.start("foo", ""); + fail("Expected NoSuchJobException"); + } catch (NoSuchJobException e) { + //expected; + } } @Test - public void testLaunchAndStopRealJob() throws Exception { + public void testAvailableJobs() throws Exception { assertEquals(0, errors.size()); assertTrue(isConnected()); - String result = launcher.run("loopJob"); - assertTrue("Should contain 'JobExecution': " + result, result.indexOf("JobExecution: id=") >= 0); - Thread.sleep(500); - assertTrue(launcher.isRunning()); - launcher.stop(); - Thread.sleep(500); - assertFalse(launcher.isRunning()); + assertTrue(launcher.getJobNames().contains("loopJob")); } /* @@ -112,9 +111,8 @@ public class RemoteLauncherTests { } if (launcher == null) { MBeanServerConnectionFactoryBean connectionFactory = new MBeanServerConnectionFactoryBean(); - connectionFactory.setServiceUrl("service:jmx:rmi://localhost/jndi/rmi://localhost:1099/batch-samples"); try { - launcher = (ExportedJobLauncher) getMBean(connectionFactory, "spring:service=batch,bean=jobLauncher", ExportedJobLauncher.class); + launcher = (JobOperator) getMBean(connectionFactory, "spring:service=batch,bean=jobOperator", JobOperator.class); loader = (JobLoader) getMBean(connectionFactory, "spring:service=batch,bean=jobLoader", JobLoader.class); } catch (MBeanServerNotFoundException e) { @@ -123,7 +121,7 @@ public class RemoteLauncherTests { } } try { - launcher.isRunning(); + launcher.getJobNames(); connected = loader.getConfigurations().size()>0; logger.info("Configurations loaded: " + loader.getConfigurations()); } @@ -139,7 +137,6 @@ public class RemoteLauncherTests { factory.setObjectName(objectName); factory.setProxyInterface(interfaceType); factory.setServer((MBeanServerConnection) connectionFactory.getObject()); - // factory.setServiceUrl("service:jmx:rmi://localhost/jndi/rmi://localhost:1099/batch-samples"); factory.afterPropertiesSet(); return factory.getObject(); }