Saturday, July 7, 2012

Spring Custom Namespaces

Spring Custom Namespaces  provides a good way to simplify the xml files used to describe the bean definitions of a Spring Application Context. It is a fairly old concept, first introduced with Spring 2.0, but deserves being reviewed once in a while.

Consider a case of having to configure a part of the beans for a Spring MVC application without custom namespaces - this would typically look like this:


<bean name="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
 <property name="webBindingInitializer">
  <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
   <property name="conversionService" ref="conversionService"></property>
   <property name="validator">
    <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
   </property>
  </bean>
 </property>
 <property name="messageConverters">
  <list>
   <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean>
   <bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
   <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean>
   <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean>
   <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></bean>
   <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>
   <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
  </list>
 </property>
</bean>

<bean name="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
 <property name="useSuffixPatternMatch" value="false"></property>
</bean>

Here it is configuring two beans - a handlerAdapter to handle the MVC controller flow and a handlerMapping to keep the mapping between request URI's and the Controller methods to handle the requests.

The same configuration becomes very concise with a custom namespace, "http://www.springframework.org/schema/mvc" typically given a namspace prefix of "mvc":

<mvc:annotation-driven conversion-service="conversionService"> 
</mvc:annotation-driven> 

This is in essence the advantage of using a Custom namespace - a very concise way to describe the Spring bean definitions

So how does a custom namespace work:

This section in the Spring Reference document describes it much better than I can - http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/extensible-xml.html#extensible-xml-schema . To summarize it, a custom namespace has 4 parts to it:

  • the schema - which describes the structure of the custom namespace - the tag names, attributes, child tags etc.
  • a NamespaceHandler - which creates the bean definition for the xml elements. However typically a better mechanism suggested by Spring document is to extend NameSpaceHandlerSupport and to register a series of BeanDefinitionParser(s) for the different xml elements supported by the Custom namespace(say annotation-driven, interceptors elements of mvc namespace).
  • BeanDefinitionParser - create the bean definition for the specific element - here is where a line like <mvc:annotation-driven/> will be expanded to the broader bean definitions with actual bean class names.
  • Registering the schema, NamespaceHandler - This is for Spring to find the schema for the custom namespaces and to find the NamespaceHandler that will handle the custom namespace. The registration of the schema is done by a file called META-INF/spring.schemas, this is neat way for Spring to find the schema in the classpath rather than downloading the schema over the web. The NamespaceHandler is further specified using a META-INF/spring.handlers file and contains the NamespaceHandler name that will handle the custom namespace, for eg. from the Spring documentation - 
http\://www.mycompany.com/schema/myns=org.springframework.samples.xml.MyNamespaceHandler


Tying it together

This information of how the Custom namespace works internally can be put to good use to understand some of behavior of a few custom namepsace tags. Consider a tag to load up the properties file:
<context:property-placeholder location="classpath*:META-INF/spring/database.properties"/>
So to find how a property-placeholder element works internally, first find the spring.handlers file. Since property-placeholder is in the context namespace, the spring.handlers file will be present in the spring-context.jar file
and the file indicates that the NamespaceHandler is org.springframework.context.config.ContextNamespaceHandler

The ContextNameSpaceHandler registers a BeanDefinition parser called org.springframework.context.config.PropertyPlaceholderBeanDefinitionParser. This BeanDefinitionParser creates a bean definition with a class name of "PropertyPlaceholderConfigurer" and so essentially we could have replaced:
<context:property-placeholder location="classpath*:META-INF/spring/database.properties" local-override="true" properties-ref="localProperties"/>
with but losing conciseness in the process -
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
 <property name="location" value="classpath*:META-INF/spring/database.properties"></property>
 <property name="localOverride" value="true"></property>
 <property name="properties">
  <ref bean="localProperties"/>
 </property>
</bean>

This however provides a good way to understand some of the nuances of how Spring handles things underlying a custom namespace.


