Helena Edelson

Enterprise & Cloud Messaging | Spring | AMQP | RabbitMQ | Esper | CEP | CloudOps | Management & Monitoring | Security

  • Cloud

  • Topics

  • Archives



Simple Asynchronous Processing with Spring’s TaskExecutor

Posted by Helena Edelson on 27th January 2010

This post is merely meant as a starting guide to tinkering for a light-weight solution to handing off execution of a task for async processing without the overhead of Spring Batch or Spring JMS and Message Brokers, among other middleware solutions.

1. I have a simplistic junit test that merely kicks off the service method to view the path of execution:

/**
 * TaskTests
 *
 * @author Helena Edelson
 * @since v 1.0
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:infrastructure-context.xml"})
public class TaskTests extends BaseTest {
    protected static final Logger logger = Logger.getLogger(TaskTests.class);
    @Autowired private OrderService orderService;

    @Test
    public void testExecution(){
        logger.debug("Starting execution thread...");
        orderService.dispatch(new Order());
    }
}

2. A simple context config:

<?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”
xmlns:task=”http://www.springframework.org/schema/task”
xmlns:aop=”http://www.springframework.org/schema/aop”
xmlns:p=”http://www.springframework.org/schema/p”
xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd”>

<bean id=”taskExecutor” class=”org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor” p:corePoolSize=”5″ p:maxPoolSize=”25″/>

<!– OR alternately: Creates a org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor –>
<task:executor id=”taskExecutor” pool-size=”5-25″ queue-capacity=”100″ rejection-policy=”CALLER_RUNS”/>

</beans>

3. OrderService that delegates to the ThreadPoolTaskExecutor:

/**
 * OrderServiceImpl is used for both orders and returns
 *
 * @author Helena Edelson
 * @MessageEndpoint which is a @Component
 * @since Dec 29, 2009
 */
@Service("orderService")
public class OrderServiceImpl implements OrderService {
    private OrderDao orderDao;
    private MerchantService merchantService;
    private ReceivingService receivingService;
    @Autowired private TaskExecutor taskExecutor;

    @Autowired
    public OrderServiceImpl(OrderDao orderDao, ReceivingService receivingService, MerchantService merchantService) {
        this.orderDao = orderDao;
        this.receivingService = receivingService;
        this.merchantService = merchantService;
    }

    public final void dispatch(final Order order) {
        logger.debug("Starting dispatch execution...");

        if (this.taskExecutor != null) {
            this.taskExecutor.execute(new Runnable() {
                public void run() {
                    executorAsync(order);
                }
            });
        }

        logger.debug("Completed dispatch execution...");
    }

