cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From egl...@apache.org
Subject svn commit: r538501 - in /incubator/cxf/trunk: api/src/main/java/org/apache/cxf/clustering/ rt/core/src/main/java/org/apache/cxf/clustering/ rt/core/src/main/java/org/apache/cxf/clustering/spring/ systests/src/test/java/org/apache/cxf/systest/clustering/
Date Wed, 16 May 2007 09:34:18 GMT
Author: eglynn
Date: Wed May 16 02:34:04 2007
New Revision: 538501

URL: http://svn.apache.org/viewvc?view=rev&rev=538501
Log:
Adding pluggable random/sequential failover strategy.


Added:
    incubator/cxf/trunk/api/src/main/java/org/apache/cxf/clustering/
    incubator/cxf/trunk/api/src/main/java/org/apache/cxf/clustering/FailoverStrategy.java
  (with props)
    incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/AbstractStaticFailoverStrategy.java
  (with props)
    incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/RandomStrategy.java
  (with props)
    incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/SequentialStrategy.java
  (with props)
Modified:
    incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/FailoverFeature.java
    incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java
    incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/Messages.properties
    incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/spring/FailoverBeanDefinitionParser.java
    incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/clustering/FailoverTest.java
    incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/clustering/failover.xml

Added: incubator/cxf/trunk/api/src/main/java/org/apache/cxf/clustering/FailoverStrategy.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/api/src/main/java/org/apache/cxf/clustering/FailoverStrategy.java?view=auto&rev=538501
==============================================================================
--- incubator/cxf/trunk/api/src/main/java/org/apache/cxf/clustering/FailoverStrategy.java
(added)
+++ incubator/cxf/trunk/api/src/main/java/org/apache/cxf/clustering/FailoverStrategy.java
Wed May 16 02:34:04 2007
@@ -0,0 +1,48 @@
+/**
+ * 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 alternative endpoints for this invocation.
+     * 
+     * @param exchange the current Exchange
+     * @param invocation the current InvocationContext
+     * @return a failover endpoint if one is available
+     */
+    List<Endpoint> getAlternateEndpoints(Exchange exchange);
+    
+    /**
+     * Select one of the alternate endpoints for a retried invocation.
+     * 
+     * @param a List of alternate endpoints if available
+     * @return the selected endpoint
+     */
+    Endpoint selectAlternateEndpoint(List<Endpoint> alternates);
+}

Propchange: incubator/cxf/trunk/api/src/main/java/org/apache/cxf/clustering/FailoverStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/AbstractStaticFailoverStrategy.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/AbstractStaticFailoverStrategy.java?view=auto&rev=538501
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/AbstractStaticFailoverStrategy.java
(added)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/AbstractStaticFailoverStrategy.java
Wed May 16 02:34:04 2007
@@ -0,0 +1,104 @@
+/**
+ * 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;
+
+public abstract class AbstractStaticFailoverStrategy implements FailoverStrategy {
+    
+    private static final Logger LOG =
+        LogUtils.getL7dLogger(AbstractStaticFailoverStrategy.class);
+    
+    /**
+     * Get the alternative endpoints for this invocation.
+     * 
+     * @param exchange the current Exchange
+     * @return a List of alternate endpoints if available
+     */
+    public List<Endpoint> getAlternateEndpoints(Exchange exchange) {
+        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 (!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;
+    }
+
+    /**
+     * 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",
+                     new Object[] {selected.getEndpointInfo().getName()});
+        } else {
+            LOG.warning("NO_ALTERNATE_TARGETS_REMAIN");
+        }
+        return selected;
+    }
+    
+    /**
+     * Get next alternate endpoint.
+     * 
+     * @param alternates non-empty List of alternate endpoints 
+     * @return
+     */
+    protected abstract Endpoint getNextAlternate(List<Endpoint> alternates);
+}

