Wednesday, May 22, 2013

Spring Integration File Polling and Tests

I recently implemented a small project where we had to poll a folder for new files and then trigger a service flow on the contents of the file.

Spring Integration is a great fit for this requirement as it comes with a channel adapter that can scan a folder for new files and then take the file through a messaging flow.

The objective of this specific article is to go over how a file poller flow can be tested.

To start with consider a simple flow implemented using the following Spring integration configuration:

<beans:beans xmlns="http://www.springframework.org/schema/integration"
    .....
 <channel id="fileChannel"></channel>
 <channel id="processedFileChannel"></channel>

 <int-file:inbound-channel-adapter directory="${inbound.folder}" channel="fileChannel" filename-pattern="*.*">
  <poller fixed-delay="5000"></poller>
 </int-file:inbound-channel-adapter>
 
 <service-activator input-channel="fileChannel" ref="fileHandlerService" method="handle" output-channel="processedFileChannel">
 </service-activator>
 
 <logging-channel-adapter id="loggingChannelAdapter" channel="processedFileChannel"></logging-channel-adapter>
 
 <beans:bean name="fileHandlerService" class="files.RealFileHandlingService"/>
 <context:property-placeholder properties-ref="localProps" local-override="true"/>
 
 <util:properties id="localProps">
 </util:properties>
</beans:beans>

This is better represented in a diagram:



Simple Testing of the flow

Now to test this flow, my first approach was to put a sample file into a folder in the classpath, dynamically discover and use this folder name during test and to write the final message into a test channel and assert on the messages coming into this channel. This is how the test configuration which composes the original Spring config looks like:

<beans:beans xmlns="http://www.springframework.org/schema/integration"
    ....
 <beans:import resource="si-fileprocessing.xml"/>
 <util:properties id="localProps">
  <beans:prop key="inbound.folder">#{new java.io.File(T(java.io.File).getResource("/samplefolder/samplefile.txt").toURI()).parent}</beans:prop>
 </util:properties>
 <channel id="testChannel">
  <queue/>
 </channel>
 
 <bridge id="loggingChannelAdapter" input-channel="processedFileChannel" output-channel="testChannel"></bridge>
</beans:beans>

and the test looks like this:
@Autowired @Qualifier("testChannel") PollableChannel testChannel;

@Test
public void testService() throws Exception{
 Message<?> message = this.testChannel.receive(5000);
 assertThat((String)message.getPayload(), equalTo("Test Sample file content"));
}

This works neatly, especially note that the path can be entirely provided in the configuration using a Spring-EL expression :
#{new java.io.File(T(java.io.File).getResource("/samplefolder/samplefile.txt").toURI()).parent}

Mocking out the Service

Now, to take it a little further, what if I want to mock the service that is processing the file (files.RealFileHandlingService). There is an issue here which will become clear once the mock is implemented. An approach to injecting in a mock service is to use Mockito and a helper function that it provides to create a mock this way using Spring configuration file:

<beans:bean name="fileHandlerService" factory-method="mock" class="org.mockito.Mockito">
 <beans:constructor-arg value="files.FileHandlingService"></beans:constructor-arg>
</beans:bean>

Once this mock bean is created, the behavior for the mock can be added in the @Before annotated method of junit, this way:

@Before
public void setUp() {
 when(fileHandlingServiceMock.handle((File)(anyObject()))).thenReturn("Completed File Processing");
}

@Test
public void testService() throws Exception{
 Message<?> message = this.testChannel.receive(5000);
 assertThat((String)message.getPayload(), equalTo("Completed File Processing"));
}

If the test is repeated now, surprisingly it will fail and the reason is - Spring application context is fully initialized by the time the call comes to the @Before method of Junit and the poller scanning the file coming into the folder gets triggered BEFORE the mock behavior is added on and so without the correct behavior of the mock service the test fails.

I am sure there are other fixes, but the fix that worked for me was to essentially control which folder is scanned and at what point the file is placed in the folder for the flow to be triggered. This is heavily based on some tests that I have seen in Spring Integration project itself. The trick is to create a temporary folder first using Spring config and set that folder as the polling folder:
<beans:bean id="temp" class="org.junit.rules.TemporaryFolder"
   init-method="create" destroy-method="delete"/>

