THIS IS A TEST INSTANCE. ALL YOUR CHANGES WILL BE LOST!!!!
Wiki Markup |
---|
{span:style=font-size:2em;font-weight:bold} JAX-RS: Failover {span}
{toc}
Starting from CXF 2.4.1, CXF JAX-RS clients can be configured for them to become failover-capable.
Core CXF Failover and Load Distribution features are supported.
h1. Failover
Proxies and WebClients can be configured to failover to alternate addresses in case of connection-related failures.
Sequential and Random strategies are supported and implementers can build more sophisticated failover features by retrieving
alternate addresses from locators and other intermediaries.
h2. Spring
{code:xml}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
<util:list id="addressList">
<value>http://localhost:${testutil.ports.Server.1}/rest</value>
<value>http://localhost:${testutil.ports.Server.2}/rest</value>
<value>http://localhost:${testutil.ports.Server.3}/rest</value>
</util:list>
<bean id="SequentialAddresses" class="org.apache.cxf.clustering.SequentialStrategy">
<property name="alternateAddresses">
<ref bean="addressList"/>
</property>
</bean>
<bean id="RandomAddresses" class="org.apache.cxf.clustering.RandomStrategy">
<property name="alternateAddresses">
<ref bean="addressList"/>
</property>
</bean>
<bean id="failover1" class="org.apache.cxf.jaxrs.features.clustering.FailoverFeature">
<property name="strategy" ref="SequentialAddresses"/>
</bean>
<bean id="failover2" class="org.apache.cxf.jaxrs.features.clustering.FailoverFeature">
<property name="strategy" ref="RandomAddresses"/>
</bean>
<jaxrs:client id="failoverSequential" address="http://localhost:8080/initialAddress">
<jaxrs:features>
<ref bean="failover1"/>
</jaxrs:features>
</jaxrs:client>
<jaxrs:client id="failoverRandom" address="http://localhost:8080/initialAddress">
<jaxrs:features>
<ref bean="failover2"/>
</jaxrs:features>
</jaxrs:client>
<bean id="myWebClient" class="org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean"
factory-method="createWebClient">
<property name="address" value="http://some.base.url.that.responds/" />
<property name="features">
<util:list>
<ref bean="failover1"/>
</util:list>
</property>
</bean>
</beans>
{code}
Note that failover feature for jaxrs:client gets configured nearly exactly the same way as it's done for JAX-WS clients. The difference at this stage is that feature class name (org.apache.cxf.jaxrs.features.clustering.FailoverFeature) and a 'strategy' property are 'hidden' for JAX-WS clients due to the use of Spring handlers, example:
{code:xml}
<jaxws:client name="{http://cxf.apache.org/greeter_control}ReplicatedPortA"
createdFromAPI="true">
<jaxws:features>
<clustering:failover>
<clustering:strategy>
<ref bean="SequentialAddresses"/>
</clustering:strategy>
</clustering:failover>
</jaxws:features>
</jaxws:client>
{code}
In other words, JAX-RS clients can not use clustering:failover/clustering:strategy only at this stage, the rest the same. An efoort will be undertaken to make sure this configuration becomes identical for JAX-WS and JAX-RS clients.
h2. Code
{code:java}
org.apache.cxf.jaxrs.features.clustering.FailoverFeature feature =
new org.apache.cxf.jaxrs.features.clustering.FailoverFeature();
List<String> alternateAddresses = new ArrayList<String>();
// addresses are alternate addresses provided at start-up
for (String s : address) {
alternateAddresses.add(s);
}
SequentialStrategy strategy = new SequentialStrategy();
strategy.setAlternateAddresses(alternateAddresses);
feature.setStrategy(strategy);
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
bean.setAddress("http://localhost:8080/inactive-replica");
List<AbstractFeature> features = new ArrayList<AbstractFeature>();
features.add(feature);
bean.setFeatures(features);
// create proxy:
bean.create(BookStore.class);
// create web client
bean.createWebClient();
{code}
h1. Load Distribution
CXF Load Distribution feature is a failover feature which can iterate where alternate addresses not only in case of failures but also after a successful invocation has been done.
It is configured for CXF JAX-RS clients exactly the same way Failover feature is configured, the only difference that a (conduit) selector property is also specified, example:
{code:xml}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
<util:list id="addressList">
<value>http://localhost:${testutil.ports.Server.1}/rest</value>
<value>http://localhost:${testutil.ports.Server.2}/rest</value>
<value>http://localhost:${testutil.ports.Server.3}/rest</value>
</util:list>
<bean id="SequentialAddresses" class="org.apache.cxf.clustering.SequentialStrategy">
<property name="alternateAddresses">
<ref bean="addressList"/>
</property>
</bean>
<bean id="targetSelector" class="org.apache.cxf.clustering.LoadDistributorTargetSelector"/>
<jaxrs:client id="loadDistributionSequential" address="http://localhost:8080/initialAddress">
<jaxrs:features>
<bean class="org.apache.cxf.jaxrs.features.clustering.FailoverFeature">
<property name="strategy" ref="SequentialAddresses"/>
<property name="selector" ref="targetSelector"/>
</bean>
</jaxrs:features>
</jaxrs:client>
{code}
the selector can be set from code like this:
{code:java}
org.apache.cxf.jaxrs.features.clustering.FailoverFeature feature =
new org.apache.cxf.jaxrs.features.clustering.FailoverFeature();
feature.setSelector(new org.apache.cxf.clustering.LoadDistributorTargetSelector());
{code} |