Sunday, August 2, 2009

Example:Spring Integration + Spring DM OSGi + Spring JMS(JBoss MQ)

I have come up with a sample for spring jms with spring integration.It shows how easy is it to configure adaptors for jms using spring integration.

Source Code Download:http://www.4shared.com/dir/18401908/5d14c8a6/springintosgijms.html

I basically have three bundles

Jms Exchange - where jms input/output channels and apapters are declared

Jms-Sender - bundle publishing message into the queue

Jms-Receiver - bundle receiving message from the queue

Jms Exchange
------------------

Publishing channel will put the message into this channel
<!-- channel for jms In message -->
<integration:channel id="jmsInChannel" />


Wrapping the channel using gateway , so that bundle publishing into teh channel is unaware of spring integration apis.

<!-- gateway which puts message into channel -->
<integration:gateway id="jmsSendProxy"
default-request-channel="jmsInChannel" service-interface="com.jms.exchange.IJmsEvent" />


Publishing the gateway as OSGi service for sender to put messages into the cahnnel.

<osgi:service id="jmsSendService" interface="com.jms.exchange.IJmsEvent" ref="jmsSendProxy"></osgi:service>



Jms outbound adaptor which picks the message from channel and puts it into the defined jms queue.

<!-- adapter which puts message from channel to jms queue -->
<jms:outbound-channel-adapter id="jmsin"
destination="sendDestination" channel="jmsInChannel" />


JNDI template required for jms communication on JBoss MQ

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory
</prop>
<prop key="java.naming.provider.url">jnp://10.1.64.232</prop>
<prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming
</prop>
</props>
</property>
</bean>


Connection Factory definition

<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>java:ConnectionFactory</value>
</property>

</bean>


Queue details for sending message

<bean id="sendDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>queue/RequestQueue</value>
</property>
</bean>



JMS message driven channel adaptor which picks the message as soon as it on the JMS queue and puts it into
the given channel.

<!-- adapter which pulls message from queue into channel -->
<jms:message-driven-channel-adapter
id="jmsout" destination="sendDestination" channel="jmsOutChannel" />


Channel defined for putting the message from queue to channel.

<!-- channel for jms Out message -->
<integration:channel id="jmsOutChannel" />


Publishing the channel as OSGi service for receiver to pick the mssage from channel.

<osgi:service id="jmsListenChannel" ref="jmsOutChannel"
interface="org.springframework.integration.channel.SubscribableChannel" />


Jms Sender
--------------


Osgi referece in to teh gateway for publishing the message into the channel.

<osgi:reference id="jmsSendProxy" interface="com.jms.exchange.IJmsEvent" ></osgi:reference>


JMS Sender using the gateway to put messages into the channel.

<!-- POJO calling gateway -->
<bean id="sender" class="com.jms.sender.Sender">
<property name="jmsSendProxy" ref="jmsSendProxy"></property>
</bean>


public class Sender extends TimerTask{

private IJmsEvent jmsSendProxy;

public void setJmsSendProxy(IJmsEvent jmsSendProxy) {
System.out.println("SETTER CALLED");
this.jmsSendProxy = jmsSendProxy;
}

@Override
public void run() {
System.out.println("TIMER TASK");
jmsSendProxy.send("TEST MESSAGE");

}
}


Spring Time Task which puts the message into the channel periodically.


<bean id="senderTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="period" value="10000" />
<property name="timerTask" ref="sender" />
</bean>

<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="senderTask" />
</list>
</property>
</bean>






Jms receiver
-----------------

OSGi reference into the channel for listening the messages in the channel.

<osgi:reference id="jmsListenChannel"
interface="org.springframework.integration.channel.SubscribableChannel" />


Service Activator which has a calls a dummy method when a jms message is received.

<!-- service activator for listening to jms messages on channel -->
<integration:service-activator
input-channel="jmsListenChannel" ref="jmsreceiver" method="receive" />

<bean id="jmsreceiver" class="com.jms.receiver.Receiver">