Sunday, July 1, 2012

Spring MVC Integration Tests

An approach to Integration Testing the controllers in Spring MVC is to use the Integration Test support provided by Spring.

With Junit4 this support consists of a custom Junit Runner called the SpringJunit4ClassRunner, and a custom annotation to load up the relevant Spring configuration.

A sample Integration test would be along these lines:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:/META-INF/spring/webmvc-config.xml", "contextcontrollertest.xml"})
public class ContextControllerTest {

    @Autowired
    private RequestMappingHandlerAdapter handlerAdapter;

    @Autowired
    private RequestMappingHandlerMapping handlerMapping;
    
    ......
 
 @Test
 public void testContextController() throws Exception{
  MockHttpServletRequest httpRequest = new MockHttpServletRequest("POST","/contexts");
  httpRequest.addParameter("name", "context1");
  
  httpRequest.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE,new FlashMap());
  MockHttpServletResponse response = new MockHttpServletResponse();
  Authentication authentication = new UsernamePasswordAuthenticationToken(new CustomUserDetails(..), null);
  SecurityContextHolder.getContext().setAuthentication(authentication);

  Object handler = this.handlerMapping.getHandler(httpRequest).getHandler();
  ModelAndView modelAndView = handlerAdapter.handle(httpRequest, response, handler);
  assertThat(modelAndView.getViewName(), is("redirect:/contexts"));
 }
}


I have used a MockHttpServletRequest to create a dummy POST request to a "/contexts" uri, and added some authentication details for Spring Security related details to be available in the Controller. The ModelAndView returned by the controller is being validated to make sure the returned view name is as expected.

A better way to perform a Controller related integration is using a relatively new Spring project called Spring-test-mvc , which provides a fluent way to test the controller flows. The same tests as above look like the following with Spring-test-mvc:
@Test
public void testContextController() throws Exception{
 Authentication authentication = new UsernamePasswordAuthenticationToken(new CustomUserDetails(..), null);
 SecurityContextHolder.getContext().setAuthentication(authentication);
 
 xmlConfigSetup("classpath:/META-INF/spring/webmvc-config.xml", "classpath:/org/bk/lmt/web/contextcontrollertest.xml").build()
  .perform(post("/contexts").param("name", "context1"))
  .andExpect(status().isOk())
  .andExpect(view().name("redirect:/contexts"));
}

The test has now become much more concise and there is no need to deal directly with a MockHttpServletRequest and MockHttpServletResponse instances and reads very well.

I have a little reservation about the amount of static imports and the number of function calls that are involved here, but again like everything else it is just a matter of getting used to this approach of testing.

One issue that I faced when implementing this controller test is that any resources that are required in the Spring context files from the WEB-INF location is not available in unit tests, so I moved all my Web related application context files from `/WEB-INF/spring` folder to the `META-INF/spring` folder in the classpath. Further, there were some beans that are heavily dependent on WEB-INF resources, for eg, tiles layouts, so I moved out the Tiles related beans to a separate Spring context file which are not imported as part of the Integration tests.
I have posted another blog entry with how spring-test-mvc supports loading web resources.

Friday, June 29, 2012

Stackoverflow personal milestone of 200 answers

I finally reached a personal milestone in Stackoverflow - answering 200 questions and 3000 reps. I have seen some people answer 2000+ questions, so this is not really a big deal, but it is personally very satisfying for me.

Wednesday, June 27, 2012

Spring Integration presentation at IndyJUG

I spoke on Spring Integration and Enterprise Integration patterns at the IndyJUG today. I thought the presentation was well received and I got some very good questions from the audience.

Here is my presentation:



And the sample project to go with the presentation: https://sites.google.com/site/bkscriptssite/home/scripts/sidemoproject.zip

Wednesday, June 20, 2012

Rube Goldberg Spring Integration

Spring Integration provides a very nice abstraction over some complexities involved with Integrating systems together - Spring Integration fits the definition of a Facade perfectly from an Integration perspective- something that provides a simplified access to a complicated underlying system.

