Permalink
Browse files

Use Spring's Environment and PropertySource feature to inject configu…

…ration

Spring 3.1 introduced the Spring Environment, which provides a flexible way
to add additional property sources. This patch updates UniversalSpringCell
to inject our configuration into the context as property sources. This allows
us to get rid of dCache specific boilerplate in our Spring XML files.

Target: trunk
Require-notes: no
Require-book: no
Acked-by: Albert Rossi <arossi@fnal.gov>
Patch: http://rb.dcache.org/r/6536/
  • Loading branch information...
gbehrmann committed Feb 5, 2014
1 parent 47b841f commit b7234eeeb827edd86a9a520af9c4f4bdc7ed8e69
Showing with 113 additions and 233 deletions.
  1. +3 −5 modules/dcache-chimera/src/main/resources/diskCacheV111/namespace/pnfsmanager-chimera.xml
  2. +4 −6 modules/dcache-jms/src/main/resources/org/dcache/cells/amq-embedded.xml
  3. +4 −6 modules/dcache-jms/src/main/resources/org/dcache/cells/amq.xml
  4. +3 −5 modules/dcache-jms/src/main/resources/org/dcache/cells/cns-amq.xml
  5. +3 −5 modules/dcache-jms/src/main/resources/org/dcache/cells/cns-openmq.xml
  6. +3 −5 modules/dcache-jms/src/main/resources/org/dcache/cells/openmq.xml
  7. +3 −6 modules/dcache-jms/src/main/resources/org/dcache/services/topology/amq.xml
  8. +3 −5 modules/dcache-jms/src/main/resources/org/dcache/services/topology/openmq.xml
  9. +2 −7 modules/dcache-webdav/src/main/resources/org/dcache/webdav/webdav.xml
  10. +1 −5 modules/dcache-xrootd/src/main/resources/org/dcache/xrootd/door/xrootd.xml
  11. +54 −98 modules/dcache/src/main/java/org/dcache/cells/UniversalSpringCell.java
  12. +1 −5 modules/dcache/src/main/resources/diskCacheV111/poolManager/poolmanager.xml
  13. +1 −5 modules/dcache/src/main/resources/diskCacheV111/services/space/spacemanager.xml
  14. +1 −5 modules/dcache/src/main/resources/diskCacheV111/srm/srm.xml
  15. +5 −8 modules/dcache/src/main/resources/org/dcache/alarms/server/alarms.xml
  16. +4 −5 modules/dcache/src/main/resources/org/dcache/chimera/nfsv41/door/nfsv41-common.xml
  17. +3 −7 modules/dcache/src/main/resources/org/dcache/missingfiles/missingfiles.xml
  18. +2 −6 modules/dcache/src/main/resources/org/dcache/pinmanager/pinmanager.xml
  19. +1 −5 modules/dcache/src/main/resources/org/dcache/pool/classic/pool.xml
  20. +3 −7 modules/dcache/src/main/resources/org/dcache/services/billing/cells/billing.xml
  21. +1 −5 modules/dcache/src/main/resources/org/dcache/services/httpd/httpd.xml
  22. +1 −6 modules/dcache/src/main/resources/org/dcache/services/info/info.xml
  23. +3 −6 modules/dcache/src/main/resources/org/dcache/services/login/gplazma.xml
  24. +1 −5 modules/dcache/src/main/resources/org/dcache/services/ssh2/ssh2Admin.xml
  25. +3 −5 modules/dcache/src/main/resources/org/dcache/services/topology/classic.xml
@@ -1,13 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<description>Imported configuration data</description>
<property name="location" value="arguments:"/>
</bean>
<context:property-placeholder/>

<bean id="permission-handler"
class="org.dcache.namespace.ChainedPermissionHandler">
@@ -2,17 +2,15 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
http://activemq.apache.org/schema/core/activemq-core.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<description>Imported configuration data</description>
<property name="location" value="arguments:"/>
</bean>
<context:property-placeholder/>