public class Receiver {

public void receive(String arg)
{
System.out.println("Jms response recevived"+arg);
}

}

Example: Spring Integration + Spring DM OSGi + Spring Remoting

I have just come up with a example for Spring integration along with OSgi.

I basically have 4 bundles

1. Exchange bundle which has definitions of channels

This bundle is spring integration aware, and hence has channel definitions in it.

Channel definition.

<publish-subscribe-channel id="login"/>

This channl is wrapped around a gateway and exposed as a OSGi service.This is to ensure that the event generating bundle is unaware of spring integration apis

Wrapping channel around gateway

<gateway id="loginProxy" default-request-channel="login"
service-interface="com.pg.exchange.event.IEvent" />

Exposing gateway as OSGi service

<osgi:service id="loginChannel" ref="loginProxy"
interface="com.pg.exchange.event.IEvent" />


Also the channel is directly published as a OSGi service for listener listening to it.

<osgi:service id="loginAnnouncementsChannel" ref="login"
interface="org.springframework.integration.channel.SubscribableChannel" />



2. Login bundle - bundle which generate login event and publishes it using gateway.

Accepting the Gateway from the exchange bundle as a OSgi service

<osgi:reference id="eventPublisher"
interface="com.pg.exchange.event.IEvent"/>

This bundle generates periodic events using a spring timer task as shown below

<bean id="logineventGenerator" class="com.pg.ara.LoginEventGenerator">
<property name="eventPublisher" ref="eventPublisher"></property>
</bean>

<bean id="loginTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="period" value="10000" />
<property name="timerTask" ref="logineventGenerator" />
</bean>


<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="loginTask" />
</list>
</property>
</bean>

Timer Task class generating events

public class LoginEventGenerator extends TimerTask {

IEvent eventPublisher;

public void setEventPublisher(IEvent eventPublisher) {
this.eventPublisher = eventPublisher;
}

@Override
public void run() {
System.out.println("login event published");
eventPublisher.login("Logged In");
}

}


3. Pam-proxy bundle is a bundle which listens to the event using OSGi refered pub-sub-channel

When the message is obtained it makes a spring remoting call uisng remoting adaptors

Consumed OSGi service

<osgi:reference id="loginAnnouncementsChannel"
interface="org.springframework.integration.channel.SubscribableChannel"/>


Activator which makes a remoting call when message is put on a channel

<si:service-activator input-channel="loginAnnouncementsChannel"
ref="exampleService"
method="testRemoting"
output-channel="responseChannel"/>


Channel which gets the spring remoting response
<si:channel id="responseChannel" />


Activator listening on the response
<si:service-activator input-channel="responseChannel"
ref="responseHandler"
method="handleResponse" />

ProxyFactory bean for making spring remoting call
<bean id="exampleService"
class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean" >
< property name="serviceUrl" value="http://localhost:8088/test/pamService" />
< property name="serviceInterface" value="com.pam.external.IExampleService" />
</bean>


Response handler for the spring remoting call
<bean id="responseHandler" class="com.pam.proxy.sample.ResponseHandler" />


All the above bean can be avoided and instead we can use http-invoker inbound and outbound adaptors as explained in spring integration reference guide.

But i did not want the spring remoting hosting side to be unaware of spring integration.

Also i did not want to put any java code in the pam-proxy bundle.


4. Pam web bundle publishing a spring remoting service

<bean id="exampleProxy" class="com.pam.ExampleService" />

<bean name="/pamService"
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="exampleProxy" />
<property name="serviceInterface" value="com.pam.external.IExampleService" />
</bean>



Source Code Location :http://www.4shared.com/dir/18401573/8c9d7e8d/springintosgiremoting.html

Saturday, August 1, 2009

Spring Integration & OSGi

This is the latest addition to the spring portfolio ,and again they have made it look so simple. This is mainly meant for asynchronous messaging between modules.Here when i say modules it could be within the same JVm or outside. Spring Integration does not provide any framework for inter JVM communication instead it provides adapters for all existing frameworks like JMS,Spring Remoting,HTTP calls ,Web Services etc.