To illustrate this point, consider a simple system, which just takes in a message, and sends it back capitalized, call it the Echo Gateway:

public interface EchoGateway { 
    String echo(String message);
}

and a test for this:
@Test
 public void testEcho() {
  String response = echoGateway.echo("Hello");
  assertThat(response, is("HELLO"));
 }


Sounds simple so far, an implementation using spring integration would take in the "message" and "transform" it by converting to its upper case and returning the enhanced message.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:beans="http://www.springframework.org/schema/beans"
 xsi:schemaLocation="
  http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  
  <channel id="requestChannel"/>
  
  <gateway id="echoGateway" service-interface="rube.simple.EchoGateway" default-request-channel="requestChannel" />
  
  <transformer input-channel="requestChannel" expression="payload.toUpperCase()" />  
  
</beans:beans>

Works beautifully!!


The beauty of Spring Integration is that even if the Integration scenario grows complex, the facade that it presents back to the application continues to remain simple,

Consider a Rube Goldberg integration scenario:

First a diagram to describe the convoluted flow:



So what exactly does it do:


  • It takes in a message of this type - "hello from spring integ",
  • splits it up into individual words(hello, from, spring, integ), 
  • sends each word to a ActiveMQ queue, 
  • from the queue the word fragments are picked up by a enricher to capitalize each word, 
  • placing the response back into a response queue, 
  • It is picked up, resequenced based on the original sequence of the words, 
  • aggregated back into a sentence("HELLO FROM SPRING INTEG") and 
  • returned back to the application.

This is how a Spring Integration configuration for this kind of flow would look like:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
 xmlns:beans="http://www.springframework.org/schema/beans"
 xsi:schemaLocation="
  http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
  http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
  http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms-2.1.xsd
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  
  <beans:import resource="broker.xml"/>

  <channel id="requestChannel">
   <queue/>  
  </channel>
  
  <channel id="responseChannel">
   <queue/>
  </channel>

  <gateway id="echoGateway" service-interface="rube.complicated.EchoGateway" default-request-channel="requestChannel" default-reply-channel="responseChannel" default-reply-timeout="5000" />
  
  <channel id="toJmsOutbound"/>
  
  <splitter input-channel="requestChannel" output-channel="toJmsOutbound" expression="payload.split('\s')">
  </splitter>
  
  <channel id="sequenceChannel">
  </channel>

  <int-jms:outbound-gateway request-channel="toJmsOutbound" reply-channel="sequenceChannel" request-destination="amq.outbound" extract-request-payload="true" />

  <channel id="enhanceMessageChannel"/>
  <channel id="toReplyQueueChannel"/>
  
  <int-jms:inbound-gateway request-channel="enhanceMessageChannel" request-destination="amq.outbound" reply-channel="toReplyQueueChannel"/>

  <transformer input-channel="enhanceMessageChannel" expression="(payload + '').toUpperCase()" output-channel="toReplyQueueChannel"/>
  
  <resequencer input-channel="sequenceChannel" output-channel="aggregateChannel" release-partial-sequences="false"></resequencer>
  
  <aggregator input-channel="aggregateChannel" output-channel="responseChannel"  expression="T(com.google.common.base.Joiner).on(' ').join(![payload].toArray())"/>
  
  <poller id="poller" fixed-delay="500" default="true"/>
  
</beans:beans>

There is so much complexity in this flow(hence the Rube Goldberg), however the facade that Spring Integration provides to the application continues to remain very simple.

@Test
 public void testEcho() throws Exception{
  String amessage = "Hello from Spring Integration";
  
  String response = echoGateway.echo(amessage);
  assertThat(response, is("HELLO FROM SPRING INTEGRATION"));
 }

This in my mind is the essence of Spring Integration

I have a github repository with this code at https://github.com/bijukunjummen/rg-si.git

