Showing posts with label spring. Show all posts
Showing posts with label spring. Show all posts

Thursday, December 8, 2011

Automated Integration Tests Using with Jetty, Maven and Other Neat Freameworks - 2

In the previous post, I have started a Jetty server in the beginning of a unit test with a configured external data-source.

Let's talk about it a little bit more. The assumption here was that the application on a regular basis uses an external data-source that is accessed via JNDI. In general it's a good practice to keep a data-source external to the application:
1. It's always possible to change the data-source without touching the application - let's say a bug was found in a data-source you are using. Or it should be configured differently. If a data-source embedded into an application and such a change is required, you will probably need to release patch. If the datasource is external, it would be enough just to change/reconfigure it.
2. In some deployments several applications can use the same datasource. Consider a Tomcat running with several wars: quite a common case, right? If a datasoure is embedded, each war has its own data-source. Usually this would be a waste of resources and duplication of a configuration.
3. And finally it would be possible to change a data-source for unit tests, which is exactly our use case.

For unit tests it's really convenient to use in-memory database. There are few databases implemented in java that provides this capability. My favorite are H2 and HSQL. In this example I have used HSQL, so here comes the jetty-ds-test.xml:

<Configure id="Server" class="org.eclipse.jetty.server.Server">
    <New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg></Arg>
        <Arg>jdbc/my_ds</Arg>
        <Arg>
            <New class="org.hsqldb.jdbc.JDBCDataSource">
                <Set name="Url">jdbc:hsqldb:mem:test;sql.syntax_ora=true</Set>
                <Set name="User">sa</Set>
                <Set name="Password">sa</Set>
            </New>
        </Arg>
    </New>
</Configure>

This is configuration of HSQL in memory. Notice sql.syntax_ora=true, which makes HSQL to use Oracle syntax. This is useful if you are using Oracle in production, but you want to use HSQL for unit testing or development.

So now you have at the beginning of a unit-test you have a Jetty server running with your application connected to in-memory HSQL database via JNDI. But something is still missing. This something is a database schema: to remind you, we have just started a new database in memory and it's empty. You probably already have a script that generates schema, tables, indexes and may be some data. Now you need to run it.

Actually there are several options how do it. One of the easiest is to use Springs's SimpleJdbcTestUtils. But first we'll need to add a dependency on spring-test in our pom.xml:

<dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-test</artifactId>
         <scope>test</scope>
         <version>${spring-version}</version>
</dependency>

And here comes the code that runs the sql script:
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
...
    @BeforeClass(dependsOnMethods = { "startJetty" })
    public void initiateDatabase() throws Exception {       
        InitialContext initialContext = new InitialContext();
        DataSource ds = (DataSource) initialContext.lookup("jdbc/my_ds");
        SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(ds);
        Resource resource = new ClassPathResource(sqlScriptFileName);
        SimpleJdbcTestUtils.executeSqlScript(simpleJdbcTemplate, resource, false);
    }
In this snippet I load the sqlScriptFileName from the classpath. Usually it's convenient to place the script in src/test/resources, but if you don't like it, you can always load it from a different place by using other Resource implementations (e.g. URLResource is quite convenient).

As I have already said in this snippet I used Spring. If you are familiar with Spring, it is probably natural to you. If you don't - don't be afraid. Only the unit tests become dependent on Spring, but the actual application did not.

And now you are ready to start the testing.


Recommended Reading

1. Next Generation Java Testing: TestNG and Advanced Concepts
2. Apache Maven 3 Cookbook
3. Spring Recipes: A Problem-Solution Approach

Thursday, August 5, 2010

Spring - Which resources are actually loaded in Spring Context?

Today I got a really weird behavior: some spring context file was loaded into the same context twice. This caused exception, since some beans are expected to be singletons, while I got two instances.

In this post I'm not going to describe what exactly was the problem. But rather how I investigated it.

So in order to see what are the actual files being loaded and what is the source of the definition that caused them to be loaded I put a breakpoint in org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(InputSource, Resource).

That's all. Try it yourself :)

Tuesday, March 2, 2010

Apache Wink - Dynamic Resources

Quite often people ask me what is so different about Apache Wink, and why another JAX-RS framework. Usually I answer that Apache Wink started in HP long before there was any REST open-source framework. It was developed internally for two years before joining Apache.

This may be interesting from historical point of view, but then people ask: so why should we use it now? Are there any unique features?
And the answer here is: yes, there are some unique features beyond the JAX-RS spec and this post will describe one of the most cool features (IMO) that Wink contains:

Dynamic Resources


The idea of Dynamic Resource is quite similar to Template pattern and it's simple: many resource classes have more or less the same logic. However, they manipulate different entities, so obviously they have different URLs.

Consider the following example: a resource that simply a facade to the database - it allows the CRUD operation and it uses Hibernate as the persistence layer.

So basically the template class will look something like this:

public class CrudResource {

private Session session;
@Context
private UriInfo uriInfo;

private Class clazz;

@GET
public Object getEntity(@PathParam("id") String id) {
return session.get(clazz, id);
}

@POST
public Response createEntity(Object newEntity) {
session.save(newEntity);
String id = newEntity.getId(); // this line will not compile, but the idea is that id is assigned by hibernate
URI location = uriInfo.getAbsolutePathBuilder().segment(String.valueOf(id)).build();
return Response.created(location).build();
}

@PUT
public void updateEntity(Object entity) {
session.update(entity);
}

@DELETE
public void delete(@PathParam("id") String id) {
session.delete(session.get(clazz, id));
}

}