<broker id="broker"
<broker id="broker"
xmlns="http://activemq.apache.org/schema/core"
brokerName="localhost" useJmx="false" persistent="false"
useShutdownHook="false">
@@ -2,17 +2,15 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
http://activemq.apache.org/schema/core/activemq-core.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<description>Imported configuration data</description>
<property name="location" value="arguments:"/>
</bean>
<context:property-placeholder/>

<amq:connectionFactory id="jmsFactory" brokerURL="${dcache.broker.amq.url}"/>
<amq:connectionFactory id="jmsFactory" brokerURL="${dcache.broker.amq.url}"/>

<bean id="tunnel" class="org.dcache.cells.JMSTunnel"
destroy-method="kill">
@@ -2,15 +2,13 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
http://activemq.apache.org/schema/core/activemq-core.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<description>Imported configuration data</description>
<property name="location" value="arguments:"/>
</bean>
<context:property-placeholder/>

<amq:connectionFactory id="connection-factory" brokerURL="${cns.broker.amq.url}"/>

@@ -1,13 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<description>Imported configuration data</description>
<property name="location" value="arguments:"/>
</bean>
<context:property-placeholder/>

<bean id="connection-factory"
class="org.dcache.cells.OpenMqConnectionFactoryFactory"
@@ -1,13 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<description>Imported configuration data</description>
<property name="location" value="arguments:"/>
</bean>
<context:property-placeholder/>

<bean id="connection-factory"
class="org.dcache.cells.OpenMqConnectionFactoryFactory"
@@ -2,18 +2,15 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:amq="http://activemq.apache.org/schema/core" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
http://activemq.apache.org/schema/core/activemq-core.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<description>Imported configuration data</description>
<property name="location" value="arguments:"/>
</bean>
<context:property-placeholder/>

<amq:connectionFactory id="connectionFactory" brokerURL="vm://localhost"/>

@@ -2,15 +2,13 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd">
http://www.springframework.org/schema/task/spring-task.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<description>Imported configuration data</description>
<property name="location" value="arguments:"/>
</bean>
<context:property-placeholder/>

<bean id="connection-factory"
class="org.dcache.cells.OpenMqConnectionFactoryFactory"
@@ -7,14 +7,9 @@
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<context:property-placeholder/>
<context:annotation-config/>

<bean id="properties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<description>Imported configuration data</description>
<property name="location" value="arguments:"/>
</bean>

<!-- Convert properties with multiple values separated by comma into an array of strings:
key=value1,value2,value3 : String[] {value1, value2, value3}
-->
@@ -296,7 +291,7 @@
<beans profile="missing-files-false">
<bean id="missing-file-strategy"
class="org.dcache.missingfiles.AlwaysFailMissingFileStrategy">
<description>configured behavour to always fail missing-files</description>
<description>configured behaviour to always fail missing-files</description>
</bean>
</beans>

@@ -7,13 +7,9 @@
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<context:property-placeholder/>
<context:annotation-config/>

<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<description>Imported configuration data</description>
<property name="location" value="arguments:"/>
</bean>

<!-- Convert properties with multiple values separated by comma into an array of strings:
key=value1,value2,value3 : String[] {value1, value2, value3}
-->
@@ -20,18 +20,17 @@
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;

import java.beans.PropertyDescriptor;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
@@ -48,7 +47,6 @@
import java.util.Formatter;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Queue;
import java.util.Set;
import java.util.TreeMap;
@@ -218,22 +216,7 @@ protected void executeInit()
/* Instantiate Spring application context. This will
* eagerly instantiate all beans.
*/
try {
_context =
new UniversalSpringCellApplicationContext(getArgs());
} catch (BeanInstantiationException e) {
Throwable t = e.getMostSpecificCause();
Throwables.propagateIfPossible(t);
String msg = "Failed to instantiate class " + e.getBeanClass().getName() +
": " + t.getMessage();
throw new CommandThrowableException(msg, t);
} catch (BeanCreationException e) {
Throwable t = e.getMostSpecificCause();
Throwables.propagateIfPossible(t);
String msg = "Failed to create bean '" + e.getBeanName() +
"' : " + t.getMessage();
throw new CommandThrowableException(msg, t);
}
createContext();