Spring Integration mainly deals with channels , which is a pipe where messages can be put , and there can be any number of subscibers listening to it.We can keep our business logic independent of the frameworks used.Here channels can be of different types direct channels,pub-sub-channel,polling channels etc .Also there are provisions to make the channel synchronous.

It also provides number of adapters like jms adapters,rmi adaptors,web service adpaters such that we always deal in terms of channels i .e we talk to channels and it publishes to the required framework.Since we keep our code independent of any framework it will be easy flip any of these using configuratiosn without affecting teh business logic.

Certain examples i came across which are very descriptive

1.Spring Integration Documentaion Examples(http://static.springsource.org/spring-integration/reference/htmlsingle/spring-integration-reference.html#samples)

2.Spring Integration Example(dist/org.springframework.integration.samples-1.0.2.SR1.jar)

3.Blog by Oleg(http://blog.springsource.com/2009/02/27/spring-integration-on-dm-server/)

Certain points to note.

1.Channels can be published as OSGi service and other bundles can import it and publish on the channel or listen to it.

Note :

When more than one pub sub channel is defined and needs to be published, filter attributes have to be used to distinguish one from teh other.

Ref : http://forum.springsource.org/showthread.php?t=75316

Two models for hiding spring integration apis from bundles

1. Have a seperate bundle(call it exchange bundle) with spring integration configurations.

2. Wrap the channel using gateway() and expose this as a service , which will be used from the publishing bundle.This makes it independent of spring integration APIs and the publishing channel needs to know only about the interface.

3a. Let all teh bundles interested in listening to teh event register with the exchange bundle using a interface.

Implement a service activator in the exchange bundle.The service activator will collect all the OSgi services interested in listening to the service and call teh method one after the other for all registered services.

3b. The service activator will have a register /unregister method ,and teh service activator will be exposed a OSgi service.The interested bundles will import this service and call the register method. On calling thr register method it will add to the list in teh activator, which will call the method when teh event is published on teh channel. (oleg's blog uses teh same model)

http://forum.springsource.org/showthread.php?t=75315

Saturday, July 25, 2009

Browser Caching -Expires,Cache Control & Deflate

Expires Header – will stop the request(304 request-if modified ?) sent from browser

Disadvantage – even if the asset changes the browser will serverthe cached image without even checking if the image has changed.

The only solution is to come up with Versoning if we set Expires.


Syntax(in apache httpd.conf)

#Adding expires header

<FilesMatch "\.(jpg|jpeg|png|gif|swf)$">

Header set Expires "Wed, 31 Dec 2008 23:59:59 GMT"

</FilesMatch>

Also can set using access plus x days

Cache control will over ride expires header even if set.

Add this line for disabling cache control

Header set Cache-control: No-cache,no-store

Add this line for enabling cache control

Header set Cache-Control "private,max-age=0,must-revalidate"

The following lines can be used to remove the ETag header

Header unset ETag

FileETag None

Etag generates the tag using the ip of the hosted machine and when the assets are hosted in multiple machines , and requests may go to different machines and hence e-tags may be different and they will be downloaded again

Also while doing scp(having multiple deployment machines), to retain the original timestamps we need to use ‘scp –p’ whereas the touch command can change the access/modified time for the file after it is copied.

The above cache control works on the basis of the last modified time .And hence the modified time stamps have to be kept same in all the asset holding machines , so when copying the assets copy with same time stamps else requests will be sent again.


Adding Gzip configuration
<FilesMatch "\.(html|htm|js|css)$">
SetOutputFilter DEFLATE
</FilesMatch>


Adding Expires
ExpiresActive On
ExpiresDefault "now plus 0 seconds"

<FilesMatch "\.(jpg|jpeg|png|gif|swf|mp3)$">
ExpiresByType image/jpg "access plus 14 days"
ExpiresByType image/jpeg "access plus 14 days"
.....
.....
Header set Cache-Control "public,max-age=1209600"
Header unset Pragma
</FilesMatch>


Apache HttpClient

Although the java.net package provides basic functionality for accessing resources via HTTP, it doesn't provide the
full flexibility or functionality needed by many applications. The Jakarta Commons HttpClient component seeks to fill
this void by providing an efficient, up-to-date, and feature-rich package implementing the client side of the most
recent HTTP standards and recommendations

Feature List

http://hc.apache.org/httpclient-3.x/features.html

CGLIB-For Dynamic Proxies

The Spring Framework implements method injection by dynamically generating a subclass overriding the method, using bytecode generation via the CGLIB library.

Please be aware that in order for this dynamic subclassing to work, you will need to have the CGLIB jar(s) on your classpath. Additionally, the class that the Spring container is going to subclass cannot be final, and the method that is being overridden cannot be final either.

By default, when the Spring container is creating a proxy for a bean that is marked up with the <aop:scoped-proxy/> element, a CGLIB-based class proxy will be created. This means that you need to have the CGLIB library on the classpath of your application.

Note: CGLIB proxies will only intercept public method calls! Do not call non-public methods on such a proxy; they will not be delegated to the scoped target object.

You can choose to have the Spring container create 'standard' JDK interface-based proxies for such scoped beans by specifying 'false' for the value of the 'proxy-target-class' attribute of the <aop:scoped-proxy/> element. Using JDK interface-based proxies does mean that you don't need any additional libraries on your application's classpath to effect such proxying, but it does mean that the class of the scoped bean must implement at least one interface, and all of the collaborators into which the scoped bean is injected must be referencing the bean via one of its interfaces.

Spring AOP can also use CGLIB proxies. This is necessary to proxy classes, rather than interfaces. CGLIB is used by default if a business object does not implement an interface. As it is good practice to program to interfaces rather than classes, business classes normally will implement one or more business interfaces. It is possible to force the use of CGLIB, in those (hopefully rare) cases where you need to advise a method that is not declared on an interface, or where you need to pass a proxied object to a method as a concrete type.

Saturday, May 16, 2009

Hibernate Mapping with parent child relation mapping into same tables

Consider cases when you have parent child relations in the same tables, this becomes very difficult to handle.

In most cases we seperate out mapping of maintaining this parent child relation into another table.

Lets consider an example

we have category which can have subcategories and both these persist on the same table.

Example : Electronics can have subcategory camera, and further camera can have its subcategories.


@Entity
@Table(name = "t_product_category")
public class ProductCategory {

@Id
@GeneratedValue
@Column(name = "f_category_id")
private int categoryId;

@Column(name = "f_category_name")
private String categoryName;

/* The following onetomany relations says that one ProductCategory can have many childrens of teh same type(ProductCategory) identified by
a collection(Set) children.
The initialisation is set to EAGER meaning when you fetch the parent product category all its childeren are automatically
loaded */

@OneToMany(mappedBy = "parent" ,fetch =FetchType.EAGER)
private Set<ProductCategory> children;

/* The following many to one relation means that many(children) of ProductCategory can have a parent of the same kind identified by
parent */


@ManyToOne
@JoinColumn(name="f_parent")
private ProductCategory parent;

public Set<ProductCategory> getChildren() {
return children;
}

public void setChildren(Set<ProductCategory> children) {
this.children = children;
}

public ProductCategory getParent() {
return parent;
}

public void setParent(ProductCategory parent) {
this.parent = parent;
}


Just by mentioning the two mapping and the corresponding getters & setters our relationship is ready.

Database table looks like this

CREATE TABLE `t_product_category` (
`F_CATEGORY_ID` int(11) NOT NULL auto_increment,
`F_CATEGORY_NAME` varchar(150) NOT NULL,
`F_PARENT` int(11) default NULL,
PRIMARY KEY (`CATEGORY_ID`), .......}

 
Free Domain Names @ .co.nr!