Notice: This class doesn't contain the full logic, like transaction management, and won't even compile. It should provide the idea how to implement the "template" style resource and not how to really work with Hibernate or even Wink.

So as you can see, this class can basically perform the CRUD operations on any entity. It would be a pity, if for each entity, we'll need to extend this class just to assign a different path. And here come the Dynamic Resources. They allow to skip the @Path annotation and implement the DynamicResource interface instead (or extend from the AbstractDynamicResource class).

So now our resource will look something like this:
public class CrudResource extends AbstractDynamicResource  {
...
}

Now it's possible to create multiple instances of this class and assign it a different paths and other members (like 'clazz', which should hold the value of actual class).

Notice: Dynamic Resources can be returned only by Application.getSingletons() method. Thus these resources are actually singletons and must be coded accordingly (for example think about synchronization issues).

Spring Integration


Wink contains the Spring Integration extension. I won't describe its features here, but only want to mention the usage of Dynamic Resources with Spring.
First, Dynamic Resource can be defined and registered via Spring Context, thus you can create new resources using the same class, while updating the configuration only. Pretty nice feature, when you think about it.
Second, Dynamic Resources benefit from different scopes. Meaning, they may not be singletons anymore.

Sunday, February 22, 2009

Tips regarding Spring's PropertyPlaceholderConfigurer

Most of the Spring users are familiar with the PropertyPlaceholderConfigurer that is used to replace placeholders defined in the context xml with the actual values. In this post I want to describe some of its less known features.

Ignore Unresolvable Placeholders


By default a PropertyPlaceholderConfigurer throws an exception, when it completes resolving the placeholders, and there are still unresolved placeholders left. However, suppose that your application is built from the several modules, which are combined to the same spring context. Each module has its own PropertyPlaceholderConfigurer and simply cannot resolve the others. You won't like it to fail the whole application loading, right?

Setting property ignoreUnresolvablePlaceholders to true will tell the PropertyPlaceholderConfigurer to ignore the unresolvable placeholders.

In general, I would suggest for all modules to set this property to true to ensure that none of the modules fails the whole system.

Placing validating PropertyPlaceholderConfigurer


"But" - you may say - "I still want to know that the context is incorrect. How can I do it, if all the PropertyPlaceholderConfigurers are set to ignore the unresolvable placeholders?"

To do so, you'll need to place a validating PropertyPlaceholderConfigurer, which task will be to run after all PropertyPlaceholderConfigurers completed their job and check, if all the properties were resolved. Its definition is very simple and won't include any special configuration.

"But" - you should ask now - "I don't know the order in which the PropertyPlaceholderConfigurers run".

Actually it's untrue and you know the order, you just don't know about it:

Setting the Order of PropertyPlaceholderConfigurers


PropertyPlaceholderConfigurer is a BeanFactoryPostProcessor that implements PriorityOrdered interface. This cause it to run before the BeanFactoryPostProcessors that implement Ordered interface and they run before the BeanFactoryPostProcessors that don't implement these interfaces at all.
Both PriorityOrdered and Ordered objects implement a method getOrder that returns an order in which the objects should be applied. Zero means a highest priority. Integer.MAX_VALUE means the lowest priority.
By default the order is set to Integer.MAX_VALUE.
And what happens if two PropertyPlaceholderConfigurer have a same priority? They run in the order of their definition in the context xml file.

Overriding Properties Defined in the PropertyPlaceholderConfigurer


Consider the following situating: you are using some module, which has defined its own PropertyPlaceholderConfigurer and you want to override a property. Without "order" and "ignoreUnresolvablePlaceholders" properties it can be quite cumbersome. However, when using "order" and "ignoreUnresolvablePlaceholders" it becomes very simple:
  1. Define a PropertyPlaceholderConfigurer with order set to a lower order (higher priority) then a PropertyPlaceholderConfigurer in the module.
  2. Set ignoreUnresolvablePlaceholders to true, since you don't want to override all the properties. Moreover, there are may be additional modules, who have their own placeholders...
  3. Define the properties you want to override.

Summary


When using a PropertyPlaceholderConfigurer you need to identify if your product is a stand alone application or a module in a bigger system. The default PropertyPlaceholderConfigurer is good for a stand alone application. But if you are writing the module make sure that:
  1. The order property should be set between 1 and Integer.MAX_VALUE. I would suggest setting it somewhere between 10000 and Integer.MAX_VALUE-10000 to ensure that anyone can insert a PropertyPlaceholderConfigurer both before and after yours. I assume that none system would have more then 10000 PropertyPlaceholderConfigurers.
  2. Set ignoreUnresolvablePlaceholders to true, to ensure that your module won't fail because of others placeholders. Your placeholder is still responsible to fill the placeholders in your module and I would recommend to create a unit test, which will hold a validating PropertyPlaceholderConfigurer and fail if someone forgets to resolve a placeholder.
  3. The main system should include the validating PropertyPlaceholderConfigurer to ensure that all modules have filled their placeholders.
  4. Include module name and version in the properties names. This will reduce conflicts and backward compatibility problems. Example: if module has name "example" and version is "4.1", make all properties to start with "example.4.1" or "example_4_1". Meaning "debug" propery would be called "example.4.1.debug" or "example_4_1_debug".


Recommended Reading

1. Spring in Action
2. Effective Java
3. Joel on Software: And on Diverse and Occasionally Related Matters That Will Prove of Interest to Software Developers, Designers, and Managers, and to Those Who, Whether by Good Fortune or Ill Luck, Work with Them in Some Capacity
4. Small Gods