cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cschnei...@apache.org
Subject svn commit: r1240054 - in /cxf/trunk: api/src/main/java/org/apache/cxf/annotations/ api/src/main/java/org/apache/cxf/clustering/ api/src/main/java/org/apache/cxf/endpoint/ rt/ rt/core/src/main/java/org/apache/cxf/clustering/ rt/core/src/main/java/org/a...
Date Fri, 03 Feb 2012 09:57:18 GMT
Author: cschneider
Date: Fri Feb  3 09:57:16 2012
New Revision: 1240054

URL: http://svn.apache.org/viewvc?rev=1240054&view=rev
Log:
CXF-3352 Move clustering support into a separate module

Added:
    cxf/trunk/api/src/main/java/org/apache/cxf/annotations/EvaluateAllEndpoints.java
    cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/ConduitSelectorHolder.java
    cxf/trunk/rt/features/
    cxf/trunk/rt/features/clustering/   (with props)
    cxf/trunk/rt/features/clustering/pom.xml
    cxf/trunk/rt/features/clustering/src/
    cxf/trunk/rt/features/clustering/src/main/
    cxf/trunk/rt/features/clustering/src/main/java/
    cxf/trunk/rt/features/clustering/src/main/java/org/
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/AbstractStaticFailoverStrategy.java
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverFeature.java
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverStrategy.java
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorFeature.java
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorTargetSelector.java
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/Messages.properties
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/RandomStrategy.java
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/RetryStrategy.java
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/SequentialStrategy.java
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/FailoverBeanDefinitionParser.java
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/LoadDistributorBeanDefinitionParser.java
    cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/NamespaceHandler.java
    cxf/trunk/rt/features/clustering/src/main/resources/
    cxf/trunk/rt/features/clustering/src/main/resources/META-INF/
    cxf/trunk/rt/features/clustering/src/main/resources/META-INF/spring.handlers
Removed:
    cxf/trunk/api/src/main/java/org/apache/cxf/clustering/
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/
Modified:
    cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/Client.java
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java
    cxf/trunk/rt/core/src/main/resources/META-INF/spring.handlers
    cxf/trunk/rt/frontend/jaxrs/pom.xml
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientConfiguration.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/features/clustering/FailoverFeature.java
    cxf/trunk/rt/pom.xml
    cxf/trunk/rt/rs/extensions/providers/   (props changed)
    cxf/trunk/systests/jaxrs/pom.xml
    cxf/trunk/systests/uncategorized/pom.xml
    cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/clustering/FailoverTest.java

Added: cxf/trunk/api/src/main/java/org/apache/cxf/annotations/EvaluateAllEndpoints.java
URL: http://svn.apache.org/viewvc/cxf/trunk/api/src/main/java/org/apache/cxf/annotations/EvaluateAllEndpoints.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/api/src/main/java/org/apache/cxf/annotations/EvaluateAllEndpoints.java (added)
+++ cxf/trunk/api/src/main/java/org/apache/cxf/annotations/EvaluateAllEndpoints.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marker for CXF Features. If a client or endpoint declaration has a Feature with this annotation then
+ * CXF will evaluate all Endpoints of the respective service instead of only the used endpoint.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Target({ ElementType.TYPE })
+public @interface EvaluateAllEndpoints {
+
+}

Modified: cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/Client.java
URL: http://svn.apache.org/viewvc/cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/Client.java?rev=1240054&r1=1240053&r2=1240054&view=diff
==============================================================================
--- cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/Client.java (original)
+++ cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/Client.java Fri Feb  3 09:57:16 2012
@@ -31,7 +31,7 @@ import org.apache.cxf.service.model.Bind
 import org.apache.cxf.transport.Conduit;
 import org.apache.cxf.transport.MessageObserver;
 