<beans:bean id="inputDirectory" class="java.io.File">
 <beans:constructor-arg value="#{temp.newFolder('sitest').path}"/>
</beans:bean> 

<util:properties id="localProps">
 <beans:prop key="inbound.folder">#{inputDirectory.getAbsolutePath()}</beans:prop>
</util:properties>

Now place the file in the temporary folder only during the test run, this way @Before annotated method gets a chance to add behavior to the mock and the mocked behavior can be cleanly asserted:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("si-test.xml")
public class FileHandlingFlowTest {
 @Autowired @Qualifier("testChannel") private PollableChannel testChannel;
 @Autowired private FileHandlingService fileHandlingServiceMock;
 @Autowired @Qualifier("inputDirectory") private File inputDirectory;
 
 @Before
 public void setUp() {
  when(fileHandlingServiceMock.handle((File)(anyObject()))).thenReturn("Completed File Processing");
 }
 
 @Test
 public void testService() throws Exception{
  Files.copy(new File(this.getClass().getResource("/samplefolder/samplefile.txt").toURI()), new File(inputDirectory, "samplefile.txt"));
  Message<?> message = this.testChannel.receive(5000);
  assertThat((String)message.getPayload(), equalTo("Completed File Processing"));
 }
}

Sunday, April 28, 2013

Spring beans with same name and @Configuration

One of the important features when testing an application is being able to replace some of the real services with test doubles. With a Spring based application, this has typically been done by defining the test doubles with the same name as the original bean which is being mocked out and this works as the bean defined later is the one which is finally instantiated by the Spring container.

Consider a bean, call it memberService bean, having two implementations one defined using XML based bean definition files say in a context1.xml file:

<bean name="memberService" class="samples.config.MemberSvcImpl1"/>

and if a different implementation of memberService is needed for test, the way to do it would have been to define the bean with the same name, this way(say in a context2.xml file):

<import resource="context1.xml"/>
<bean name="memberService" class="samples.config.MemberSvcImpl2"/>

since the MemberSvcImpl2 is defined after MemberSvcImpl1, the MemberSvcImpl2 would be available for injection in tests.


However with @Configuration style of defining beans, things are not so clear cut. What does it mean to define a bean after another bean, consider the following which tries to mimic the definition in context2.xml file above:

@Configuration
@ImportResource("classpath:samples/config/context1.xml")
public class Context2Config {
 @Bean
 public MemberService memberService() {
  return new MemberSvcImpl2();
 }
}

Here the memberService defined in the @Configuration DOES NOT override the memberService bean defined in the xml. Something to be careful about.

The solution is actually simple - if you need to override a previously defined bean(without say the flexibility of autowiring with a different bean name), either use the XML bean configuration for both the bean being overridden and the overriding bean or use the @Configuration. XML bean configuration is the first example in this entry, the one with @Configuration would be something like this:

@Configuration
public class Context1JavaConfig {
 @Bean
 public MemberService memberService() {
  return new MemberSvcImpl1();
 }
}

@Configuration
@Import(Context1JavaConfig.class)
public class Context2JavaConfig {
 @Bean
 public MemberService memberService() {
  return new MemberSvcImpl2();
 }
}

This would work as expected. I am sure there are alternate ways of getting this to work, but the approach that I have outlined here has worked well for me and I have been sticking to this pattern

Friday, March 1, 2013

Test Fixtures - Using Spring scala

Continuing on my previous blog entry about creating test fixtures using Spring XML bean configuration file and the newer Spring @Configuration style, this time around I wanted to see how the same configuration turns out using the new Spring Scala project.

So this is what I had as a test fixture defined using xml bean configuration earlier:

<?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:c="http://www.springframework.org/schema/c"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

 <bean name="address1" class="el.Address" c:city="City1" c:state="State1"/>
 <bean name="address2" class="el.Address" p:city="City2" p:state="State2"/>
 <bean name="address3" class="el.Address" p:city="City3" p:state="State3"/>
 <bean name="address4" class="el.Address" p:city="City4" p:state="State4"/>
 <bean name="address5" class="el.Address" p:city="City5" p:state="State5"/>

 <bean name="member1" class="el.Member" c:first="First1" c:last="Last1" c:address-ref="address1"/>
 <bean name="member2" class="el.Member" p:first="First1" p:last="Last1" p:address-ref="address2"/>
 <bean name="member3" class="el.Member" p:first="First1" p:last="Last1" p:address-ref="address3"/>
 <bean name="member4" class="el.Member" p:first="First1" p:last="Last1" p:address-ref="address4"/>
 <bean name="member5" class="el.Member" p:first="First1" p:last="Last1" p:address-ref="address5"/>
 