Friday, June 15, 2012

Spring PropertySourcesPlaceholderConfigurer - overriding properties for tests

PropertySourcesPlaceholderConfigurer provides a good way to load in configuration from property files and populate the Spring bean definition property values. It is configured using a custom tag provided by Spring:

<context:property-placeholder location="classpath*:META-INF/spring/database.properties"/>

Say, for eg, if I had peristenceUnitName as a property loaded in from database.properties, I could use this property to configure my EntityManagerFactory:

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
    <property name="dataSource" ref="dataSource"/>
    <property name="persistenceUnitName" value="${persistenceUnitName}"></property>
</bean>

So, now I want to override the name of the persistence unit for running my tests. A reasonable solution would be to define another PropertySourcesPlaceholderConfigurer in the test context with a different value of the "persistenceUnitName", this will work if the test placeholder is loaded up BEFORE the main application context.

A better way to go about doing this is using a local-override flag of property-placeholder tag, what this indicates is that the local properties should have a higher precedence over the one's loaded from the file -

<context:property-placeholder location="classpath*:META-INF/spring/database.properties" local-override="true" properties-ref="localProperties"/>

<util:properties id="localProperties">
</util:properties>

I have provided a dummy localProperties above, just as a place holder.

So now, to override the desired properties in test, the only thing that needs to be done is to define a new localProperties bean this way:
<util:properties id="localProperties">
     <prop key="persistenceUnitName">TEST-tasksPersitenceUnit</prop>
</util:properties>

This I feel is a much cleaner approach to defining placeholder properties that are to be overridden in the tests.

Saturday, June 9, 2012

Creating a Java Dynamic Proxy

Java Dynamic proxy mechanism provides an interesting way to create proxy instances. The steps to create a dynamic proxy is a little tedious though, consider a proxy to be used for auditing the time taken for a method call for a service instance -

public interface InventoryService {
    public Inventory create(Inventory inventory);
    public List<Inventory> list();
    public Inventory findByVin(String vin);
    public Inventory update(Inventory inventory);
    public boolean delete(Long id);
    public Inventory compositeUpdateService(String vin, String newMake);
}

The steps to create a dynamic proxy for instances of this interface is along these lines:
1. Create an instance of a java.lang.reflect.InvocationHandler, this will be responsible for handling the method calls on behalf of the actual service instance, a sample Invocation handler for auditing is the following:
...
public class AuditProxy implements java.lang.reflect.InvocationHandler {

    private Object obj;

    public static Object newInstance(Object obj) {
        return java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
                .getClass().getInterfaces(), new AuditProxy(obj));
    }

    private AuditProxy(Object obj) {
        this.obj = obj;
    }

    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
        Object result;
        try {
            logger.info("before method " + m.getName());
            long start = System.nanoTime();
            result = m.invoke(obj, args);
            long end = System.nanoTime();
            logger.info(String.format("%s took %d ns", m.getName(), (end-start)) );
        } catch (InvocationTargetException e) {
            throw e.getTargetException(); 
        } catch (Exception e) {
            throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
        } finally {
            logger.info("after method " + m.getName());
        }
        return result;
    }
}

2. When creating instances of InventoryService, return a proxy which in this case is the AuditProxy, composing instances of InventoryService, which can be better explained using a UML:




This is how it would look in code:
InventoryService inventoryService = (InventoryService)AuditProxy.newInstance(new DefaultInventoryService());

Now, any calls to inventoryService will be via the AuditProxy instance, which would measure the time taken in the method while delegating the actual method call to the InventoryService instance.



So what are proxies used for:
1. Spring AOP uses it extensively - it internally creates a dynamic proxy for different AOP constructs
2. As in this example, for any class decoration - AOP will definitely be a better fit for such a use case though
3. For any frameworks needing to support interface and annotation based features - A real proxied instance need not even exist, a dynamic proxy can recreate the behavior expected of an interface, based on some meta-data provided through annotations.