Propchange: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/AbstractStaticFailoverStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/FailoverFeature.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/FailoverFeature.java?view=diff&rev=538501&r1=538500&r2=538501
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/FailoverFeature.java
(original)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/FailoverFeature.java
Wed May 16 02:34:04 2007
@@ -29,11 +29,22 @@
  */
 public class FailoverFeature extends AbstractFeature {
 
+    private FailoverStrategy failoverStrategy;
+    
     @Override
     public void initialize(Client client, Bus bus) {
         FailoverTargetSelector selector =
             new FailoverTargetSelector();
         selector.setEndpoint(client.getEndpoint());
+        selector.setStrategy(getStrategy());
         client.setConduitSelector(selector);
+    }
+
+    public void setStrategy(FailoverStrategy strategy) {
+        failoverStrategy = strategy;
+    }
+    
+    public FailoverStrategy getStrategy()  {
+        return failoverStrategy;
     }
 }

Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java?view=diff&rev=538501&r1=538500&r2=538501
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java
(original)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java
Wed May 16 02:34:04 2007
@@ -20,16 +20,12 @@
 package org.apache.cxf.clustering;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 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.AbstractConduitSelector;
 import org.apache.cxf.endpoint.Client;
@@ -39,8 +35,6 @@
 import org.apache.cxf.message.Exchange;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.service.model.BindingOperationInfo;
-import org.apache.cxf.service.model.EndpointInfo;
-import org.apache.cxf.service.model.ServiceInfo;
 import org.apache.cxf.transport.Conduit;
 
 
@@ -54,6 +48,7 @@
     private static final Logger LOG =
         LogUtils.getL7dLogger(FailoverTargetSelector.class);
     private Map<InvocationKey, InvocationContext> inProgress;
+    private FailoverStrategy failoverStrategy;
     
     /**
      * Normal constructor.
@@ -166,6 +161,27 @@
             }
         }
     }
+    
+    /**
+     * @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
@@ -212,46 +228,12 @@
         if (invocation.getAlternateTargets() == null) {
             // no previous failover attempt on this invocation
             //
-            Endpoint endpoint = exchange.get(Endpoint.class);
-            Collection<ServiceInfo> services = endpoint.getService().getServiceInfos();
-            QName currentBinding = endpoint.getBinding().getBindingInfo().getName();
-            invocation.setAlternateTargets(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 (!candidate.getAddress().equals(
-                                 endpoint.getEndpointInfo().getAddress())) {
-                            Endpoint alternate =
-                                endpoint.getService().getEndpoints().get(candidate.getName());
-                            if (alternate != null) {
-                                getLogger().log(Level.INFO,
-                                                "FAILOVER_CANDIDATE_ACCEPTED",
-                                                candidate.getName());
-                                invocation.getAlternateTargets().add(alternate);
-                            }
-                        }
-                    } else {
-                        getLogger().log(Level.INFO,
-                                        "FAILOVER_CANDIDATE_REJECTED",
-                                        new Object[] {candidate.getName(), candidateBinding});
-                    }
-                }
-            }
+            invocation.setAlternateTargets(
+                getStrategy().getAlternateEndpoints(exchange));
         } 
 
-        Endpoint failoverTarget = null;
-        if (invocation.getAlternateTargets().size() > 0) {
-            // REVISIT: configurable sequential or randomized
-            failoverTarget = invocation.getAlternateTargets().remove(0);
-            getLogger().log(Level.WARNING,
-                            "FAILING_OVER_TO",
-                            new Object[] {failoverTarget.getEndpointInfo().getName()});
-        } else {
-            getLogger().warning("NO_ALTERNATE_TARGETS_REMAIN");
-        }
-        return failoverTarget;
+        return getStrategy().selectAlternateEndpoint(
+                   invocation.getAlternateTargets());
     }
     
     /**

Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/Messages.properties
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/Messages.properties?view=diff&rev=538501&r1=538500&r2=538501
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/Messages.properties
(original)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/Messages.properties
Wed May 16 02:34:04 2007
@@ -18,6 +18,7 @@
 #    under the License.
 #
 #
+USING_STRATEGY = Using failover strategy {0}
 REVERT_TO_ORIGINAL_TARGET = reverted to original endpoint {0}
 FAILOVER_NOT_REQUIRED = failover not required
 NO_ALTERNATE_TARGETS_REMAIN = no alternate targets remain => giving up on failover

Added: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/RandomStrategy.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/RandomStrategy.java?view=auto&rev=538501
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/RandomStrategy.java
(added)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/RandomStrategy.java
Wed May 16 02:34:04 2007
@@ -0,0 +1,47 @@
+/**
+ * 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;
+
+import org.apache.cxf.endpoint.Endpoint;
+
+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 Endpoint getNextAlternate(List<Endpoint> alternates) {
+        return alternates.remove(random.nextInt(alternates.size()));
+    }
+}
\ No newline at end of file

Propchange: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/RandomStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/SequentialStrategy.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/SequentialStrategy.java?view=auto&rev=538501
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/SequentialStrategy.java
(added)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/SequentialStrategy.java
Wed May 16 02:34:04 2007
@@ -0,0 +1,37 @@
+/**
+ * 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;
+
+public class SequentialStrategy extends AbstractStaticFailoverStrategy {
+
+    /**
+     * Get next alternate endpoint.
+     * 
+     * @param alternates non-empty List of alternate endpoints 
+     * @return
+     */
+    protected Endpoint getNextAlternate(List<Endpoint> alternates) {
+        return alternates.remove(0);
+    }
+}