</beans>

and using Java @Configuration:

@Configuration
public class FixturesJavaConfig {
 @Bean public Address address1(){return new Address("city1", "state1");}
 @Bean public Address address2(){return new Address("city2", "state2");}
 @Bean public Address address3(){return new Address("city3", "state3");}
 @Bean public Address address4(){return new Address("city4", "state4");}
 @Bean public Address address5(){return new Address("city5", "state5");}

 @Bean public Member member1(){return new Member("first1", "last1", address1());}
 @Bean public Member member2(){return new Member("first2", "last2", address1());}
 @Bean public Member member3(){return new Member("first3", "last3", address1());}
 @Bean public Member member4(){return new Member("first4", "last4", address1());}
 
 @Bean public Member member5(){
  Member member = new Member();
  member.setFirst("first5");
  member.setLast("last5");
  member.setAddress(address5());
  return member;
 }
}


Now, using Spring scala the bean configuration is the following:

import org.springframework.scala.context.function.FunctionalConfiguration

class MemberConfiguration extends FunctionalConfiguration {
  val address1 = bean() { new Address("city1", "state1") }
  val address2 = bean() { new Address("city2", "state2") }
  val address3 = bean() { new Address("city3", "state3") }
  val address4 = bean() { new Address("city4", "state4") }
  val address5 = bean() { new Address("city5", "state5") }

  bean("member1") { new Member("first1", "last1", address1()) }
  bean("member2") { new Member("first2", "last2", address2()) }
  bean("member3") { new Member("first3", "last3", address3()) }
  bean("member4") { new Member("first4", "last4", address4()) }
  bean("member5") {
    val member = new Member()
    member.setFirst("first5");
    member.setLast("last5");
    member.setAddress(address5());
    member
  }
}

The fixture configuration does look very clean and concise and I would definitely be looking out for the spring-scala project as it matures a little more - a few things which will need to be implemented are a way for bootstrapping this configuration with Spring based tests(through @ContextConfiguration), way to import this configuration into normal xml based bean configurations and into java based @Configurations.
For Scala only projects the Spring Scala project does look very promising.

Finally, this is a test for the "FunctionalConfiguration" above:

import org.scalatest.FunSuite
import org.springframework.scala.context.function.FunctionalConfigApplicationContext
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
@RunWith(classOf[JUnitRunner])
class MemberConfigTest extends FunSuite {
  test("there should be 5 members in the configuration") {
    val applicationContext = new FunctionalConfigApplicationContext(classOf[MemberConfiguration])
    val members = applicationContext.getBeansOfType(classOf[Member])
    assert(members.size() === 5)
  }
}

Friday, February 22, 2013

Test fixtures - using XML Spring bean definition vs Java Configuration

Spring's Java based container configuration is a neat way of specifying Spring bean configurations and in my own projects I have systematically replaced XML configuration with Java Bean configuration where feasible.

However, there are still a few places where an XML bean configuration is a better fit than the Java Configuration, here I am focusing on one such use case.

Consider a test case which requires a fixture with a lot of test instances of domain classes, assume a simple domain of a Member(a person) with an address. This would be expressed the following way using a Spring XML configuration:

<?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:c="http://www.springframework.org/schema/c"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

 <bean name="member1" class="el.Member" c:first="First1" c:last="Last1" c:address-ref="address1"/>
 <bean name="member2" class="el.Member" p:first="First1" p:last="Last1" p:address-ref="address2"/>
 <bean name="member3" class="el.Member" p:first="First1" p:last="Last1" p:address-ref="address3"/>
 <bean name="member4" class="el.Member" p:first="First1" p:last="Last1" p:address-ref="address4"/>
 <bean name="member5" class="el.Member" p:first="First1" p:last="Last1" p:address-ref="address5"/>
 
 <bean name="address1" class="el.Address" c:city="City1" c:state="State1"/>
 <bean name="address2" class="el.Address" p:city="City2" p:state="State2"/>
 <bean name="address3" class="el.Address" p:city="City3" p:state="State3"/>
 <bean name="address4" class="el.Address" p:city="City4" p:state="State4"/>
 <bean name="address5" class="el.Address" p:city="City5" p:state="State5"/>
