Wednesday, July 21, 2010

Some Cool Ubuntu Plugins to have

Found this article giving some cool things you can use if your on Ubuntu. Check it out.

Thursday, July 15, 2010

Running embedded JMS with Spring

I was experimenting on how to run active mq embedded with spring so as to ease out unit testing of queues. First i looked at the doc provided in active mq but the thing is the namespace URI provided in the site was invalid and as such it didnt work right out of the box. Then i stumbled upon this article which showed the correct namespace to include. And also you need to include xbean-spring-3.4.jar. Here is a sample i have done;

First we create the message sender;


import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

public class JMSSender {

private JmsTemplate jmsTemplate;

private Destination destination;

public void sendMessage(final String message) {
jmsTemplate.send(destination, new MessageCreator() {

@Override
public Message createMessage(Session arg0) throws JMSException {

TextMessage msg = arg0.createTextMessage();
msg.setText(message);
return msg;
}
});
}

/**
* @return the jmsTemplate
*/
public JmsTemplate getJmsTemplate() {
return jmsTemplate;
}

/**
* @param jmsTemplate the jmsTemplate to set
*/
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}

/**
* @return the destination
*/
public Destination getDestination() {
return destination;
}

/**
* @param destination the destination to set
*/
public void setDestination(Destination destination) {
this.destination = destination;
}
}


This will just send the message to the specified destination. The destination will be specified in the spring configuration which we will look at in just a little moment.

Next i write my JUnit test class to test the embedded messaging queue.