Propchange: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/SequentialStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/spring/FailoverBeanDefinitionParser.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/spring/FailoverBeanDefinitionParser.java?view=diff&rev=538501&r1=538500&r2=538501
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/spring/FailoverBeanDefinitionParser.java
(original)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/clustering/spring/FailoverBeanDefinitionParser.java
Wed May 16 02:34:04 2007
@@ -19,16 +19,30 @@
 package org.apache.cxf.clustering.spring;
 
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 
 import org.apache.cxf.clustering.FailoverFeature;
+import org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser;
 
-import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
 
-public class FailoverBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser {
+public class FailoverBeanDefinitionParser extends AbstractBeanDefinitionParser {
 
     @Override
-    protected Class getBeanClass(Element arg0) {
+    protected Class getBeanClass(Element element) {
         return FailoverFeature.class;
     }
-
+ 
+    @Override
+    protected void doParse(Element element, ParserContext ctx, BeanDefinitionBuilder bean)
{
+        NodeList children = element.getChildNodes();
+        for (int i = 0; i < children.getLength(); i++) {
+            Node n = children.item(i);
+            if (n.getNodeType() == Node.ELEMENT_NODE) {
+                setFirstChildAsProperty((Element) n, ctx, bean, n.getLocalName());
+            }
+        }
+    }
 }

Modified: incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/clustering/FailoverTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/clustering/FailoverTest.java?view=diff&rev=538501&r1=538500&r2=538501
==============================================================================
--- incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/clustering/FailoverTest.java
(original)
+++ incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/clustering/FailoverTest.java
Wed May 16 02:34:04 2007
@@ -28,6 +28,9 @@
 import org.apache.cxf.BusFactory;
 import org.apache.cxf.bus.spring.SpringBusFactory;
 import org.apache.cxf.clustering.FailoverTargetSelector;
+import org.apache.cxf.clustering.RandomStrategy;
+import org.apache.cxf.clustering.SequentialStrategy;
+import org.apache.cxf.endpoint.ConduitSelector;
 import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.frontend.ClientProxy;
 import org.apache.cxf.greeter_control.ClusteredGreeterService;
@@ -180,7 +183,6 @@
         }
     }
 
-        
     @Test
     public void testFailoverOnCurrentReplicaDeath() throws Exception {
         startTarget(REPLICA_C);
@@ -276,7 +278,54 @@
         assertFalse("unexpected WSA enabled for current endpoint",
                     isWSAEnabledForCurrentEndpoint());
     }
+
+    @Test
+    public void testDefaultSequentialStrategy() throws Exception {
+        strategyTest(REPLICA_B, REPLICA_C, REPLICA_A, false);
+    }
+
+    @Test
+    public void testExplicitSequentialStrategy() throws Exception {
+        strategyTest(REPLICA_A, REPLICA_C, REPLICA_B, false);
+    }
     