</beans>




The good thing about this configuration is that it is very easy to see the list of entities with Spring's c (constructor) and p(property) custom xml namespaces allowing a very concise expression.

On the other hand if the same fixture had been created through Java Configuration it would be a little more verbose, especially for cases where setters are used(like in member5 below):

@Configuration
public class FixturesJavaConfig {

 @Bean public Member member1(){return new Member("first1", "last1", address1());}
 @Bean public Member member2(){return new Member("first2", "last2", address1());}
 @Bean public Member member3(){return new Member("first3", "last3", address1());}
 @Bean public Member member4(){return new Member("first4", "last4", address1());}
 
 @Bean public Member member5(){
  Member member = new Member();
  member.setFirst("first5");
  member.setLast("last5");
  member.setAddress(address5());
  return member;
 }
 
 @Bean public Address address1(){return new Address("city1", "state1");}
 @Bean public Address address2(){return new Address("city2", "state2");}
 @Bean public Address address3(){return new Address("city3", "state3");}
 @Bean public Address address4(){return new Address("city4", "state4");}
 @Bean public Address address5(){return new Address("city5", "state5");}
}

A matter of choice at the end of the day I suppose, but this has become a pattern that I have been using now - use Java Configuration where feasible, but use XML configuration for cases where a bunch of test fixtures need to be created.

Thursday, February 7, 2013

Spring Bean names

Spring bean names are straightforward, except for cases where names are not explicitly specified.

To start with, Spring bean names for an xml based bean definition is specified this way:

<bean name="sampleService1" class="mvcsample.beanname.SampleService">
 <constructor-arg>
  <bean class="mvcsample.beanname.SampleDao"></bean>
 </constructor-arg>
</bean>

For a Java @Configuration based bean definition, the method name of the @Bean annotated method becomes the bean name:

@Configuration
@ComponentScan(basePackages="mvcsample.beanname")
public static class SpringConfig{
 
 @Bean
 public SampleService sampleService(){
  return new SampleService(sampleDao());
 }
 
 @Bean
 public SampleDao sampleDao(){
  return new SampleDao();
 }
 
}


and for Stereotype annotation(@Component, @Service, @Repository etc) based beans, the value field indicates the bean name:
@Repository("aSampleDao")
public class SampleDao {
    ...
}

@Service("aSampleService")
public class SampleService {
    ...
}

Now, what happens for cases where the bean name is not specified.

XML Based Bean Configuration Case:
For an xml based configuration, a case where the bean name is typically not specified are for beans which can act on the entire bean factory - say for eg, to define a BeanPostProcessor or a BeanFactoryPostProcessor
For eg. consider the following dummy BeanPostProcessor that just grabs all the bean names from bean factory:
public class BeanNameScanningBeanPostProcessor implements BeanPostProcessor{
 private List<String> beanNames = new ArrayList<>();
 @Override
 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  return bean;
 }

 @Override
 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  beanNames.add(beanName);
  return bean;
 }
 
 public List<String> getBeanNames(){
  return this.beanNames;
 }
}

It would typically be defined in an xml bean configuration this way:
<bean class="mvcsample.beanname.BeanNameScanningBeanPostProcessor"/>

A second case with xml based configuration where a name is typically not specified is with inner beans, for eg. defined this way:
<bean class="mvcsample.beanname.SampleService">
 <constructor-arg>
  <bean class="mvcsample.beanname.SampleDao"></bean>
 </constructor-arg>
</bean>

The bean names for these cases is handled by a component called the BeanNameGenerator. For the case of a top level bean the name typically ends up being the package qualified class name along with a count of the instances, this way:

mvcsample.beanname.BeanNameScanningBeanPostProcessor#0

For the case of an inner bean, since it exists only in the scope of its containing bean, the name is not that relevant, however internally it does get a name based on the hex hash code of the bean definition for eg, "mvcsample.beanname.SampleDao#1881ee8b"


