Total Pageviews

Friday 4 January 2013

Spring : Configuring failover in Spring


WebClients can be configured in Spring to handle the failover in case any of the webservice connection fails to respond due to network or server failure or due to any other reason. In order to handle such issues Apache CXF provides Sequential and Random strategies, which are supported and implementers can develop more sophisticated failover features by retrieving alternate addresses.

The above could be achieved by doing the following configurations in spring-servlet.xml (Spring Web Context Configuration file) or whatever else you call it.

Spring-servlet.xml( failover configurations only)
____________________________________________________________________________

<?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:context="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.0.xsd
"
>

<!-- begin: Fail over configurations -->
<util:list id="alternateSerAddresses" list-class="java.util.concurrent.CopyOnWriteArrayList">
    <value>http://hostname:port/servie-location-1</value>
    <value>http://hostname:port/servie-location-2</value>
    <value>http://hostname:port/servie-location-3</value>
</util:list>

<bean id="serviceClientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
   <property name="serviceClass" value="com.soaptopupsuite.EndPointInterface"/>
   <property name="address" value="http://hostname:port/service-default-loc"/>
   <property name="username" value="service-username"/>
   <property name="password" value="service-password"/>
   <property name="features">
    <util:list>
      <bean class="org.apache.cxf.clustering.FailoverFeature">
             <property name="strategy">
                  <bean class="org.apache.cxf.clustering.SequentialStrategy">
                <property name="alternateAddresses" ref="alternateSerAddresses"/>
             </bean>
             </property>
         </bean>
     </util:list>
</property>
</bean>

<bean id="serviceClient" class="com.soaptopupsuite.EndPointInterface" factory-   bean="serviceClientFactory" factory-method="create"/>
<bean id="servicePort" class="com.swaraj.client.WsClient">
   <property name="port" ref="serviceClient" />
</bean>
<!-- end: Fail over configurations -->
</beans>

Here, the client factory does not itself defines the address attribute. It uses that alternateSerAddresses list exclusively throughout all the invocations and primary address exists as default location. SequentialStrategy will use one endpoint after another providing nice round robin implementation (RandomStrategy is available as well, where an end point is picked up randomly). Also in this configuration we will get failoverif any endpoint fails, all endpoints starting from the default one will be examined (except the one that has just failed).


Reference Java Code (Spring 3.1) :

package com.swaraj.client;


@Service
public class WsClient {
/* list of instance variable*/
// web service location
private EndPointInterface port;
// setter injection for EndPointInterface
   public void setPort(EndPointInterface port) {
       this.port = port;
   }
// Invoking web service method on EndPointInterface port.
   public String webSerMethodCall(){
       return port.testCall();
   }
}