import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.TextMessage;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:test-common-context.xml")
public class JMSTest {

@Autowired
private JMSSender jmsSender;

@Autowired
@Qualifier("consumer")
private JmsTemplate jmsTemplate;

@Autowired
private Destination destination;

@Test
public void testJMSSender() {
jmsSender.sendMessage("test");
TextMessage msg = (TextMessage) jmsTemplate.receive(destination);
System.out.println("***********************");
try {
System.out.println(msg.getText());
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("***********************");
}
}


I have specified the configuration file with the annotation. In that i just import the active mq configuration file which im going to show you now.


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd">


<!-- lets create an embedded ActiveMQ Broker -->
<amq:broker useJmx="false" persistent="false">
<amq:transportConnectors>
<amq:transportConnector uri="tcp://localhost:0" />
</amq:transportConnectors>
</amq:broker>

<!-- ActiveMQ destinations to use -->
<amq:queue id="destination"
physicalName="org.apache.activemq.spring.Test.spring.embedded" />


<!--
JMS ConnectionFactory to use, configuring the embedded broker using
XML
-->
<amq:connectionFactory id="jmsFactory" brokerURL="vm://localhost" />


<!-- Spring JMS Template -->
<bean id="myJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<qualifier value="producer" />
<property name="connectionFactory">
<!-- lets wrap in a pool to avoid creating a connection per send -->
<bean class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory">
<ref local="jmsFactory" />
</property>
</bean>
</property>
</bean>

<bean id="consumerJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<qualifier value="consumer" />
<property name="connectionFactory" ref="jmsFactory" />
</bean>

<!-- a sample POJO which uses a Spring JmsTemplate -->
<bean id="producer"
class="JMSSender">
<property name="jmsTemplate">
<ref bean="myJmsTemplate"></ref>
</property>

<property name="destination">
<ref bean="destination" />
</property>
<!--

<property name="messageCount"> <value>10</value> </property>
-->
</bean>



</beans>





That is all you need. And now you can just run the jUnit test and you can see the result. Ofcourse there are better ways of hooking up the jms template, but the purpose of this article was not to exemplify that. If you do have any queries do let me know.


Cheers

Friday, July 2, 2010

An Abstraction to use HibernateDAOSupport

In this post i would like to share with you guys on this DAO abstraction i have created by using HibernateDAOSupport for the previously mentioned development framework im currently creating. First of all i start with defining my BaseDAO.


package com.dyna.frm.commons.dao;

import java.io.Serializable;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public interface BaseDAO<T, PK extends Serializable> {

public void createOrUpdate(T... entity);

@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
public T read(PK id);

public void update(T id);

public void delete(PK... id);

}


Here i have created four methods to deal with the main four CRUD operations that anyone will have to deal with. I have specified the transactions at the interface layer and have opted to go for annotation based transactions due to rarity of transactions being changed and i didnt want to clutter by XML configuration with it. At the top most layer i have defined as transaction equired and read only false. This is because only the read method does not need a transaction and whilst others do. As you know REQUIRED will create a new transaction if one is not already provided.

Note that i have used NOT_SUPPORTED for the read method as retrievals do not need to run within a transaction and hence it is just over head to create a transaction for retrievals.

Moving on next i show you the BaseDAO implementation class;


package com.dyna.frm.commons.dao.daoimpl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.dyna.frm.commons.dao.BaseDAO;

public class BaseDAOHiberanateImpl<T, PK extends java.io.Serializable> extends
HibernateDaoSupport implements BaseDAO<T, PK> {

private Class<T> entityClass;


public BaseDAOHiberanateImpl(Class<T> entityClass) {
this.entityClass = entityClass;
}

@Override
public void createOrUpdate(T... entity) {

getHibernateTemplate().saveOrUpdateAll(Arrays.asList(entity));

}

@SuppressWarnings("unchecked")
@Override
public T read(PK id) {
return (T) getHibernateTemplate().get(entityClass, id);

}

@Override
public void update(T entity) {
getHibernateTemplate().update(entity);

}

@Override
public void delete(PK... id) {
if (id.length == 1) {
T entity = read(id[0]);
getHibernateTemplate().delete(entity);
} else {
List<T> entityList = new ArrayList<T>();
for (PK pk : id) {
T entity = read(pk);
entityList.add(entity);
}
getHibernateTemplate().deleteAll(entityList);
}

}

}



As you can see here i have extended from Spring's HibernateDAOSupport class. The good thing about using the HibernateTemplate is that it encapsulates all those nitty gritty database exceptions and wraps it around Spring's DAO exception stack. The good thing is Spring's Exceptions are runtime and hence are not forced to catch any exceptions if you do not need to.

The best approach of handling exceptions is i believe through writing an Exception Interceptor to intercept all your DAO calls and you can catch the ones you only need in your application and wrap it with your own custom application specific exceptions.

Anyhow moving on with the implementation class for create or update i have used the saveOrUpdate method of Hibernate template and as i have used var args in the method parameters i can process both single entity persistence as well as batch entity persistence within one method.All the other methods are self explanatory as i see it. For delete also as i have provided the ability for the user to send a collection of PK values to delete from i have again used two different methods from the Hibernate template checking whether the varg args length is greater than zero.

Next i show you a sample usage of this base dao implementation i have provided by creating a DAO for a hypothetical Person entity;

package com.dyna.frm.controller.dao;

import com.dyna.frm.commons.dao.BaseDAO;
import com.dyna.frm.controller.domain.Person;

public interface PersonDAO extends BaseDAO<Person, Long>{

}




package com.dyna.frm.controller.dao.hibernate;

import org.springframework.beans.factory.annotation.Qualifier;

import com.dyna.frm.commons.dao.daoimpl.BaseDAOHiberanateImpl;
import com.dyna.frm.controller.dao.PersonDAO;
import com.dyna.frm.controller.domain.Person;


@Qualifier("personDAOHibernate")
public class PersonDAOImpl extends BaseDAOHiberanateImpl<Person, Long> implements PersonDAO{


public PersonDAOImpl() {
super(Person.class);
}



}



I have defined a qualifier here because if i ever needed to use JpaTemplate then i wouldnt have conflicts when i try to Auto wire based on the PersonDAO interface.As you can see within the constructor i have called the BaseDAOImpl class constructor passing in the entity we need to manage within this DAO class. And all other basic methods are now available to this PersonDAO and you can add any additional methods you need as you progress.

And finally i give you the XML configuration needed to wire this up;



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

<tx:annotation-driven />

<!-- JTA Transaction Mgr is used for JEE applications -->
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="autodetectTransactionManager" value="true" />
</bean>

<bean id="personDAO" class="com.dyna.frm.controller.dao.hibernate.PersonDAOImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>com.dyna.frm.**.*</value>
</list>
</property>
<property name="hibernateProperties">
<ref bean="defaultHibernateProps" />
</property>
</bean>


<!-- Hibernate properties bean -->
<bean id="defaultHibernateProps"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.dialect">${dyna.frm.db.hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${dyna.frm.db.show.sql}</prop>
</props>
</property>
</bean>

</beans>


Note that here i have used JTA transactions and as i am running this within jboss i have used the autodetectTransactionManager property.

One notable thing here is that within the sessionFactory bean definition i have used the attribute packagesToScan. Why i have defined this way is because now i do not need to define each annotated class individually as Spring will scan all sub packages within com.dyna.frm so that all classes that are annotated with @Entity will be enclosed. I have used PropertyPlaceHolder to get the dialect names and other parameters.

Thats it. If you have any queries do drop a comment.