Java Based @Configuration Case:
For java based @Configuration on the other hand it is not possible to specify a bean without a name, the bean name is the method name.

Annotation based Configuration
For stereotype annotation based bean, if the name is not explicitly specified with the value field of stereotype annotations, then the name is again generated by AnnotationBeanNameGenerator which is an implementation of the BeanNameGenerator strategy interface, the names generated is simply the short name of the class, for eg from the javadoc for AnnotationBeanNameGenerator - bean name for com.xyz.FooServiceImpl becomes fooServiceImpl.

Conclusion:
So to finally conclude, if bean names are relevant to you in some way(for eg to disambiguate between multiple bean instances of same type), then it is best to be explicit about the names, otherwise depend on Spring to generate the bean names for you. In some cases, for eg. with Spring-data project it is possible to specify custom behavior for repositories as a separate bean and Spring-data by default uses Spring naming conventions to find the custom implementation and understanding how bean names are generated helps.


Friday, February 1, 2013

atan2 in scala

atan2 function is defined as follows:



I wanted to try a small exercise of implementing this using scala(ignoring the fact that it is already natively implemented in java.lang.Math library).

The simplest implementation that I could think of is with a if expression this way:


def atan2(x: Double, y: Double):Double = {
  if (x >0)                     atan(y/x)
  else if (y >= 0 && x < 0)     Pi + atan(y/x)
  else if (y < 0 && x < 0)      atan(y/x) - Pi
  else if (y > 0 && x==0)       Pi/2
  else if (y < 0 && x==0)       -Pi/2
  else                          Double.NaN
}

However, I wanted to see at this point if it could be reimplemented using a case-match expression, and I could only come up with a souped up version of if/else this way:

def atan2(x: Double, y: Double): Double = {
  true match {
    case _ if (x>0)             => atan(y/x)
    case _ if (y >= 0 && x < 0) => atan(y/x) + Pi
    case _ if (y < 0 && x < 0)  => atan(y/x) - Pi
    case _ if (y > 0 && x==0)   => Pi/2
    case _ if (y <0 && x==0)    => -Pi/2
    case _                      => Double.NaN
  }
}

After reading up a little more on scala extractors, I could come up with a crazier version of the same:
def atan2(x: Double, y: Double): Double = {
  (x, y) match {
    case xgt0()           => atan(y/x)
    case ygte0Andxlt0()   => atan(y/x) + Pi
    case ylt0Andxlt0()    => atan(y/x) - Pi
    case ygt0Andxeq0()    => Pi/2
    case ylt0Andxeq0()    => -Pi/2
    case _                => Double.NaN
  }
}

However, this unfortunately requires defining 5 extractors this way:
object xgt0 {
 def unapply(tup: (Double, Double)): Boolean = tup match { case (x,y) => (x>0)}
}

object ygte0Andxlt0 {
 def unapply(tup: (Double, Double)): Boolean = tup match { case (x, y) => (y >= 0 && x < 0)}
}

object ylt0Andxlt0 {
 def unapply(tup: (Double, Double)): Boolean = tup match { case (x, y) => (y < 0 && x < 0)}
}
 
object ygt0Andxeq0 {
 def unapply(tup: (Double, Double)): Boolean = tup match { case (x, y) => (y > 0 && x == 0)}
}

object ylt0Andxeq0 {
 def unapply(tup: (Double, Double)): Boolean = tup match { case (x, y) => (y < 0 && x == 0)}
}

The only conclusion I could make out of this is that if I had to re-write atan2 in scala the best approach is probably using the first one - using if expression. I am sure there is definitely a more scala way of doing this and would definitely appreciate any suggestions on these approaches

Wednesday, January 30, 2013

CGLIB and ASM inlined with Spring 3.2

This is a small change, but will go some way with issues that I have faced in the past in getting the correct dependency of CGLIB/ASM with my projects. CGLIB and its dependency ASM are now both inlined with the Spring-Core binaries(as of Spring 3.2+) - their source is not maintained with the spring-core project, but are inlined at build time. From the maven pom.xml perspective, the following can now be kept out of the file:

<dependency>
 <groupId>cglib</groupId>
 <artifactId>cglib</artifactId>
 <version>2.2.2</version>
</dependency>