    private final void executorAsync(final Order order) {
        logger.debug("Starting Async execution...");

        daoDatasourceOne.createOrder(order);
        daoDatasourceTwo.createOrder(order);

        logger.debug("Completed Async execution...");
    }

/* Where the output will be: Note the dispatch method returns control to its caller before the async method begins:
2010-01-27 13:23:27,546 [main] DEBUG org.springsource.oms.infrastructure.TaskTests  - Starting execution thread...
2010-01-27 13:23:27,546 [main] DEBUG org.springsource.oms.domain.services.OrderServiceImpl  - Starting dispatch execution...
2010-01-27 13:23:27,546 [main] DEBUG org.springsource.oms.domain.services.OrderServiceImpl  - Completed dispatch execution...
2010-01-27 13:23:27,546 [taskExecutor-1] DEBUG org.springsource.oms.domain.services.OrderServiceImpl  - Starting Async execution...
persisting org.springsource.oms.domain.entities.Order@1f10a67
*/

/**
* Alternately for a different scenario you can play around with this:
*/
public void withExecutor(final Order order) {
        try {
            CompletionService completionService = new ExecutorCompletionService(taskExecutor);

            Object result1 = completionService.submit(new Callable() {
                public Object call() {
                    return daoDatasourceOne.createOrder(order);
                }
            });
            Object result2 = completionService.submit(new Callable() {
                public Object call() {
                    return daoDatasourceTwo.createOrder(order);
                }
            });

            completionService.take().get();
            completionService.take().get();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }
}

I recommend looking into the @Async annotation, which I will post on shortly. In the meantime here is the ref page for Spring Task and Scheduling: http://static.springsource.org/spring/docs/3.0.x/reference/html/scheduling.html

Share/Save/Bookmark

Posted in Annotations, Concurrency, Java, Spring, Spring Task | No Comments »

JMS ActiveMQ Broker Topologies and High-Availability Configuration

Posted by Helena Edelson on 22nd December 2009

Pure Master Slave BrokerTopology
Pure Master Slave Simplified Topology
I am not actually going to go into Broker topologies, there are many great resources for that such as this by Bruce Snyder: http://www.slideshare.net/bruce.snyder/messaging-with-activemq-presentation or http://activemq.apache.org/topologies.html, all great stuff. This example uses a store and forward topology, or, distributed queues, and incorporates basic authentication:

My use case was to handle down JMS Servers. What I needed to do was implement failover as well as master slave strategies and a topology for message redundancy in case of hardware failure, etc. The client could not have any message loss. With failover, you can see how ActiveMQ switches from the main broker to the second, third, etc on failure. I have a case of four JMS servers in production, each server it is on is load balanced.

There are just a few configurations to add or modify in order to set up JMS Failover with Master/Slave for your broker topology. Here is a basic configuration. For this use case, all JMS servers are configured as standalone versus embedded.

I. Client URI

You will need to add the Failover protocol, either with a basic URI pattern or a composite. In this use case, there are load balanced servers in Production and multiple Development and QA environments which require different configurations for master/slave and failover.

In your application’s properties file for messaging add a modified version of this with your mappings:
activemq.broker.uri=failover://(tcp://localhost:61616,tcp://slaveh2:61616,tcp://master2:61616,tcp://slave2:61616,network:static://(tcp://localhost:61616,tcp://master2:61616,tcp://slave2:61616))?randomize=false

Note: I set connections as locked down (static) communication configurations vs multicast or dynamic discovery so that I know exactly what servers can communicate with each other and how. Also this is assuming you have one set per environment to account for mapping the appropriate IP’s in development, qa, production, dr, etc.

Note: Do not configure networkConnections for master slave, they are handled on the slave with the following configuration:
<masterConnector remoteURI= "tcp://masterhost:61616" userName="wooty" password="woo"/>

II. Spring Configuration

<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.spring.ActiveMQConnectionFactory">
<constructor-arg value="${amq.broker.uri}"/>
<property name="userName" value="${activemq.username}"/>
<property name="password" value="${activemq.password}"/>
</bean>
</property
</bean>

III. Broker Configuration

Master

<broker brokerName="{hostname}" waitForSlave="true" xmlns="http://activemq.apache.org/schema/core" dataDirectory="${activemq.base}/data">
<networkConnectors>
<!-- passed in by the client broker URI so you can easily manager per environment: sweet -->
</networkConnectors>

<transportConnectors>
<!-- TCP uses the OpenWire marshaling protocol to convert messages to stream of bytes (and back) -->
<transportConnector name="tcp" uri="tcp://localhost:61616?trace=true" />
<transportConnector name="nio" uri="nio://localhost:61618?trace=true" />
<!-- <transportConnector name="ssl" uri="ssl://localhost:61617"/>
<transportConnector name="http" uri="http://localhost:61613"/
<transportConnector name="https" uri="https://localhost:61222"/> -->
<transportConnectors>
</transportConnectors>

<!-- Basic security and credentials -->
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="system" password="manager" groups="admin, publishers,consumers"/>
</users>
</simpleAuthenticationPlugin>
</plugins>

..more configuration
</broker>

Slave: for ActiveMQ 4.1 or later which also allows for authentication as show below

<broker brokerName="{hostname}Slave" deleteAllMessagesOnStartup="true" xmlns="http://activemq.apache.org/schema/core">
<transportConnectors>
<transportConnector uri="tcp://localhost:61616"/>
</transportConnectors>

<services>
<masterConnector remoteURI= "tcp://masterhost:62001" userName="wooty" password="woo"/
</services>
<!-- Basic security and credentials -->
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="system" password="manager" groups="admin, publishers,consumers"/>
</users>
</simpleAuthenticationPlugin>
</plugins>

</broker>

Share/Save/Bookmark

Posted in ActiveMQ, JMS, JMS Broker, Java, Messaging, Spring JMS | No Comments »

Application Configuration with Spring and Java Annotations

Posted by Helena Edelson on 25th July 2009

There is an ongoing debate about best practices for configuration management between XML with schema support versus Annotational meta data. I can make a valid argument either way, and I think the choice should be made on a case by case basis. But, is XML configuration so bad? I like using annotational configuration for things like Spring Web Services and Spring @MVC, where the configuration is specific to the method and arguments – where if you modify code you are likely to modify configuration. I also schema config with namespace support for cases where having a central area of configuration, easily maintainable, and keeping all code clean of meta data is preferred. One easy way to clean up necessary XML config is to use namespaces.

“Namespaces dramatically improve the Spring XML landscape
• More expressive, less verbose
• Just ask Spring Security where it’s 200+ lines of config went!”
- Chris Beams, Project Lead, Spring JavaConfig

Also with namespaces, in some cases the best practices configuration is already done for you and you can easily leverage convention over configuration to also reduce verbosity.

Item two in the list above is absolutely true. When you upgrade from Acegi Security to Spring Security, the configuration volume is night and day, and very cool. Perhaps they realized that if you required users to configure so many framework objects for one application layer such as security or messaging, you haven’t done a service to your users. They simply automatically register what amounts to best practices, letting the user override and add to the security context alternatively, as needed. Now that’s helpful.

So what about annotations? I am currently on large-scale enterprise migration project. Originally we made the decision to go with XML because the team was learning Java and Flex and we didn’t want to add Annotations to the mix for them. As the migrated application’s codebase is growing with domain logic, and in parallel its config files for business and framework services, I am moving toward Annotations at least in my own committed code. At first it was a, “Let’s not pollute and add dependencies in the code..” issue, and now it is a, “Component scanning, very cool.. automated registration … no config files to maintain and refactor” issue.

I am blogging not writing a thesis, so yes, there are more valid arguments which I leave for others, lets get to it and look at code. The main topics I’ll cover briefly are implementing JSR-250 Support, Spring’s @Autowired, Using Qualifiers, Component Scanning.

JSR-250 Support

Three of the total JSR-250 annotations defined in Java EE 5 which are out of the box in Java SE 6 are @Resource, @PostConstruct, and @PostDestroy. There are more in common-annotations.jar.

Enabling Spring’s JSR-250 support
This is as simple as implementing one of these two options in your application’s context.xml:

1. Old School
<bean class=“org.springframework.context.annotation.CommonAnnotationBeanPostProcessor”/>

2. Namespace, which offers greater functionalty than the above option:
<context:annotation-config/>

@Resource
You can implicitly are explicitly name your resource. This is implicit naming by property:
@Resource
private DataSource securityDataSource;

@Resource
public void setSecurityDataSource(DataSource sds) {
this.primaryDataSource = sds;
}

Alternatively, you can name by explicit meta data:

@Resource(name=“securityDataSource”)
private DataSource dataSource;

@Resource(name=“securityDataSource”)
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}