+    @Test
+    public void testRandomStrategy() throws Exception {
+        strategyTest(REPLICA_A, REPLICA_B, REPLICA_C, true);
+    }
+    
+    private void strategyTest(String activeReplica1,
+                              String activeReplica2,
+                              String inactiveReplica,
+                              boolean expectRandom) {
+        startTarget(activeReplica1);
+        startTarget(activeReplica2);
+        boolean randomized = false;
+        String prevEndpoint = null;
+        for (int i = 0; i < 20; i++) {
+            Greeter g = REPLICA_A.equals(inactiveReplica)
+                        ? new ClusteredGreeterService().getReplicatedPortA()
+                        : REPLICA_B.equals(inactiveReplica)
+                          ? new ClusteredGreeterService().getReplicatedPortB()
+                          : new ClusteredGreeterService().getReplicatedPortC();
+            verifyStrategy(g, expectRandom 
+                              ? RandomStrategy.class
+                              : SequentialStrategy.class);
+            String response = g.greetMe("fred");
+            assertNotNull("expected non-null response", response);
+            String currEndpoint = getCurrentEndpoint(g);
+            if (!(prevEndpoint == null || currEndpoint.equals(prevEndpoint))) {
+                randomized = true;
+            }
+            prevEndpoint = currEndpoint;
+        }
+        stopTarget(activeReplica1);
+        stopTarget(activeReplica2);
+        assertEquals("unexpected random/sequential distribution of failovers",
+                     expectRandom,
+                     randomized);
+    }
+
     private void startTarget(String address) {
         ControlService cs = new ControlService();
         control = cs.getControlPort();
@@ -298,7 +347,11 @@
     private void verifyCurrentEndpoint(String replica) {
         assertEquals("unexpected current endpoint",
                      replica,
-                     ClientProxy.getClient(greeter).getEndpoint().getEndpointInfo().getAddress());
+                     getCurrentEndpoint(greeter));
+    }
+    
+    private String getCurrentEndpoint(Object proxy) {
+        return ClientProxy.getClient(proxy).getEndpoint().getEndpointInfo().getAddress();
     }
     
     private void setupGreeter() {
@@ -310,7 +363,19 @@
                    ClientProxy.getClient(greeter).getConduitSelector()
                    instanceof FailoverTargetSelector);
     }
-    
+        
+    private void verifyStrategy(Object proxy, Class clz) {
+        ConduitSelector conduitSelector =
+            ClientProxy.getClient(proxy).getConduitSelector();
+        if (conduitSelector instanceof FailoverTargetSelector) {
+            Object strategy =
+                ((FailoverTargetSelector)conduitSelector).getStrategy();
+            assertTrue("unexpected strategy", clz.isInstance(strategy));
+        } else {
+            fail("unexpected conduit selector: " + conduitSelector);
+        }
+    }
+
     protected void enableWSAForCurrentEndpoint() {
         Endpoint provider = ClientProxy.getClient(greeter).getEndpoint();
         mapAggregator = new MAPAggregator();

Modified: incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/clustering/failover.xml
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/clustering/failover.xml?view=diff&rev=538501&r1=538500&r2=538501
==============================================================================
--- incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/clustering/failover.xml
(original)
+++ incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/clustering/failover.xml
Wed May 16 02:34:04 2007
@@ -24,6 +24,9 @@
        xsi:schemaLocation="
 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
     
+    <bean id="Sequential" class="org.apache.cxf.clustering.SequentialStrategy"/>
+    <bean id="Random" class="org.apache.cxf.clustering.RandomStrategy"/>
+    
     <jaxws:client id="{http://cxf.apache.org/greeter_control}ReplicatedPortA"
                   createdFromAPI="true">
         <jaxws:features>
@@ -34,15 +37,23 @@
     <jaxws:client id="{http://cxf.apache.org/greeter_control}ReplicatedPortB"
                   createdFromAPI="true">
         <jaxws:features>
-            <clustering:failover/>
+            <clustering:failover>
+                <clustering:strategy>
+                    <ref bean="Sequential"/>
+                </clustering:strategy>
+            </clustering:failover>
         </jaxws:features>
     </jaxws:client>
-    
+
     <jaxws:client id="{http://cxf.apache.org/greeter_control}ReplicatedPortC"
                   createdFromAPI="true">
         <jaxws:features>
-            <clustering:failover/>
+            <clustering:failover>
+                <clustering:strategy>
+                    <ref bean="Random"/>
+                </clustering:strategy>
+            </clustering:failover>
         </jaxws:features>
     </jaxws:client>
-
+    
 </beans>



Mime
View raw message