OPEN - issue BATCH-733: Upgrade StepExecutionResourceProxy to be able to use values from job execution context.

Step 1: extend JobFactory implementations a bit to provide more options for creating the context (also consolidated TaskExecutor and QUartz JobLaunchers into JobRegstryBackgroundJobRunner).
This commit is contained in:
dsyer
2008-07-21 16:41:16 +00:00
parent c424603e59
commit 69a64758d8
18 changed files with 566 additions and 332 deletions

View File

@@ -1,131 +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.sample.launch;
import java.util.ArrayList;
import java.util.List;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.configuration.support.ClassPathXmlApplicationContextJobFactory;
import org.springframework.batch.core.repository.DuplicateJobException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ResourceLoader;
/**
* @author Dave Syer
*
*/
public class TaskExecutorLauncher implements ResourceLoaderAware {
private JobRegistry registry;
private ResourceLoader resourceLoader;
private ApplicationContext parentContext = null;
private static List<RuntimeException> errors = new ArrayList<RuntimeException>();
/**
* Public setter for the {@link JobRegistry}.
* @param registry the registry to set
*/
public void setRegistry(JobRegistry registry) {
this.registry = registry;
}
/*
* (non-Javadoc)
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org.springframework.core.io.ResourceLoader)
*/
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
/**
* Public getter for the errors.
* @return the errors
*/
public static List<RuntimeException> getErrors() {
return errors;
}
private void register(String[] paths) throws DuplicateJobException {
for (int i = 0; i < paths.length; i++) {
String path = paths[i];
ConfigurableListableBeanFactory beanFactory = new XmlBeanFactory(resourceLoader.getResource(path),
parentContext.getAutowireCapableBeanFactory());
String[] names = beanFactory.getBeanNamesForType(Job.class);
for (int j = 0; j < names.length; j++) {
registry.register(new ClassPathXmlApplicationContextJobFactory(names[j], path, parentContext));
}
}
}
public static void main(String[] args) throws Exception {
final TaskExecutorLauncher launcher = new TaskExecutorLauncher();
errors.clear();
new Thread(new Runnable() {
public void run() {
try {
launcher.run();
}
catch (RuntimeException e) {
errors.add(e);
throw e;
}
};
}).start();
while (launcher.parentContext == null) {
Thread.sleep(100L);
}
// Paths to individual job configurations.
final String[] paths = new String[] { "jobs/adhocLoopJob.xml", "jobs/footballJob.xml" };
launcher.register(paths);
System.out
.println("Started application. "
+ "Please connect using JMX (remember to use -Dcom.sun.management.jmxremote if you can't see anything in Jconsole).");
System.in.read();
}
private void run() {
/*
* A simple execution environment with an MBean for the JobLauncher,
* which has an asynchronous TaskExecutor. This will be used as the
* parent context for loading job configurations.
*/
final ApplicationContext parent = new ClassPathXmlApplicationContext("adhoc-job-launcher-context.xml");
parent.getAutowireCapableBeanFactory().autowireBeanProperties(this,
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
parent.getAutowireCapableBeanFactory().initializeBean(this, "taskExecutorLauncher");
this.parentContext = parent;
}
}

View File

@@ -1,106 +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.sample.quartz;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.configuration.support.ClassPathXmlApplicationContextJobFactory;
import org.springframework.batch.core.repository.DuplicateJobException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ResourceLoader;
public class QuartzBatchLauncher {
private static Log log = LogFactory.getLog(QuartzBatchLauncher.class);
private JobRegistry registry;
private ResourceLoader resourceLoader;
private ApplicationContext parentContext = null;
/**
* Public setter for the {@link JobRegistry}.
* @param registry the registry to set
*/
public void setRegistry(JobRegistry registry) {
this.registry = registry;
}
/*
* (non-Javadoc)
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org.springframework.core.io.ResourceLoader)
*/
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
private void register(String[] paths) throws DuplicateJobException {
for (int i = 0; i < paths.length; i++) {
String path = paths[i];
ConfigurableListableBeanFactory beanFactory = new XmlBeanFactory(resourceLoader.getResource(path),
parentContext.getAutowireCapableBeanFactory());
String[] names = beanFactory.getBeanNamesForType(Job.class);
for (int j = 0; j < names.length; j++) {
registry.register(new ClassPathXmlApplicationContextJobFactory(names[j], path, parentContext));
}
}
}
public static void main(String[] args) throws Exception {
final QuartzBatchLauncher launcher = new QuartzBatchLauncher();
new Thread(new Runnable() {
public void run() {
launcher.run();
};
}).start();
while (launcher.parentContext == null) {
Thread.sleep(100L);
}
// Paths to individual job configurations.
final String[] paths = new String[] { "jobs/adhocLoopJob.xml", "jobs/footballJob.xml" };
launcher.register(paths);
log.info("Started Quartz scheduler.");
System.in.read();
}
private void run() {
/*
* A simple execution environment with a Quartz scheduler. This will be
* used as the parent context for loading job configurations.
*/
final ApplicationContext parent = new ClassPathXmlApplicationContext("quartz-job-launcher-context.xml");
parent.getAutowireCapableBeanFactory().autowireBeanProperties(this,
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
parent.getAutowireCapableBeanFactory().initializeBean(this, "quartzLauncher");
this.parentContext = parent;
}
}

View File

@@ -22,7 +22,7 @@ log4j.rootLogger=info, stdout
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace
### enable spring
log4j.logger.org.springframework=error
log4j.logger.org.springframework=info
#log4j.logger.org.springframework.transaction=debug
#log4j.logger.org.springframework.jdbc.core=debug
#log4j.logger.org.springframework.orm=debug

View File

@@ -15,17 +15,22 @@
*/
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 java.util.ArrayList;
import java.util.List;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import junit.framework.TestCase;
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.support.JobRegistryBackgroundJobRunner;
import org.springframework.jmx.MBeanServerNotFoundException;
import org.springframework.jmx.access.InvalidInvocationException;
import org.springframework.jmx.access.MBeanProxyFactoryBean;
@@ -35,7 +40,7 @@ import org.springframework.jmx.support.MBeanServerConnectionFactoryBean;
* @author Dave Syer
*
*/
public class RemoteLauncherTests extends TestCase {
public class RemoteLauncherTests {
private static Log logger = LogFactory.getLog(RemoteLauncherTests.class);
@@ -47,11 +52,14 @@ public class RemoteLauncherTests extends TestCase {
private static JobLoader loader;
@Test
public void testConnect() throws Exception {
assertEquals(0, errors.size());
String message = errors.isEmpty() ? "" : errors.get(0).getMessage();
assertEquals(message, 0, errors.size());
assertTrue(isConnected());
}
@Test
public void testLaunchBadJob() throws Exception {
assertEquals(0, errors.size());
assertTrue(isConnected());
@@ -59,6 +67,7 @@ public class RemoteLauncherTests extends TestCase {
assertTrue("Should contain 'NoSuchJobException': " + result, result.indexOf("NoSuchJobException") >= 0);
}
@Test
public void testLaunchAndStopRealJob() throws Exception {
assertEquals(0, errors.size());
assertTrue(isConnected());
@@ -74,7 +83,8 @@ public class RemoteLauncherTests extends TestCase {
* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
@Before
public void setUp() throws Exception {
if (launcher != null) {
return;
}
@@ -82,7 +92,7 @@ public class RemoteLauncherTests extends TestCase {
thread = new Thread(new Runnable() {
public void run() {
try {
TaskExecutorLauncher.main(new String[0]);
JobRegistryBackgroundJobRunner.main("adhoc-job-launcher-context.xml", "jobs/adhocLoopJob.xml");
}
catch (Exception e) {
errors.add(e);
@@ -102,8 +112,8 @@ public class RemoteLauncherTests extends TestCase {
*/
private static boolean isConnected() throws Exception {
boolean connected = false;
if (!TaskExecutorLauncher.getErrors().isEmpty()) {
throw (RuntimeException) TaskExecutorLauncher.getErrors().get(0);
if (!JobRegistryBackgroundJobRunner.getErrors().isEmpty()) {
throw (RuntimeException) JobRegistryBackgroundJobRunner.getErrors().get(0);
}
if (launcher == null) {
MBeanServerConnectionFactoryBean connectionFactory = new MBeanServerConnectionFactoryBean();