And if needed, you can disable type-matching fallback as well:

<bean class=“org.springframework.context.annotation.CommonAnnotationBeanPostProcessor”>
<property name=“fallbackToDefaultTypeMatch” value=“false”/>
</bean>

Spring

Lifecycle Annotations: @PostConstruct and @PreDestroy

In some of my framework services I use 2 of Spring’s Interfaces: InitializingBean, DisposableBean and their respective methods: afterPropertiesSet(), destroy().  Another option to implementing these non-programmatically is this method which I think makes the code much cleaner and less verbose:

@PostConstruct public void initialize() { // on post setter injection }


@PreDestroy public void doShutdown() { // on close context }

Yet another option is if you have a need for creating custom initialize and destroy annotations you can configure them like so:

<bean class=“org.springframework.context.annotation.CommonAnnotationBeanPostProcessor”>
<property name=“initAnnotationType” value=“com.edelsonmedia.infrastructure.annotations.Initialize”/>
<property name=“destroyAnnotationType” value=“com.edelsonmedia.infrastructure.annotations..Destroy”/>
</bean>

which is cool because I like writing annotations for increased customization.

@Autowired

@Autowired is a dependency resolver acting on type which acts on fields, methods, and constructors. There are no method naming convention restrictions and multiple parameters are accepted.

In Spring 2.5, using the context namespace with <context:annotation-config/> automatically enables the @Autowired annotation.

Field injection:
@Autowired private DataSource dataSource;

Setter Injection:
@Autowired public void setDataSource(DataSource dataSource){...}

Constructor Injection:
@Autowired public ObjectRepository(DataSource dataSource){...}

Method Injection:
@Autowired public doSetup(DataSource dataSource, Company company) {...}

Attributes for further configuration:
This distinguishes an optional property but note that if there are more than one matches found this will fail:
@Autowired(required=false)
private SomeObject obj;

This configures a primary candidate from the other types:
<bean id=“dataSource” primary=“true” class=“org.apache.commons.dbcp.BasicDataSource” … />
<bean id=“backupDataSource” class=“org.apache.commons.dbcp.BasicDataSource” … />



@Qualifier
The @Qualifier annotation is scoped for field, constructor arg and method parameters. This annotation offers named matching functionality to the @Autowired annotation, finer granularity for autowire candidate resolution, and an extension point for custom autowiring qualifiers, which I will show below:

Field Injection
@Autowired
@Qualifier(“primaryDataSource”)
private DataSource dataSource;

Setter Injection
@Autowired
public void setDataSource(@Qualifier(“securityDataSource”)
DataSource dataSource) {
this.dataSource = dataSource;
}

Constructor Injection
@Autowired
public void setup(@Qualifier(“securityDataSource”)
DataSource dataSource, SomeObject obj) {
this.dataSource = dataSource;
this.obj = obj;
}

Multiple Parameter Method Injection
@Autowired
public AbstractedRepository(@Qualifier(“securityDataSource”)
DataSource dataSource) {
this.dataSource = dataSource;
}

@Qualifier As Meta-Annotation for Extended or Custom Qualifiers

Define it:
@Qualifier
public @interface VMLoaded { … }

Now use the annotation with @Autowired:
@Autowired
@VMLoaded /* If the annotation provides meaning as is, no value necessary */
private BootrapManager bootstrapManager;

If you want to register a custom annotation without using @Qualifier as meta-annotation:

<bean class=“org.springframework.beans.factory.annotation.CustomAutowireConfigurer”>
<property name=“customQualifierTypes”>
<set>
<value>org.example.Online</value>
<value>org.example.Offline</value>
</set>
</property>
</bean>

You can define attributes with custom qualifiers A value attribute can match against a bean name just like it does for @Qualifier
@Qualifier
public @interface CompanyCatalog {
String company();
int type();
...etc
}

Attributes can resolve against XML metadata or class-level annotation metadata
@Category(company=“someCompany”, type=“principle”)
public class CompanyCatalog implements Catalog {
//… etc
}

Stereotype Annotations

@Component – a generic component
@Repository – a repository (DAO)
@Service – a stateless service of idempotent operations
@Controller – an MVC controller

All auto-detected components are implicitly named from the non-qualified class name. This:
@Controller
public class AController { … }

is equivalent to:

<bean id=“aController” class=“org.foo.web.controller.AController”/>

You can set the generated name explicitly, where this:
@Controller(“aCatalog”)
public class AController { … }

is equivalent to:
<bean id=“aCatalog”
class=“org.foo.web.controller.AController”/>

So that whole services-config.xml file you may have that grows and grows now can be migrated to annotations in your classes, and you can delete the config file.

Component Scanning
In Spring 2.5, they included a new class, ClassPathBeanDefinitionScanner, which accepts packages passed in as arguments, and detects any class with declared stereotypes in the path while scanning the base package and its sub-packages. Using component scanning is easy. Simply add the context namespace to your main schema config and add:

<context:component-scan base-package=“org.foo”/>

Now you are set to customize the component scanner if needed. Using the @Component stereotype declared on a custom annotation, you can then decorate any class with that annotation simply by the above configuration addition and:

@Component
public @interface MyAnnotation{ ... }


@MyAnnotation
public class MyClass { ... }

But what if you need to filter the package scanning? Below demonstrates how to include components with custom filters, and the assignable, aspectj and regex filters:

<context:component-scan base-package=“org.foo”>
<!-- custom filter -->
<context:include-filter type=“annotation” expression=“foo.Bar”/>
<context:include-filter type=“assignable” expression=“foo.Baz”/>
<context:include-filter type=“aspectj” expression=“foo..*Service”/>
<context:include-filter type=“regex” expression=“foo\.B[a-z]+”/>
</context:component-scan>

For further customization, you can disable default filters or stereotypes and exclude filters

<context:component-scan base-package=“org.example.web” use-default-filters=“false”>
<context:include-filter type=“annotation” expression=“foo.Bar”/>
<context:include-filter type=“aspectj” expression=“foo..*Service”/>
<context:exclude-filter type=“assignable” expression=“foo.Bad”/>
</context:component-scan>

Scoping Components
As with bean definition in xml, the default scope is singleton. To provide any other scope, add the @Scope annotation:

@Controller
@Scope(“prototype”)
public class MyController { … }

@MyController
@Scope(“session”)
public class SomeWebComponent { … }

Best Practices
So in conclusion, you can you annotations and XML configuration together and leverage the best of both within one application context. Here are some thoughts from Juergen Hoeller, a Principle engineer at SpringSource, on the topic:
Annotation metadata is in the code

  • Pro: facilitates refactoring
  • Con: forces recompilation

XML externalizes the configuration

  • Pro: configuration is not scattered
  • Con: XML is verbose

Find out more: JSR_250 spec

Share/Save/Bookmark

Posted in Annotations, Application Cofiguration, Configuration Management, Flex, JMS, Java, Software Development, Spring | No Comments »

Spring BlazeDS Integration

Posted by Helena Edelson on 19th December 2008

I went through the reference docs and quickly set up a basic implementation using Livecycle Data Services and one thing quickly occurred to me just in reading the docs:

Here is an easy test drive from Christophe at Adobe.

I hope I am not taking the statement, “the FlexRemotingServiceExporter will be able to work transparently..” out of context but the sample below from the reference docs adds a layer of complexity to spring configuration. Example: I have 100 java services wrapping dao’s etc, configured in Spring, plus their flex handler services to pipe the remoting calls. Wrapping each service in a FlexRemotingServiceExporter adds to configuration mayhem. Could we simply declare the FlexRemotingServiceExporter, annotate the services as @RemoteService or new similar type of annotation that wires it to FlexRemotingServiceExporter as a wrapper, where it does its job allowing dynamic creation of remoting destinations? But by the sample below it would add a lot of overhead to massive enterprise apps such as the one I am currently working on. We are partnering with Adobe on our framework, and I had just proposed to write a Spring Extension for this when 2 weeks later read the press release, so I look forward to seeing this module develop.

From: Spring BlazeDS Integration Reference Guide

Code:
<!-- Expose the productService bean for BlazeDS remoting -->
<bean id="product" class="org.springframework.flex.messaging.remoting.FlexRemotingServiceExporter">
    <property name="messageBroker" ref="mySpringManagedMessageBroker"/>
    <property name="service" ref="productService"/>
</bean>

Would it help to set a parent a bean and save the implementors from adding the wrapper to each?

Code:
<bean name="fxExporter" abstract="true" "class="org.springframework.flex.messaging.remoting.FlexRemotingServiceExporter">
     <property name="messageBroker" ref="mySpringManagedMessageBroker"/>
</bean>

and then set
<bean id="product" parent="fxExporter" class="org.springframework.flex.messaging.remoting.FlexRemotingServiceExporter">
    <property name="service" ref="productService"/>
</bean>

I know this is just the first foundation release so this is just a suggestion (cutting down on configuration as you can already do dynamic destinations for java-flex at present). What i AM looking forward to is the JMS module with Flex Messaging. I’ve got this working now with Flex -Livecycle Data Services – AMQ – JMS, and hope this module will simplify implementations going forward.

Share/Save/Bookmark

Posted in BlazeDS & LCDS, Flex, Spring | Comments Off

SpringSource First Milestone of Spring BlazeDS Released

Posted by Helena Edelson on 18th December 2008

SpringSource released its first Milestone for Spring and BlazeDS, the free version of Adobe’s LCDS

“This first milestone is very much a foundational release, focusing on support for configuring and bootstrapping the BlazeDS MessageBroker (the central component that handles incoming messages from the Flex client) as a Spring-managed object, routing HTTP messages to it through the Spring DispatcherServlet infrastructure, and easily exporting Spring beans as destinations for direct Flex remoting. Future milestones leading up to the final 1.0 will build upon this foundation to provide deeper features such as Spring Security integration, messaging integration using Spring’s JMS support, an AMFView for use in conjunction with Spring 3.0’s REST support, and hopefully further things to address the needs of our community that we haven’t thought of yet.” – Jeremy Grelle, SpringSource

More info: http://www.springsource.org/node/904

Reference Docs http://static.springframework.org/spring-flex/docs/1.0.x/reference/html/index.html

I’ve been developing framework for messaging with Flex, Livecycle Data Services, Java and JMS and will give this first release a test run

Share/Save/Bookmark

Posted in BlazeDS & LCDS, Flex, Software Development, Spring | No Comments »

SpringOne 2008

Posted by Helena Edelson on 3rd December 2008

Day 2 of SpringOne Americas – new name same great show. This year is all about osgi, dm server, tc server. One thing I like is talking with developers from around the world to see how they chose to solve issues we all face (minus unique constrains) and to talk about new tools and hear feedback.

I met with the CEO of Terracotta (I think it was him, Ari) who was very helpful in explaining an overview of how their clustering software works and some options for how to configure it also with JMS clustering (with ActiveMQ and without a JMS provider, insterestingly).

Later today I will meet with Bruce Snyder, a senior engineer at SpringSource, to talk about Spring, JMS, and ActiveMQ configurations and I hope to grab Jeremy Grelle tomorrow to see what he has to say about clustering Adobe’s Live Cycle Data Services (also to connect w JMS, clustered or per load balanced app server).

I also need to talk with someone from Spring Batch to clarify boundaries on when you need it and when you can go with just Spring / Quartz scheduling.

One of my favorite sessions with Juergen Hoeller’s on Spring 3.0, very interesting, I’ll add a link about that later, as well as Spring Integration with Mark Fisher. I will add a follow up on that, another interesting idea of when you use that with JMS and can you cut out JMS in some cases with Spring Integration.

Share/Save/Bookmark

Posted in Spring | Comments Off

Configuring JMS in Spring

Posted by Helena Edelson on 21st July 2008

When initially looking into implementation strategies for building a JMS framework component into an enterprise application, it took quite a while to sort out what elements were necessary. From there, I began looking into what the configuration options were. What follows are the key components of my first JMS implementation with Spring 2.5x, Java 1.6x. Note that this is for a client that while were were using the latest java sdk, we were deliberately introducing annotations slowly. I started with annotations in java, Spring, and JUnit for creating a parent test that rolled back database state after method execution and transaction completion. The core developers were new to Java, so we kept all spring config files as schema, and I based my configurations, even for AOP, as mostly non annotational for now. Although I have written a SystemArchitecture.java for design-level assertions, it will not be implemented for at least a year :) too bad because it’s fun stuff.

<?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:p=”http://www.springframework.org/schema/p”
xmlns:jms=”http://www.springframework.org/schema/jms”
xmlns:amq=”http://activemq.apache.org/schema/core”
xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-2.5.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd
http://activemq.apache.org/camel/schema/spring http://activemq.apache.org/camel/schema/spring/camel-spring.xsd”>

…this post is in process…more soon

Share/Save/Bookmark

Posted in Java, Spring, Spring JMS | No Comments »

Dynamically Change Databases At Runtime

Posted by Helena Edelson on 24th May 2008

This is a common issue to solve and there are many solutions to every problem of course.
One solution for this problem is:

This example uses IBATIS which can easily be migrated for Hibernate

1. Set environment variables

2. Create a different set of property files such as

    1. /properties/production/database.properties
    2. /properties/qa/database.properties
    3. …and so forth

3. Set environment variables and create a class like SampleProperties.java that checks things such as required env variables, etc

public Class SampleProperties {
private static SampleProperties ourInstance = new SampleProperties();

public static SampleProperties getInstance() {
return ourInstance;
}

private SampleProperties() { }

public boolean isEnvProduction() {
if ((SYS_ENV != null) && (SYS_ENV.equals(PRODUCTION))) {
return true;
}
return false;
}

public boolean isEnvDevelopment() {
if ((SYS_ENV != null) && (SYS_ENV.equals(DEV1))) {
return true;
}
return false;
}
//… and so forth for other environments/servers, and other application properties

public void setSYS_ENV(String newSYS_ENV) {
if (SYS_ENV != null) {
logger.error(“Error – SYS_ENV can only be set once on startup!”);
return;
}
SYS_ENV = newSYS_ENV;
}

public String getSYS_ENV() {
return SYS_ENV;
}
}

Now you can call this class in your services

  if (SampleProperties.getInstance().isDevelopment())  doSomethingRelevant();

But the real juice is this

4. Configure multiple datasources in Spring. Here is one example
dataSourceConfig.xml

autowire-candidate=”false” id=”aDataSource” class=”com.foo.databaseUtils.MyProxyDataSource” destroy-method=”close” p:driverClassName=”${jdbc.driverClassName}”
p:url=”${jdbc.url}”
p:username=”${jdbc.username}”
p:password=”${jdbc.encrypted.password}”
p:defaultCatalog=”${jdbc.defaultCatalog}”/>

5. Configure as many of these as needed, then to actually put it into practice: through the framework’s abstractions, wire datasource A into one instance of a dao in my service, and wire datasource B into a second instance of the same dao like so:

<bean id="aSqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"
      p:configLocation="classpath:SqlMapConfig.xml">
      <property name="aDataSource" ref="aDataSource"/>
</bean>
<bean id="bSqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"
     p:configLocation="classpath:SqlMapConfig.xml">
     <property name="bDataSource" ref="bDataSource"/>
</bean>

6. dao.xml: Now some magic…

<!-- ******************* DAO PARENTS ******************* -->
<bean id="aSqlMapService" abstract="true" class="com.foo.databaseUtils.SampleClientDaoSupport">
      <property name="aSqlMapClient" ref="aSqlMapClient"/>
      <property name="simpleSqlMapClient" ref="simpleSqlMapClient"/>
</bean>
<bean id="bSqlMapService" abstract="true" class="com.foo.databaseUtils.SampleClientDaoSupport">
     <property name="bSqlMapClient" ref="bSqlMapClient"/>
</bean>

7. services.xml: To your services Spring config file, configure 2 dao’s each dao now injected with multiple data sources able to be set at runtime:

<bean id="sampleService" class="com.foo.services.SampleService">
          <property name="aSampleDAO">
                <bean parent="aSqlMapService" class="com.foo.dao.SampleDAO"/>
          </property>
          <property name="bSampleDAO">
               <bean parent="bSqlMapService" class="com.foo.dao.SampleDAO"/>
         </property>
</bean>

8. Here is a service, now injected with multiple dao’s of the same type yet with differing data sources.

Note: the business service interface is used as the transaction management interface declared in the tx AOP pointcut

public class SimpleService implements BusinessService, ISimpleService</strong> {
    SampleDAO aSampleDAO;
    SampleDAO bSampleDAO;
    /**
     * This method tests for, sets, and returns the appropriate dao.
     * One instance is wired with datasource A, the other with datasource B
     */
    public SampleDAO getDatasource(Criteria criteria){
         return someCriteria.someEvaluator(criteria)) ? aSampleDAO : bSampleDAO;
    }
/* Example method using changing datasources at runtime */
 public Object getImportantData(Date date) throws DataAccessException {
     return getDatasource(date).getImportantDataFromDAO(date);
}

It is dicey when you push to servers – you have to insure checkpoints in your system that the environment variables exist and are correct. Put it in your deploy script, or other solution with a fail on false plus notification of failure. You could have a system.properties file in /home/someuser on app server boxes and have the app read from there, but again, you have the issue of how to keep that file under version control…

Share/Save/Bookmark

Posted in Java, Spring | No Comments »