RESOLVED - issue BATCH-980: Add SystemPropertyInitializer

This commit is contained in:
dsyer
2008-12-30 09:23:27 +00:00
parent c9d7b45f14
commit e4ca63a927
9 changed files with 190 additions and 51 deletions

View File

@@ -27,6 +27,7 @@ import org.springframework.batch.core.repository.dao.JobInstanceDao;
import org.springframework.batch.core.repository.dao.StepExecutionDao;
import org.springframework.batch.item.database.support.DataFieldMaxValueIncrementerFactory;
import org.springframework.batch.item.database.support.DefaultDataFieldMaxValueIncrementerFactory;
import org.springframework.batch.support.DatabaseType;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.core.simple.SimpleJdbcOperations;
@@ -92,6 +93,10 @@ public class JobExplorerFactoryBean extends AbstractJobExplorerFactoryBean imple
incrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(dataSource);
}
if (databaseType == null) {
databaseType = DatabaseType.fromMetaData(dataSource).name();
}
Assert.isTrue(incrementerFactory.isSupportedIncrementerType(databaseType), "'" + databaseType
+ "' is an unsupported database type. The supported database types are "
+ StringUtils.arrayToCommaDelimitedString(incrementerFactory.getSupportedIncrementerTypes()));

View File

@@ -22,6 +22,9 @@ import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import javax.sql.DataSource;
import org.junit.Before;
@@ -57,20 +60,45 @@ public class JobExplorerFactoryBeanTests {
}
@Test
public void testDetectDatabaseType() throws Exception {
DatabaseMetaData dmd = createMock(DatabaseMetaData.class);
Connection con = createMock(Connection.class);
expect(dataSource.getConnection()).andReturn(con);
expect(con.getMetaData()).andReturn(dmd);
expect(dmd.getDatabaseProductName()).andReturn("Oracle");
expect(incrementerFactory.isSupportedIncrementerType("ORACLE")).andReturn(true);
expect(incrementerFactory.getSupportedIncrementerTypes()).andReturn(new String[0]);
expect(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).andReturn(new StubIncrementer());
expect(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")).andReturn(
new StubIncrementer());
expect(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "STEP_EXECUTION_SEQ")).andReturn(
new StubIncrementer());
replay(dataSource, con, dmd, incrementerFactory);
factory.afterPropertiesSet();
}
@Test
public void testNoDatabaseType() throws Exception {
DatabaseMetaData dmd = createMock(DatabaseMetaData.class);
Connection con = createMock(Connection.class);
expect(dataSource.getConnection()).andReturn(con);
expect(con.getMetaData()).andReturn(dmd);
expect(dmd.getDatabaseProductName()).andReturn("foo");
try {
expect(incrementerFactory.isSupportedIncrementerType(null)).andReturn(false);
expect(incrementerFactory.getSupportedIncrementerTypes()).andReturn(new String[0]);
replay(incrementerFactory);
replay(dataSource, con, dmd, incrementerFactory);
factory.afterPropertiesSet();
fail();
}
catch (IllegalArgumentException ex) {
// expected
String message = ex.getMessage();
assertTrue("Wrong message: " + message, message.indexOf("unsupported database type") >= 0);
assertTrue("Wrong message: " + message, message.indexOf("DatabaseType") >= 0);
}
}
@@ -117,9 +145,12 @@ public class JobExplorerFactoryBeanTests {
expect(incrementerFactory.isSupportedIncrementerType("foo")).andReturn(true);
expect(incrementerFactory.getSupportedIncrementerTypes()).andReturn(new String[0]);
expect(incrementerFactory.getIncrementer(databaseType, tablePrefix + "JOB_SEQ")).andReturn(new StubIncrementer());
expect(incrementerFactory.getIncrementer(databaseType, tablePrefix + "JOB_EXECUTION_SEQ")).andReturn(new StubIncrementer());
expect(incrementerFactory.getIncrementer(databaseType, tablePrefix + "STEP_EXECUTION_SEQ")).andReturn(new StubIncrementer());
expect(incrementerFactory.getIncrementer(databaseType, tablePrefix + "JOB_SEQ")).andReturn(
new StubIncrementer());
expect(incrementerFactory.getIncrementer(databaseType, tablePrefix + "JOB_EXECUTION_SEQ")).andReturn(
new StubIncrementer());
expect(incrementerFactory.getIncrementer(databaseType, tablePrefix + "STEP_EXECUTION_SEQ")).andReturn(
new StubIncrementer());
replay(incrementerFactory);
factory.afterPropertiesSet();

View File

@@ -0,0 +1,71 @@
/*
* 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.support;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
/**
* Helper class that sets up a System property with a default value. A System
* property is created with the specified key name, and default value (i.e. if
* the property already exists it is not changed).
*
* @author Dave Syer
*
*/
public class SystemPropertyInitializer implements InitializingBean {
/**
* Name of system property used by default.
*/
public static final String ENVIRONMENT = "org.springframework.batch.support.SystemPropertyInitializer.ENVIRONMENT";
private String keyName = ENVIRONMENT;
private String defaultValue;
/**
* Set the key name for the System property that is created. Defaults to
* {@link #ENVIRONMENT}.
*
* @param keyName the key name to set
*/
public void setKeyName(String keyName) {
this.keyName = keyName;
}
/**
* Mandatory property specifying the default value of the System property.
*
* @param defaultValue the default value to set
*/
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
/**
* Sets the System property with the provided name and default value.
*
* @see InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
Assert.state(defaultValue != null || System.getProperty(keyName) != null,
"Either a default value must be specified or the value should already be set for System property: "
+ keyName);
System.setProperty(keyName, System.getProperty(keyName, defaultValue));
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.support;
import static org.junit.Assert.assertEquals;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* @author Dave Syer
*
*/
public class SystemPropertyInitializerTests {
private static final String SIMPLE_NAME = SystemPropertyInitializerTests.class.getSimpleName();
private SystemPropertyInitializer initializer = new SystemPropertyInitializer();
@Before
@After
public void initializeProperty() {
System.clearProperty(SystemPropertyInitializer.ENVIRONMENT);
System.clearProperty(SIMPLE_NAME);
}
@Test
public void testSetKeyName() throws Exception {
initializer.setKeyName(SIMPLE_NAME);
System.setProperty(SIMPLE_NAME, "foo");
initializer.afterPropertiesSet();
assertEquals("foo", System.getProperty(SIMPLE_NAME));
}
@Test
public void testSetDefaultValue() throws Exception {
initializer.setDefaultValue("foo");
initializer.afterPropertiesSet();
assertEquals("foo", System.getProperty(SystemPropertyInitializer.ENVIRONMENT));
}
@Test(expected=IllegalStateException.class)
public void testNoDefaultValue() throws Exception {
initializer.afterPropertiesSet();
}
}

View File

@@ -37,7 +37,6 @@
<property name="jobExplorer">
<bean class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="databaseType" value="${environment}" />
</bean>
</property>
<property name="jobRepository" ref="jobRepository" />

View File

@@ -6,39 +6,28 @@
<!-- Initialise the database before every test case: -->
<import resource="data-source-context-init.xml" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${batch.jdbc.driver}" />
<property name="url" value="${batch.jdbc.url}" />
<property name="username" value="${batch.jdbc.user}" />
<property name="password" value="${batch.jdbc.password}" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" lazy-init="true">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Set up or detect a System property called "environment" used to construct a properties file on the classpath. The default is "hsql". -->
<bean id="environment" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="java.lang.System" />
<property name="targetMethod" value="setProperty" />
<property name="arguments">
<list>
<value>environment</value>
<bean class="java.lang.System" factory-method="getProperty">
<constructor-arg>
<value>environment</value>
</constructor-arg>
<!-- The default value of the environment property -->
<constructor-arg>
<value>hsql</value>
</constructor-arg>
</bean>
</list>
</property>
<bean id="environment"
class="org.springframework.batch.support.SystemPropertyInitializer">
<property name="defaultValue" value="hsql"/>
</bean>
<!-- Use this to set additional properties on beans at run time -->
<bean id="overrideProperties" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"
depends-on="environment">
<property name="location" value="classpath:batch-${environment}.properties" />
<property name="location" value="classpath:batch-${org.springframework.batch.support.SystemPropertyInitializer.ENVIRONMENT}.properties" />
<!-- Allow system properties (-D) to override those from file -->
<property name="localOverride" value="true" />
<property name="properties">
@@ -47,18 +36,22 @@
<property name="ignoreInvalidKeys" value="true" />
<property name="order" value="2" />
</bean>
<bean id="placeholderProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
depends-on="environment">
<property name="location" value="classpath:batch-${environment}.properties" />
<property name="location" value="classpath:batch-${org.springframework.batch.support.SystemPropertyInitializer.ENVIRONMENT}.properties" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="order" value="1" />
</bean>
<bean id="lobHandler" class="${batch.lob.handler.class}" />
<bean id="incrementerParent" class="${batch.database.incrementer.class}">
<property name="dataSource" ref="dataSource" />
<property name="incrementerName" value="ID" />
</bean>
<!--import resource="alt-data-source-context.xml" /-->
</beans>

View File

@@ -18,10 +18,6 @@
<property name="jobRegistry" ref="jobRegistry"/>
</bean>
<!--
use p:databaseType="${environment}" below if auto-detection does not
work
-->
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager" />
@@ -37,7 +33,7 @@
<bean id="jobExplorer"
class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean"
p:databaseType="${environment}" p:dataSource-ref="dataSource" />
p:dataSource-ref="dataSource" />
<bean id="jobRegistry"
class="org.springframework.batch.core.configuration.support.MapJobRegistry" />

View File

@@ -15,7 +15,6 @@
<property name="jobRepository" ref="jobRepository" />
</bean>
<!-- use p:databaseType="${environment}" below if auto-detection does not work -->
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager" />
@@ -29,7 +28,7 @@
p:jobRegistry-ref="jobRegistry" />
<bean id="jobExplorer" class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean"
p:databaseType="${environment}" p:dataSource-ref="dataSource" />
p:dataSource-ref="dataSource" />
<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.ClassPathXmlJobRegistry" >
<constructor-arg value="jobs/skipSampleJob.xml" />

View File

@@ -34,30 +34,15 @@
construct a properties file on the classpath. The default is "hsql".
-->
<bean id="environment"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="java.lang.System" />
<property name="targetMethod" value="setProperty" />
<property name="arguments">
<list>
<value>environment</value>
<bean class="java.lang.System" factory-method="getProperty">
<constructor-arg>
<value>environment</value>
</constructor-arg>
<!-- The default value of the environment property -->
<constructor-arg>
<value>hsql</value>
</constructor-arg>
</bean>
</list>
</property>
class="org.springframework.batch.support.SystemPropertyInitializer">
<property name="defaultValue" value="hsql"/>
</bean>
<!-- Use this to set additional properties on beans at run time -->
<bean id="overrideProperties"
class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"
depends-on="environment">
<property name="location" value="classpath:batch-${environment}.properties" />
<property name="location" value="classpath:batch-${org.springframework.batch.support.SystemPropertyInitializer.ENVIRONMENT}.properties" />
<!-- Allow system properties (-D) to override those from file -->
<property name="localOverride" value="true" />
<property name="properties">
@@ -70,7 +55,7 @@
<bean id="placeholderProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
depends-on="environment">
<property name="location" value="classpath:batch-${environment}.properties" />
<property name="location" value="classpath:batch-${org.springframework.batch.support.SystemPropertyInitializer.ENVIRONMENT}.properties" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="order" value="1" />