-public interface Client extends InterceptorProvider, MessageObserver {
+public interface Client extends InterceptorProvider, MessageObserver, ConduitSelectorHolder {
     String REQUEST_CONTEXT = "RequestContext";
     String RESPONSE_CONTEXT = "ResponseContext";
     String KEEP_CONDUIT_ALIVE = "KeepConduitAlive";

Added: cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/ConduitSelectorHolder.java
URL: http://svn.apache.org/viewvc/cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/ConduitSelectorHolder.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/ConduitSelectorHolder.java (added)
+++ cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/ConduitSelectorHolder.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.endpoint;
+
+public interface ConduitSelectorHolder {
+    ConduitSelector getConduitSelector();
+    
+    void setConduitSelector(ConduitSelector conduitSelector);
+}

Modified: cxf/trunk/rt/core/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java?rev=1240054&r1=1240053&r2=1240054&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java (original)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java Fri Feb  3 09:57:16 2012
@@ -57,9 +57,9 @@ import org.w3c.dom.DOMError;
 import org.w3c.dom.DOMErrorHandler;
 
 import org.apache.cxf.BusException;
+import org.apache.cxf.annotations.EvaluateAllEndpoints;
 import org.apache.cxf.binding.BindingFactoryManager;
 import org.apache.cxf.catalog.CatalogXmlSchemaURIResolver;
-import org.apache.cxf.clustering.FailoverFeature;
 import org.apache.cxf.common.WSDLConstants;
 import org.apache.cxf.common.classloader.ClassLoaderUtils;
 import org.apache.cxf.common.i18n.Message;
@@ -399,12 +399,13 @@ public class ReflectionServiceFactoryBea
         boolean setEPName = true;
         if (features != null) {
             for (AbstractFeature f : features) {
-                if (f instanceof FailoverFeature) {
+                if (f.getClass().isAnnotationPresent(EvaluateAllEndpoints.class)) {
                     setEPName = false;
                 }
             }
         }
         if (setEPName) {
+            // CXF will only evaluate this endpoint
             factory.setEndpointName(getEndpointName(false));
         }
         sendEvent(Event.WSDL_LOADED, factory.getDefinition());

Modified: cxf/trunk/rt/core/src/main/resources/META-INF/spring.handlers
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/resources/META-INF/spring.handlers?rev=1240054&r1=1240053&r2=1240054&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/resources/META-INF/spring.handlers (original)
+++ cxf/trunk/rt/core/src/main/resources/META-INF/spring.handlers Fri Feb  3 09:57:16 2012
@@ -18,5 +18,4 @@
 #    under the License.
 #
 #
-http\://cxf.apache.org/clustering=org.apache.cxf.clustering.spring.NamespaceHandler
 http\://cxf.apache.org/core=org.apache.cxf.bus.spring.NamespaceHandler

Propchange: cxf/trunk/rt/features/clustering/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Feb  3 09:57:16 2012
@@ -0,0 +1,5 @@
+.checkstyle
+.classpath
+.project
+.settings
+target

Added: cxf/trunk/rt/features/clustering/pom.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/pom.xml?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/pom.xml (added)
+++ cxf/trunk/rt/features/clustering/pom.xml Fri Feb  3 09:57:16 2012
@@ -0,0 +1,80 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.cxf</groupId>
+    <artifactId>cxf-rt-features-clustering</artifactId>
+    <packaging>jar</packaging>
+    <version>2.6.0-SNAPSHOT</version>
+    <name>Apache CXF Runtime Clustering</name>
+    <description>Failover and loadbalancing support</description>
+    <url>http://cxf.apache.org</url>
+
+    <parent>
+        <groupId>org.apache.cxf</groupId>
+        <artifactId>cxf-parent</artifactId>
+        <version>2.6.0-SNAPSHOT</version>
+        <relativePath>../../../parent/pom.xml</relativePath>
+    </parent>
+    <properties>
+        <cxf.bundle.activator>org.apache.cxf.transport.http.osgi.HTTPTransportActivator</cxf.bundle.activator>
+        <cxf.osgi.import>
+            *
+        </cxf.osgi.import>
+        <cxf.osgi.export>
+            *
+        </cxf.osgi.export>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
+</project>

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/AbstractStaticFailoverStrategy.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/AbstractStaticFailoverStrategy.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/AbstractStaticFailoverStrategy.java (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/AbstractStaticFailoverStrategy.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,165 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.clustering;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.service.model.ServiceInfo;
+
+/**
+ * Failover strategy based on a static cluster represented by
+ * multiple endpoints associated with the same service instance.
+ */
+public abstract class AbstractStaticFailoverStrategy implements FailoverStrategy {
+    private static final Logger LOG =
+        LogUtils.getL7dLogger(AbstractStaticFailoverStrategy.class);
+
+    private List<String> alternateAddresses;
+    private long delayBetweenRetries;
+
+    public void setDelayBetweenRetries(long delay) {
+        this.delayBetweenRetries = delay;
+    }
+    
+    public long getDelayBetweenRetries() {
+        return this.delayBetweenRetries;
+    }
+    
+    public void setAlternateAddresses(List<String> alternateAddresses) {
+        this.alternateAddresses = alternateAddresses;
+    }
+   
+    /**
+     * Get the alternate addresses for this invocation.
+     * 
+     * @param exchange the current Exchange
+     * @return a List of alternate addresses if available
+     */
+    public List<String> getAlternateAddresses(Exchange exchange) {
+        return alternateAddresses != null
+               ? new ArrayList<String>(alternateAddresses)
+               : null;
+    }
+
+    /**
+     * Select one of the alternate addresses for a retried invocation.
+     * 
+     * @param a List of alternate addresses if available
+     * @return the selected address
+     */
+    public String selectAlternateAddress(List<String> alternates) {
+        String selected = null;
+        if (alternates != null && alternates.size() > 0) {
+            selected = getNextAlternate(alternates);
+            LOG.log(Level.WARNING,
+                    "FAILING_OVER_TO_ADDRESS_OVERRIDE",
+                    selected);
+        } else {
+            LOG.warning("NO_ALTERNATE_TARGETS_REMAIN");
+        }
+        return selected;
+    }
+
+    /**
+     * Get the alternate endpoints for this invocation.
+     * 
+     * @param exchange the current Exchange
+     * @return a List of alternate endpoints if available
+     */
+    public List<Endpoint> getAlternateEndpoints(Exchange exchange) {
+        return getEndpoints(exchange, false);
+    }
+    
+    /**
+     * Select one of the alternate endpoints for a retried invocation.
+     * 
+     * @param a List of alternate endpoints if available
+     * @return the selected endpoint
+     */
+    public Endpoint selectAlternateEndpoint(List<Endpoint> alternates) {
+        Endpoint selected = null;
+        if (alternates != null && alternates.size() > 0) {
+            selected = getNextAlternate(alternates);
+            LOG.log(Level.WARNING,
+                    "FAILING_OVER_TO_ALTERNATE_ENDPOINT",
+                     new Object[] {selected.getEndpointInfo().getName(),
+                                   selected.getEndpointInfo().getAddress()});
+        } else {
+            LOG.warning("NO_ALTERNATE_TARGETS_REMAIN");
+        }
+        return selected;
+    }
+    
+    /**
+     * Get the endpoints for this invocation.
+     * 
+     * @param exchange the current Exchange
+     * @param acceptCandidatesWithSameAddress true to accept candidates with the same address
+     * @return a List of alternate endpoints if available
+     */
+    protected List<Endpoint> getEndpoints(Exchange exchange, boolean acceptCandidatesWithSameAddress) {
+        Endpoint endpoint = exchange.get(Endpoint.class);
+        Collection<ServiceInfo> services = endpoint.getService().getServiceInfos();
+        QName currentBinding = endpoint.getBinding().getBindingInfo().getName();
+        List<Endpoint> alternates = new ArrayList<Endpoint>();
+        for (ServiceInfo service : services) {
+            Collection<EndpointInfo> candidates = service.getEndpoints();
+            for (EndpointInfo candidate : candidates) {
+                QName candidateBinding = candidate.getBinding().getName();
+                if (candidateBinding.equals(currentBinding)) {
+                    if (acceptCandidatesWithSameAddress || !candidate.getAddress().equals(
+                             endpoint.getEndpointInfo().getAddress())) {
+                        Endpoint alternate =
+                            endpoint.getService().getEndpoints().get(candidate.getName());
+                        if (alternate != null) {
+                            LOG.log(Level.INFO,
+                                    "FAILOVER_CANDIDATE_ACCEPTED",
+                                    candidate.getName());
+                            alternates.add(alternate);
+                        }
+                    }
+                } else {
+                    LOG.log(Level.INFO,
+                            "FAILOVER_CANDIDATE_REJECTED",
+                            new Object[] {candidate.getName(), candidateBinding});
+                }
+            }
+        }
+        return alternates;
+    }
+
+    /**
+     * Get next alternate endpoint.
+     * 
+     * @param alternates non-empty List of alternate endpoints 
+     * @return
+     */
+    protected abstract <T> T getNextAlternate(List<T> alternates);
+}

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverFeature.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverFeature.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverFeature.java (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverFeature.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,84 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.clustering;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.annotations.EvaluateAllEndpoints;
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.endpoint.ConduitSelector;
+import org.apache.cxf.endpoint.ConduitSelectorHolder;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.feature.AbstractFeature;
+import org.apache.cxf.interceptor.InterceptorProvider;
+
+/**
+ * This feature may be applied to a Client so as to enable
+ * failover from the initial target endpoint to any other
+ * compatible endpoint for the target service.
+ */
+@NoJSR250Annotations
+@EvaluateAllEndpoints
+public class FailoverFeature extends AbstractFeature {
+
+    private FailoverStrategy failoverStrategy;
+    private FailoverTargetSelector targetSelector;
+    
+    @Override
+    protected void initializeProvider(InterceptorProvider provider, Bus bus) {
+        if (provider instanceof ConduitSelectorHolder) {
+            ConduitSelectorHolder csHolder = (ConduitSelectorHolder) provider;
+            Endpoint endpoint = csHolder.getConduitSelector().getEndpoint();
+            ConduitSelector conduitSelector = initTargetSelector(endpoint);
+            csHolder.setConduitSelector(conduitSelector);
+        }
+    }
+
+    @Override
+    public void initialize(Client client, Bus bus) {
+        ConduitSelector selector = initTargetSelector(client.getConduitSelector().getEndpoint());
+        client.setConduitSelector(selector);
+    }
+
+    protected ConduitSelector initTargetSelector(Endpoint endpoint) {
+        FailoverTargetSelector selector = getTargetSelector();
+        selector.setEndpoint(endpoint);
+        selector.setStrategy(getStrategy());
+        return selector;
+    }
+    
+    protected FailoverTargetSelector getTargetSelector() {
+        if (this.targetSelector == null) {
+            this.targetSelector = new FailoverTargetSelector();
+        }
+        return this.targetSelector;
+    }
+    
+    public void setTargetSelector(FailoverTargetSelector selector) {
+        this.targetSelector = selector;
+    }
+    
+    public void setStrategy(FailoverStrategy strategy) {
+        failoverStrategy = strategy;
+    }
+    
+    public FailoverStrategy getStrategy()  {
+        return failoverStrategy;
+    }
+}

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverStrategy.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverStrategy.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverStrategy.java (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverStrategy.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.clustering;
+
+import java.util.List;
+
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.message.Exchange;
+
+/**
+ * Supports pluggable strategies for alternate endpoint selection on
+ * failover.
+ */
+public interface FailoverStrategy {
+    /**
+     * Get the alternate endpoints for this invocation.
+     * 
+     * @param exchange the current Exchange     
+     * @return a failover endpoint if one is available
+     */
+    List<Endpoint> getAlternateEndpoints(Exchange exchange);
+    
+    /**
+     * Select one of the alternate endpoints for a retried invocation.
+     * 
+     * @param alternates List of alternate endpoints if available
+     * @return the selected endpoint
+     */
+    Endpoint selectAlternateEndpoint(List<Endpoint> alternates);
+
+    /**
+     * Get the alternate addresses for this invocation.
+     * These addresses over-ride any addresses specified in the WSDL.
+     * 
+     * @param exchange the current Exchange     
+     * @return a failover endpoint if one is available
+     */
+    List<String> getAlternateAddresses(Exchange exchange);
+
+    /**
+     * Select one of the alternate addresses for a retried invocation.
+     * 
+     * @param addresses List of alternate addresses if available
+     * @return the selected address
+     */
+    String selectAlternateAddress(List<String> addresses);
+}

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,390 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.clustering;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.endpoint.AbstractConduitSelector;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.endpoint.Retryable;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.service.model.BindingOperationInfo;
+import org.apache.cxf.transport.Conduit;
+
+
+/**
+ * Implements a target selection strategy based on failover to an 
+ * alternate target endpoint when a transport level failure is 
+ * encountered.
+ * Note that this feature changes the conduit on the fly and thus makes
+ * the Client not thread safe.
+ */
+public class FailoverTargetSelector extends AbstractConduitSelector {
+
+    private static final Logger LOG =
+        LogUtils.getL7dLogger(FailoverTargetSelector.class);
+    protected Map<InvocationKey, InvocationContext> inProgress;
+    protected FailoverStrategy failoverStrategy;
+    
+    /**
+     * Normal constructor.
+     */
+    public FailoverTargetSelector() {
+        this(null);
+    }
+    
+    /**
+     * Constructor, allowing a specific conduit to override normal selection.
+     * 
+     * @param c specific conduit
+     */
+    public FailoverTargetSelector(Conduit c) {
+        super(c);
+        inProgress = new ConcurrentHashMap<InvocationKey, InvocationContext>();
+    }
+    
+    /**
+     * Called prior to the interceptor chain being traversed.
+     * 
+     * @param message the current Message
+     */
+    public synchronized void prepare(Message message) {
+        Exchange exchange = message.getExchange();
+        InvocationKey key = new InvocationKey(exchange);
+        if (!inProgress.containsKey(key)) {
+            Endpoint endpoint = exchange.get(Endpoint.class);
+            BindingOperationInfo bindingOperationInfo =
+                exchange.getBindingOperationInfo();
+            Object[] params = message.getContent(List.class).toArray();
+            Map<String, Object> context =
+                CastUtils.cast((Map<?, ?>)message.get(Message.INVOCATION_CONTEXT));
+            InvocationContext invocation = 
+                new InvocationContext(endpoint, 
+                                      bindingOperationInfo,
+                                      params,
+                                      context);
+            inProgress.put(key, invocation);
+        }
+    }
+
+    /**
+     * Called when a Conduit is actually required.
+     * 
+     * @param message
+     * @return the Conduit to use for mediation of the message
+     */
+    public Conduit selectConduit(Message message) {
+        return getSelectedConduit(message);
+    }
+
+    /**
+     * Called on completion of the MEP for which the Conduit was required.
+     * 
+     * @param exchange represents the completed MEP
+     */
+    public void complete(Exchange exchange) {
+        InvocationKey key = new InvocationKey(exchange);
+        InvocationContext invocation = null;
+        synchronized (this) {
+            invocation = inProgress.get(key);
+        }
+        boolean failover = false;
+        if (requiresFailover(exchange)) {
+            Endpoint failoverTarget = getFailoverTarget(exchange, invocation);
+            if (failoverTarget != null) {
+                setEndpoint(failoverTarget);
+                selectedConduit.close();
+                selectedConduit = null;
+                Exception prevExchangeFault =
+                    (Exception)exchange.remove(Exception.class.getName());
+                Message outMessage = exchange.getOutMessage();
+                Exception prevMessageFault =
+                    outMessage.getContent(Exception.class);
+                outMessage.setContent(Exception.class, null);
+                overrideAddressProperty(invocation.getContext());
+                Retryable retry = exchange.get(Retryable.class);
+                exchange.clear();
+                if (retry != null) {
+                    try {
+                        failover = true;
+                        long delay = getDelayBetweenRetries();
+                        if (delay > 0) {
+                            Thread.sleep(delay);
+                        }
+                        retry.invoke(invocation.getBindingOperationInfo(),
+                                     invocation.getParams(),
+                                     invocation.getContext(),
+                                     exchange);
+                    } catch (Exception e) {
+                        if (exchange.get(Exception.class) != null) {
+                            exchange.put(Exception.class, prevExchangeFault);
+                        }
+                        if (outMessage.getContent(Exception.class) != null) {
+                            outMessage.setContent(Exception.class,
+                                                  prevMessageFault);
+                        }
+                    }
+                }
+            } else {
+                setEndpoint(invocation.retrieveOriginalEndpoint(endpoint));
+            }
+        }
+        if (!failover) {
+            getLogger().info("FAILOVER_NOT_REQUIRED");
+            synchronized (this) {
+                inProgress.remove(key);
+            }
+            super.complete(exchange);
+        }
+    }
+    
+    /**
+     * @param strategy the FailoverStrategy to use
+     */
+    public synchronized void setStrategy(FailoverStrategy strategy) {
+        getLogger().log(Level.INFO, "USING_STRATEGY", new Object[] {strategy});
+        failoverStrategy = strategy;
+    }
+    
+    /**
+     * @return strategy the FailoverStrategy to use
+     */    
+    public synchronized FailoverStrategy getStrategy()  {
+        if (failoverStrategy == null) {
+            failoverStrategy = new SequentialStrategy();
+            getLogger().log(Level.INFO,
+                            "USING_STRATEGY",
+                            new Object[] {failoverStrategy});
+        }
+        return failoverStrategy;
+    }
+
+    /**
+     * @return the logger to use
+     */
+    protected Logger getLogger() {
+        return LOG;
+    }
+
+    /**
+     * Returns delay (in milliseconds) between retries
+     * @return delay, 0 means no delay
+     */
+    protected long getDelayBetweenRetries() {
+        FailoverStrategy strategy = getStrategy();
+        if (strategy instanceof AbstractStaticFailoverStrategy) {
+            return ((AbstractStaticFailoverStrategy)strategy).getDelayBetweenRetries();
+        }
+        //perhaps supporting FailoverTargetSelector specific property can make sense too
+        return 0;
+    }
+    
+    /**
+     * Check if the exchange is suitable for a failover.
+     * 
+     * @param exchange the current Exchange
+     * @return boolean true if a failover should be attempted
+     */
+    protected boolean requiresFailover(Exchange exchange) {
+        Message outMessage = exchange.getOutMessage();
+        Exception ex = outMessage.get(Exception.class) != null
+                       ? outMessage.get(Exception.class)
+                       : exchange.get(Exception.class);
+        getLogger().log(Level.FINE,
+                        "CHECK_LAST_INVOKE_FAILED",
+                        new Object[] {ex != null});
+        Throwable curr = ex;
+        boolean failover = false;
+        while (curr != null) {
+            failover = curr instanceof java.io.IOException;
+            curr = curr.getCause();
+        }
+        if (ex != null) {
+            getLogger().log(Level.INFO,
+                            "CHECK_FAILURE_IN_TRANSPORT",
+                            new Object[] {ex, failover});
+        }
+        return failover;
+    }
+    
+    /**
+     * Get the failover target endpoint, if a suitable one is available.
+     * 
+     * @param exchange the current Exchange
+     * @param invocation the current InvocationContext
+     * @return a failover endpoint if one is available
+     */
+    protected Endpoint getFailoverTarget(Exchange exchange,
+                                       InvocationContext invocation) {
+        List<String> alternateAddresses = null;
+        if (!invocation.hasAlternates()) {
+            // no previous failover attempt on this invocation
+            //
+            alternateAddresses = 
+                getStrategy().getAlternateAddresses(exchange);
+            if (alternateAddresses != null) {
+                invocation.setAlternateAddresses(alternateAddresses);
+            } else {
+                invocation.setAlternateEndpoints(
+                    getStrategy().getAlternateEndpoints(exchange));
+            }
+        } else {
+            alternateAddresses = invocation.getAlternateAddresses();
+        }
+
+        Endpoint failoverTarget = null;
+        if (alternateAddresses != null) {
+            String alternateAddress = 
+                getStrategy().selectAlternateAddress(alternateAddresses);
+            if (alternateAddress != null) {
+                // re-use current endpoint
+                //
+                failoverTarget = getEndpoint();
+
+                failoverTarget.getEndpointInfo().setAddress(alternateAddress);
+            }
+        } else {
+            failoverTarget = getStrategy().selectAlternateEndpoint(
+                                 invocation.getAlternateEndpoints());
+        }
+        return failoverTarget;
+    }
+    
+    /**
+     * Override the ENDPOINT_ADDRESS property in the request context
+     * 
+     * @param context the request context
+     */
+    protected void overrideAddressProperty(Map<String, Object> context) {
+        Map<String, Object> requestContext =
+            CastUtils.cast((Map<?, ?>)context.get(Client.REQUEST_CONTEXT));
+        if (requestContext != null) {
+            requestContext.put(Message.ENDPOINT_ADDRESS,
+                               getEndpoint().getEndpointInfo().getAddress());
+            requestContext.put("javax.xml.ws.service.endpoint.address",
+                               getEndpoint().getEndpointInfo().getAddress());
+        }
+    }
+            
+    /**
+     * Used to wrap an Exchange for usage as a Map key. The raw Exchange
+     * is not a suitable key type, as the hashCode is computed from its
+     * current contents, which may obviously change over the lifetime of
+     * an invocation.
+     */
+    protected static class InvocationKey {
+        private Exchange exchange;
+        
+        InvocationKey(Exchange ex) {
+            exchange = ex;     
+        }
+        
+        @Override
+        public int hashCode() {
+            return System.identityHashCode(exchange);
+        }
+        
+        @Override
+        public boolean equals(Object o) {
+            return o instanceof InvocationKey
+                   && exchange == ((InvocationKey)o).exchange;
+        }
+    }
+
+
+    /**
+     * Records the context of an invocation.
+     */
+    protected class InvocationContext {
+        private Endpoint originalEndpoint;
+        private String originalAddress;
+        private BindingOperationInfo bindingOperationInfo;
+        private Object[] params; 
+        private Map<String, Object> context;
+        private List<Endpoint> alternateEndpoints;
+        private List<String> alternateAddresses;
+        
+        InvocationContext(Endpoint endpoint,
+                          BindingOperationInfo boi,
+                          Object[] prms, 
+                          Map<String, Object> ctx) {
+            originalEndpoint = endpoint;
+            originalAddress = endpoint.getEndpointInfo().getAddress();
+            bindingOperationInfo = boi;
+            params = prms;
+            context = ctx;
+        }
+
+        Endpoint retrieveOriginalEndpoint(Endpoint endpoint) {
+            if (endpoint != originalEndpoint) {
+                getLogger().log(Level.INFO,
+                                "REVERT_TO_ORIGINAL_TARGET",
+                                endpoint.getEndpointInfo().getName());
+            }
+            if (!endpoint.getEndpointInfo().getAddress().equals(originalAddress)) {
+                endpoint.getEndpointInfo().setAddress(originalAddress);
+                getLogger().log(Level.INFO,
+                                "REVERT_TO_ORIGINAL_ADDRESS",
+                                endpoint.getEndpointInfo().getAddress());
+            }
+            return originalEndpoint;
+        }
+        
+        BindingOperationInfo getBindingOperationInfo() {
+            return bindingOperationInfo;
+        }
+        
+        Object[] getParams() {
+            return params;
+        }
+        
+        Map<String, Object> getContext() {
+            return context;
+        }
+        
+        List<Endpoint> getAlternateEndpoints() {
+            return alternateEndpoints;
+        }
+
+        List<String> getAlternateAddresses() {
+            return alternateAddresses;
+        }
+
+        void setAlternateEndpoints(List<Endpoint> alternates) {
+            alternateEndpoints = alternates;
+        }
+
+        void setAlternateAddresses(List<String> alternates) {
+            alternateAddresses = alternates;
+        }
+
+        boolean hasAlternates() {
+            return !(alternateEndpoints == null && alternateAddresses == null);
+        }
+    }    
+}

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorFeature.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorFeature.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorFeature.java (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorFeature.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.clustering;
+
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+
+/**
+ * This feature may be applied to a Client so as to enable
+ * load distribution amongst a set of target endpoints or addresses
+ * Note that this feature changes the conduit on the fly and thus makes
+ * the Client not thread safe.
+ */
+@NoJSR250Annotations
+public class LoadDistributorFeature extends FailoverFeature {
+
+    @Override
+    protected FailoverTargetSelector getTargetSelector() {
+        return new LoadDistributorTargetSelector();
+    }
+}

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorTargetSelector.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorTargetSelector.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorTargetSelector.java (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorTargetSelector.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,221 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.clustering;
+
+import java.util.List;
+import java.util.logging.Logger;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.transport.Conduit;
+
+/**
+ *
+ * @author jtalbut
+ * 
+ * The LoadDistributorTargetSelector attempts to do the same job as the 
+ * FailoverTargetSelector, but to choose an alternate target on every request
+ * rather than just when a fault occurs.
+ * The LoadDistributorTargetSelector uses the same FailoverStrategy interface as 
+ * the FailoverTargetSelector, but has a few significant limitations:
+ * 1. Because the LoadDistributorTargetSelector needs to maintain a list of targets
+ *    between calls it has to obtain that list without reference to a Message.
+ *    Most FailoverStrategy classes can support this for addresses, but it cannot
+ *    be supported for endpoints.
+ *    If the list of targets cannot be obtained without reference to a Message then
+ *    the list will still be obtained but it will be specific to the Message and thus
+ *    discarded after this message has been processed.  As a consequence, if the
+ *    strategy chosen is a simple sequential one the first item in the list will
+ *    be chosen every time.
+ *    Conclusion: Be aware that if you are working with targets that are 
+ *    dependent on the Message the process will be less efficient and that the
+ *    SequentialStrategy will not distribute the load at all.
+ * 2. The AbstractStaticFailoverStrategy base class excludes the 'default' endpoint
+ *    from the list of alternate endpoints.
+ *    If alternate endpoints (as opposed to alternate addresses) are to be used
+ *    you should probably ensure that your FailoverStrategy overrides getAlternateEndpoints
+ *    and calls getEndpoints with acceptCandidatesWithSameAddress = true.
+ */
+public class LoadDistributorTargetSelector extends FailoverTargetSelector {
+    private static final Logger LOG = LogUtils.getL7dLogger(
+                        LoadDistributorTargetSelector.class);
+    private static final String IS_DISTRIBUTED = 
+            "org.apache.cxf.clustering.LoadDistributorTargetSelector.IS_DISTRIBUTED";
+
+    private List<String> addressList;
+
+    private boolean failover = true;
+
+    /**
+     * Normal constructor.
+     */
+    public LoadDistributorTargetSelector() {
+        this(null);
+    }
+
+    /**
+     * Constructor, allowing a specific conduit to override normal selection.
+     *
+     * @param c specific conduit
+     */
+    public LoadDistributorTargetSelector(Conduit c) {
+        super(c);
+    }
+
+    public boolean isFailover() {
+        return failover;
+    }
+
+    public void setFailover(boolean failover) {
+        this.failover = failover;
+    }
+
+    @Override
+    protected java.util.logging.Logger getLogger() {
+        return LOG;
+    }
+
+    /**
+     * Called when a Conduit is actually required.
+     *
+     * @param message
+     * @return the Conduit to use for mediation of the message
+     */
+    public Conduit selectConduit(Message message) {
+        Exchange exchange = message.getExchange();
+        InvocationKey key = new InvocationKey(exchange);
+        InvocationContext invocation = inProgress.get(key);
+        if ((invocation != null) && !invocation.getContext().containsKey(IS_DISTRIBUTED)) {
+            Endpoint target = getDistributionTarget(exchange, invocation);
+            if (target != null) {
+                setEndpoint(target);
+                if (selectedConduit != null) {
+                    selectedConduit.close();
+                    selectedConduit = null;
+                }
+                message.put(Message.ENDPOINT_ADDRESS, target.getEndpointInfo().getAddress());
+                overrideAddressProperty(invocation.getContext());
+                invocation.getContext().put(IS_DISTRIBUTED, null);
+            }
+        }
+        return getSelectedConduit(message);
+    }
+
+    /**
+     * Get the failover target endpoint, if a suitable one is available.
+     *
+     * @param exchange the current Exchange
+     * @param invocation the current InvocationContext
+     * @return a failover endpoint if one is available
+     * 
+     * Note: The only difference between this and the super implementation is
+     * that the current (failed) address is removed from the list set of alternates,
+     * it could be argued that that change should be in the super implementation
+     * but I'm not sure of the impact.
+     */
+    protected Endpoint getFailoverTarget(Exchange exchange,
+                                       InvocationContext invocation) {
+        List<String> alternateAddresses = null;
+        if (!invocation.hasAlternates()) {
+            // no previous failover attempt on this invocation
+            //
+            alternateAddresses = 
+                getStrategy().getAlternateAddresses(exchange);
+            if (alternateAddresses != null) {
+                alternateAddresses.remove(exchange.getEndpoint().getEndpointInfo().getAddress());
+                invocation.setAlternateAddresses(alternateAddresses);
+            } else {
+                invocation.setAlternateEndpoints(
+                    getStrategy().getAlternateEndpoints(exchange));
+            }
+        } else {
+            alternateAddresses = invocation.getAlternateAddresses();
+        }
+
+        Endpoint failoverTarget = null;
+        if (alternateAddresses != null) {
+            String alternateAddress = 
+                getStrategy().selectAlternateAddress(alternateAddresses);
+            if (alternateAddress != null) {
+                // re-use current endpoint
+                //
+                failoverTarget = getEndpoint();
+
+                failoverTarget.getEndpointInfo().setAddress(alternateAddress);
+            }
+        } else {
+            failoverTarget = getStrategy().selectAlternateEndpoint(
+                                 invocation.getAlternateEndpoints());
+        }
+        return failoverTarget;
+    }
+
+    /**
+     * Get the distribution target endpoint, if a suitable one is available.
+     *
+     * @param exchange the current Exchange
+     * @param invocation the current InvocationContext
+     * @return a distribution endpoint if one is available
+     */
+    private Endpoint getDistributionTarget(Exchange exchange,
+                                           InvocationContext invocation) {
+        List<String> alternateAddresses = null;
+        if ((addressList == null) || (addressList.isEmpty())) {
+            try {
+                addressList = getStrategy().getAlternateAddresses(null);
+            } catch (NullPointerException ex) {
+                getLogger().fine("Strategy " + getStrategy().getClass()
+                        + " cannot handle a null argument to getAlternateAddresses: " + ex.toString());
+            }
+        }
+        alternateAddresses = addressList;
+
+        if ((alternateAddresses == null) || (alternateAddresses.isEmpty())) {
+            alternateAddresses = getStrategy().getAlternateAddresses(exchange);
+            if (alternateAddresses != null) {
+                invocation.setAlternateAddresses(alternateAddresses);
+            } else {
+                invocation.setAlternateEndpoints(
+                    getStrategy().getAlternateEndpoints(exchange));
+            }
+        }
+
+        Endpoint distributionTarget = null;
+        if ((alternateAddresses != null) && !alternateAddresses.isEmpty()) {
+            String alternateAddress =
+                getStrategy().selectAlternateAddress(alternateAddresses);
+            if (alternateAddress != null) {
+                // re-use current endpoint
+                distributionTarget = getEndpoint();
+                distributionTarget.getEndpointInfo().setAddress(alternateAddress);
+            }
+        } else {
+            distributionTarget = getStrategy().selectAlternateEndpoint(
+                                 invocation.getAlternateEndpoints());
+        }
+        return distributionTarget;
+    }
+
+    @Override
+    protected boolean requiresFailover(Exchange exchange) {
+        return failover && super.requiresFailover(exchange);
+    }
+
+}

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/Messages.properties
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/Messages.properties?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/Messages.properties (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/Messages.properties Fri Feb  3 09:57:16 2012
@@ -0,0 +1,31 @@
+#
+#
+#    Licensed to the Apache Software Foundation (ASF) under one
+#    or more contributor license agreements. See the NOTICE file
+#    distributed with this work for additional information
+#    regarding copyright ownership. The ASF licenses this file
+#    to you under the Apache License, Version 2.0 (the
+#    "License"); you may not use this file except in compliance
+#    with the License. You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing,
+#    software distributed under the License is distributed on an
+#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#    KIND, either express or implied. See the License for the
+#    specific language governing permissions and limitations
+#    under the License.
+#
+#
+USING_STRATEGY = Using failover strategy {0}
+REVERT_TO_ORIGINAL_TARGET = reverted to original endpoint {0}
+REVERT_TO_ORIGINAL_ADDRESS = reverted to original address {0}
+FAILOVER_NOT_REQUIRED = failover not required
+NO_ALTERNATE_TARGETS_REMAIN = no alternate targets remain => giving up on failover
+CHECK_LAST_INVOKE_FAILED = last invocation raised fault?: {0}
+CHECK_FAILURE_IN_TRANSPORT = failure {0} caused at transport level?: {1}
+FAILOVER_CANDIDATE_ACCEPTED = failover candidate {0} accepted
+FAILOVER_CANDIDATE_REJECTED = failover candidate {0} rejected on binding mismatch
+FAILING_OVER_TO_ALTERNATE_ENDPOINT = failing over to alternate target {0}
+FAILING_OVER_TO_ADDRESS_OVERRIDE = failing over to alternate address {0}

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/RandomStrategy.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/RandomStrategy.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/RandomStrategy.java (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/RandomStrategy.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.clustering;
+
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Failover strategy based on a randomized walk through the
+ * static cluster represented by multiple endpoints associated 
+ * with the same service instance.
+ */
+public class RandomStrategy extends AbstractStaticFailoverStrategy {
+    
+    private Random random;
+    
+    /**
+     * Constructor.
+     */
+    public RandomStrategy() {
+        random = new Random();
+    }
+
+    /**
+     * Get next alternate endpoint.
+     * 
+     * @param alternates non-empty List of alternate endpoints 
+     * @return
+     */
+    protected <T> T getNextAlternate(List<T> alternates) {
+        return alternates.remove(random.nextInt(alternates.size()));
+    }
+}
\ No newline at end of file

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/RetryStrategy.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/RetryStrategy.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/RetryStrategy.java (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/RetryStrategy.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.clustering;
+
+import java.util.List;
+
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.message.Exchange;
+
+/**
+ * This strategy simply retries the invocation using the same Endpoint (CXF-2036).
+ * 
+ * @author Dennis Kieselhorst
+ *
+ */
+public class RetryStrategy extends SequentialStrategy {
+
+    private int maxNumberOfRetries;
+    private int counter;
+    
+    /* (non-Javadoc)
+     * @see org.apache.cxf.clustering.AbstractStaticFailoverStrategy#getAlternateEndpoints(
+     * org.apache.cxf.message.Exchange)
+     */
+    @Override
+    public List<Endpoint> getAlternateEndpoints(Exchange exchange) {
+        return getEndpoints(exchange, stillTheSameAddress());
+    }
+    
+    protected <T> T getNextAlternate(List<T> alternates) {
+        return stillTheSameAddress() ? alternates.get(0) : alternates.remove(0);
+    }
+
+    protected boolean stillTheSameAddress() {
+        if (maxNumberOfRetries == 0) {
+            return true;
+        }
+        // let the target selector move to the next address
+        // and then stay on the same address for maxNumberOfRetries
+        if (++counter <= maxNumberOfRetries) {
+            return true;    
+        } else {
+            counter = 0;
+            return false;
+        }
+    }
+    
+
+    public void setMaxNumberOfRetries(int maxNumberOfRetries) {
+        if (maxNumberOfRetries < 0) {
+            throw new IllegalArgumentException();
+        }
+        this.maxNumberOfRetries = maxNumberOfRetries;
+    }
+
+
+    public int getMaxNumberOfRetries() {
+        return maxNumberOfRetries;
+    }
+
+}
\ No newline at end of file

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/SequentialStrategy.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/SequentialStrategy.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/SequentialStrategy.java (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/SequentialStrategy.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.clustering;
+
+import java.util.List;
+
+/**
+ * Failover strategy based on a sequential walk through the
+ * static cluster represented by multiple endpoints associated 
+ * with the same service instance.
+ */
+public class SequentialStrategy extends AbstractStaticFailoverStrategy {
+
+    /**
+     * Get next alternate endpoint.
+     * 
+     * @param alternates non-empty List of alternate endpoints 
+     * @return
+     */
+    protected <T> T getNextAlternate(List<T> alternates) {
+        return alternates.remove(0);
+    }
+}

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/FailoverBeanDefinitionParser.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/FailoverBeanDefinitionParser.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/FailoverBeanDefinitionParser.java (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/FailoverBeanDefinitionParser.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.clustering.spring;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.clustering.FailoverFeature;
+import org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+
+public class FailoverBeanDefinitionParser extends AbstractBeanDefinitionParser {
+
+    @Override
+    protected Class<?> getBeanClass(Element element) {
+        return FailoverFeature.class;
+    }
+ 
+    @Override
+    protected void mapElement(ParserContext ctx, BeanDefinitionBuilder bean, Element e, String name) {
+        setFirstChildAsProperty(e, ctx, bean, name);
+    }
+}

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/LoadDistributorBeanDefinitionParser.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/LoadDistributorBeanDefinitionParser.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/LoadDistributorBeanDefinitionParser.java (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/LoadDistributorBeanDefinitionParser.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.clustering.spring;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.clustering.LoadDistributorFeature;
+import org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+
+public class LoadDistributorBeanDefinitionParser extends AbstractBeanDefinitionParser {
+
+    @Override
+    protected Class<?> getBeanClass(Element element) {
+        return LoadDistributorFeature.class;
+    }
+ 
+    @Override
+    protected void mapElement(ParserContext ctx, BeanDefinitionBuilder bean, Element e, String name) {
+        setFirstChildAsProperty(e, ctx, bean, name);
+    }
+}

Added: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/NamespaceHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/NamespaceHandler.java?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/NamespaceHandler.java (added)
+++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/spring/NamespaceHandler.java Fri Feb  3 09:57:16 2012
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.clustering.spring;
+
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+
+public class NamespaceHandler extends NamespaceHandlerSupport {
+    public void init() {
+        registerBeanDefinitionParser("failover",
+                                     new FailoverBeanDefinitionParser());
+        registerBeanDefinitionParser("loadDistributor",
+                                     new LoadDistributorBeanDefinitionParser());
+    }
+}

Added: cxf/trunk/rt/features/clustering/src/main/resources/META-INF/spring.handlers
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/resources/META-INF/spring.handlers?rev=1240054&view=auto
==============================================================================
--- cxf/trunk/rt/features/clustering/src/main/resources/META-INF/spring.handlers (added)
+++ cxf/trunk/rt/features/clustering/src/main/resources/META-INF/spring.handlers Fri Feb  3 09:57:16 2012
@@ -0,0 +1,22 @@
+#
+#
+#    Licensed to the Apache Software Foundation (ASF) under one
+#    or more contributor license agreements. See the NOTICE file
+#    distributed with this work for additional information
+#    regarding copyright ownership. The ASF licenses this file
+#    to you under the Apache License, Version 2.0 (the
+#    "License"); you may not use this file except in compliance
+#    with the License. You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing,
+#    software distributed under the License is distributed on an
+#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#    KIND, either express or implied. See the License for the
+#    specific language governing permissions and limitations
+#    under the License.
+#
+#
+http\://cxf.apache.org/clustering=org.apache.cxf.clustering.spring.NamespaceHandler
+

Modified: cxf/trunk/rt/frontend/jaxrs/pom.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/pom.xml?rev=1240054&r1=1240053&r2=1240054&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/pom.xml (original)
+++ cxf/trunk/rt/frontend/jaxrs/pom.xml Fri Feb  3 09:57:16 2012
@@ -66,6 +66,14 @@
             <artifactId>cxf-rt-core</artifactId>
             <version>${project.version}</version>
         </dependency>
+        
+        <!-- Only necessary for the @Deprecated FailoverFeature -->
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-features-clustering</artifactId>
+            <version>${project.version}</version>
+            <optional>true</optional>
+        </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-core</artifactId>
@@ -160,8 +168,4 @@
             </exclusions>
         </dependency> 
     </dependencies>
-    <build>
-        <plugins>
-        </plugins>
-    </build>
 </project>

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientConfiguration.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientConfiguration.java?rev=1240054&r1=1240053&r2=1240054&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientConfiguration.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientConfiguration.java Fri Feb  3 09:57:16 2012
@@ -27,6 +27,7 @@ import org.apache.cxf.Bus;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.ModCountCopyOnWriteArrayList;
 import org.apache.cxf.endpoint.ConduitSelector;
+import org.apache.cxf.endpoint.ConduitSelectorHolder;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.interceptor.Interceptor;
 import org.apache.cxf.interceptor.InterceptorProvider;
@@ -43,7 +44,7 @@ import org.apache.cxf.transport.http.HTT
  * Given an instance with the name 'client', one can access its configuration
  * using a WebClient.getConfig(client) call.
  */
-public class ClientConfiguration implements InterceptorProvider {
+public class ClientConfiguration implements InterceptorProvider, ConduitSelectorHolder {
     private static final Logger LOG = LogUtils.getL7dLogger(ClientConfiguration.class);
     
     private List<Interceptor<? extends Message>> inInterceptors 

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/features/clustering/FailoverFeature.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/features/clustering/FailoverFeature.java?rev=1240054&r1=1240053&r2=1240054&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/features/clustering/FailoverFeature.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/features/clustering/FailoverFeature.java Fri Feb  3 09:57:16 2012
@@ -20,46 +20,17 @@ package org.apache.cxf.jaxrs.features.cl
 
 import java.util.List;
 
-import org.apache.cxf.Bus;
 import org.apache.cxf.clustering.AbstractStaticFailoverStrategy;
 import org.apache.cxf.clustering.FailoverStrategy;
-import org.apache.cxf.clustering.FailoverTargetSelector;
 import org.apache.cxf.common.injection.NoJSR250Annotations;
-import org.apache.cxf.endpoint.ConduitSelector;
-import org.apache.cxf.interceptor.InterceptorProvider;
-import org.apache.cxf.jaxrs.client.ClientConfiguration;
 
 /**
- * This feature may be applied to proxy or HTTP-centric clients
+ * Use the default FailoverFeature instead
  */
+@Deprecated
 @NoJSR250Annotations
 public class FailoverFeature extends org.apache.cxf.clustering.FailoverFeature {
 
-    private FailoverTargetSelector customSelector;
-    
-    @Override
-    public void initialize(InterceptorProvider interceptorProvider, Bus bus) {
-        initialize((ClientConfiguration)interceptorProvider, bus);
-    }
-    
-    public void initialize(ClientConfiguration client, Bus bus) {
-        ConduitSelector selector = initTargetSelector(client.getConduitSelector().getEndpoint());
-        client.setConduitSelector(selector);
-    }
-
-    @Override
-    protected FailoverTargetSelector getTargetSelector() {
-        if (customSelector != null) {
-            return customSelector;
-        } else {
-            return super.getTargetSelector();
-        }
-    }
-    
-    public void setTargetSelector(FailoverTargetSelector selector) {
-        customSelector = selector;
-    }
-    
     @Override
     public FailoverStrategy getStrategy()  {
         FailoverStrategy strategy = super.getStrategy();

Modified: cxf/trunk/rt/pom.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/pom.xml?rev=1240054&r1=1240053&r2=1240054&view=diff
==============================================================================
--- cxf/trunk/rt/pom.xml (original)
+++ cxf/trunk/rt/pom.xml Fri Feb  3 09:57:16 2012
@@ -41,6 +41,7 @@
         <module>databinding/sdo</module>
         <module>databinding/jibx</module>
         <module>bindings</module>
+        <module>features/clustering</module>
         <module>frontend/simple</module>
         <module>frontend/jaxws</module>
         <module>frontend/jaxrs</module>

Propchange: cxf/trunk/rt/rs/extensions/providers/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Feb  3 09:57:16 2012
@@ -0,0 +1 @@
+target

Modified: cxf/trunk/systests/jaxrs/pom.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/pom.xml?rev=1240054&r1=1240053&r2=1240054&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/pom.xml (original)
+++ cxf/trunk/systests/jaxrs/pom.xml Fri Feb  3 09:57:16 2012
@@ -133,6 +133,11 @@
             <artifactId>cxf-rt-transports-jms</artifactId>
             <version>${project.version}</version>
         </dependency>
+         <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-features-clustering</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.activemq</groupId>
             <artifactId>activemq-core</artifactId>

Modified: cxf/trunk/systests/uncategorized/pom.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/uncategorized/pom.xml?rev=1240054&r1=1240053&r2=1240054&view=diff
==============================================================================
--- cxf/trunk/systests/uncategorized/pom.xml (original)
+++ cxf/trunk/systests/uncategorized/pom.xml Fri Feb  3 09:57:16 2012
@@ -132,6 +132,11 @@
         </dependency>
         <dependency>
             <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-features-clustering</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
             <artifactId>cxf-rt-databinding-jaxb</artifactId>
             <version>${project.version}</version>
         </dependency>

Modified: cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/clustering/FailoverTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/clustering/FailoverTest.java?rev=1240054&r1=1240053&r2=1240054&view=diff
==============================================================================
--- cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/clustering/FailoverTest.java (original)
+++ cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/clustering/FailoverTest.java Fri Feb  3 09:57:16 2012
@@ -93,7 +93,7 @@ public class FailoverTest extends Abstra
     @BeforeClass
     public static void startServers() throws Exception {
         assertTrue("server did not launch correctly",
-                   launchServer(Server.class));
+                   launchServer(Server.class, true));
     }
             
     protected String getConfig() {
@@ -452,6 +452,11 @@ public class FailoverTest extends Abstra
     }
     
     
+    /**
+     * Exchange the port number in all service addresses on the bus.  
+     * @param port1 current port
+     * @param port2 new port
+     */
     private void updateWsdlExtensors(String port1, String port2) {
         try {
             Definition def = bus.getExtension(WSDLManager.class)



Mime
View raw message