/* Cell threading is configurable through arguments to
* UniversalSpringCell. The executors have to be created as
@@ -1057,89 +1040,62 @@ public Object postProcessAfterInitialization(Object bean,
return bean;
}

class UniversalSpringCellApplicationContext
extends ClassPathXmlApplicationContext
private void createContext() throws CommandThrowableException
{
UniversalSpringCellApplicationContext(Args args)
{
super(args.argv(0));
}

private ByteArrayResource getArgumentsResource()
{
Args args = new Args(getArgs());
args.shift();

Properties properties = new Properties();
for (Map.Entry<String, Object> entry : _environment.entrySet()) {
properties.setProperty(entry.getKey(), entry.getValue().toString());
}
for (Map.Entry<String, String> option : args.optionsAsMap().entrySet()) {
properties.setProperty(option.getKey(), option.getValue());
}
String arguments =
args.toString().replaceAll("-\\$\\{[0-9]+\\}", "");
properties.setProperty("arguments", arguments);


/* Convert to byte array form such that we can make it
* available as a Spring resource.
*/
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
properties.store(out, "");
} catch (IOException e) {
/* This should never happen with a ByteArrayOutputStream.
*/
throw Throwables.propagate(e);
}
final byte[] _domainContext = out.toByteArray();

return new ByteArrayResource(_domainContext) {
/**
* Fake file name to make
* PropertyPlaceholderConfigurer happy.
*/
ClassPathXmlApplicationContext context;
Args args = getArgs();
try {
context = new ClassPathXmlApplicationContext();
context.setConfigLocations(new String[]{args.argv(0)});
context.addBeanFactoryPostProcessor(new BeanFactoryPostProcessor()
{
@Override
public String getFilename()
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{
return "arguments.properties";
}
};
}
beanFactory.addBeanPostProcessor(UniversalSpringCell.this); }
});

ConfigurableEnvironment environment = context.getEnvironment();
environment.getPropertySources().addFirst(
new MapPropertySource("environment", _environment));
environment.getPropertySources().addFirst(
new MapPropertySource("options", Maps.<String,Object>newHashMap(args.optionsAsMap())));
environment.getPropertySources().addFirst(
new PropertySource<Object>("arguments")
{
private final String arguments;

{
Args args = new Args(getArgs());
args.shift();
arguments = args.toString().replaceAll("-\\$\\{[0-9]+\\}", "");
}

@Override
public Resource getResource(String location)
{
if (location.startsWith("arguments:")) {
return getArgumentsResource();
} else {
return super.getResource(location);
@Override
public Object getProperty(String name)
{
return name.equals("arguments") ? arguments : null;
}
}
);
if (args.hasOption("profiles")) {
environment.setActiveProfiles(args.getOption("profiles").split(","));
}
context.refresh();
} catch (BeanInstantiationException e) {
Throwable t = e.getMostSpecificCause();
Throwables.propagateIfPossible(t);
String msg = "Failed to instantiate class " + e.getBeanClass().getName() +
": " + t.getMessage();
throw new CommandThrowableException(msg, t);
} catch (BeanCreationException e) {
Throwable t = e.getMostSpecificCause();
Throwables.propagateIfPossible(t);
String msg = "Failed to create bean '" + e.getBeanName() +
"' : " + t.getMessage();
throw new CommandThrowableException(msg, t);
}

@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory)
{
super.customizeBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(UniversalSpringCell.this);
}

@Override
public synchronized ConfigurableEnvironment getEnvironment() {
ConfigurableEnvironment environment = super.getEnvironment();

Args args = getArgs();

if(args.hasOption("profiles")) {
String[] profiles = args.getOption("profiles").split(",");

if(!Arrays.equals(profiles, environment.getActiveProfiles())) {
environment.setActiveProfiles(profiles);
}
}

return environment;
}
_context = context;
}
}
Oops, something went wrong.

0 comments on commit b7234ee

Please sign in to comment.