Author: sergeyb
Date: Tue Jun 7 20:57:47 2011
New Revision: 1133162
URL: http://svn.apache.org/viewvc?rev=1133162&view=rev
Log:
[CXF-3575] Adding LoadDistributorTest
Added:
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/LoadDistributorTest.java
(with props)
Modified:
cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/AbstractConduitSelector.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
Modified:
cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/AbstractConduitSelector.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/AbstractConduitSelector.java?rev=1133162&r1=1133161&r2=1133162&view=diff
==============================================================================
---
cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/AbstractConduitSelector.java
(original)
+++
cxf/trunk/api/src/main/java/org/apache/cxf/endpoint/AbstractConduitSelector.java
Tue Jun 7 20:57:47 2011
@@ -77,6 +77,7 @@ public abstract class AbstractConduitSel
String add =
(String)message.get(Message.ENDPOINT_ADDRESS);
if (StringUtils.isEmpty(add)
|| add.equals(ei.getAddress())) {
+ replaceEndpointAddressPropertyIfNeeded(message,
add);
selectedConduit = conduitInitiator.getConduit(ei);
} else {
EndpointReferenceType epr = new
EndpointReferenceType();
@@ -108,6 +109,28 @@ public abstract class AbstractConduitSel
return selectedConduit;
}
+ // Some conduits may replace the endpoint address after it has already
been prepared
+ // but before the invocation has been done (ex,
org.apache.cxf.clustering.LoadDistributorTargetSelector)
+ // which may affect JAX-RS clients where actual endpoint address property
may include additional path
+ // segments.
+ protected void replaceEndpointAddressPropertyIfNeeded(Message message,
String endpointAddress) {
+ String requestURI = (String)message.get(Message.REQUEST_URI);
+ if (requestURI != null && !requestURI.startsWith(endpointAddress)) {
+ String basePath = (String)message.get(Message.BASE_PATH);
+ if (basePath != null && requestURI.startsWith(basePath)) {
+ String pathInfo = requestURI.substring(basePath.length());
+ final String slash = "/";
+ boolean startsWithSlash = pathInfo.startsWith(slash);
+ if (endpointAddress.endsWith(slash)) {
+ endpointAddress = endpointAddress + (startsWithSlash ?
pathInfo.substring(1) : pathInfo);
+ } else {
+ endpointAddress = endpointAddress + (startsWithSlash ?
pathInfo : (slash + pathInfo));
+ }
+ message.put(Message.ENDPOINT_ADDRESS, endpointAddress);
+ }
+ }
+ }
+
/**
* @return the encapsulated Endpoint
*/
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java?rev=1133162&r1=1133161&r2=1133162&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
Tue Jun 7 20:57:47 2011
@@ -67,7 +67,6 @@ import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.ExchangeImpl;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageContentsList;
-import org.apache.cxf.message.MessageImpl;
import org.apache.cxf.phase.PhaseChainCache;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.phase.PhaseManager;
@@ -671,6 +670,11 @@ public abstract class AbstractClient imp
cfg = config;
}
+ // Note that some conduit selectors may update Message.ENDPOINT_ADDRESS
+ // after the conduit selector has been prepared but before the actual
+ // invocation thus it is also important to have baseURI and currentURI
+ // synched up with the latest endpoint address, after a successful proxy
+ // or web client invocation has returned
protected void prepareConduitSelector(Message message, URI currentURI) {
try {
cfg.prepareConduitSelector(message);
@@ -688,6 +692,7 @@ public abstract class AbstractClient imp
message.put(Message.ENDPOINT_ADDRESS, currentURI.toString());
message.put(Message.REQUEST_URI, currentURI.toString());
}
+ message.put(Message.BASE_PATH, getBaseURI().toString());
}
protected static PhaseInterceptorChain
setupOutInterceptorChain(ClientConfiguration cfg) {
@@ -707,12 +712,6 @@ public abstract class AbstractClient imp
return new PhaseChainCache().get(pm.getInPhases(), i1, i2, i3);
}
- protected Message createSimpleMessage() {
- Message m = new MessageImpl();
- m.put(Message.PROTOCOL_HEADERS, getHeaders());
- return m;
- }
-
protected Message createMessage(Object body,
String httpMethod,
MultivaluedMap<String, String> headers,
@@ -749,7 +748,6 @@ public abstract class AbstractClient imp
//setup conduit selector
prepareConduitSelector(m, currentURI);
-
return m;
}
Added:
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/LoadDistributorTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/LoadDistributorTest.java?rev=1133162&view=auto
==============================================================================
---
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/LoadDistributorTest.java
(added)
+++
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/LoadDistributorTest.java
Tue Jun 7 20:57:47 2011
@@ -0,0 +1,162 @@
+/**
+ * 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.systest.jaxrs.failover;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.core.Response;
+
+import org.apache.cxf.clustering.FailoverTargetSelector;
+import org.apache.cxf.clustering.LoadDistributorTargetSelector;
+import org.apache.cxf.clustering.SequentialStrategy;
+import org.apache.cxf.endpoint.ConduitSelector;
+import org.apache.cxf.feature.AbstractFeature;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.features.clustering.FailoverFeature;
+import org.apache.cxf.systest.jaxrs.Book;
+import org.apache.cxf.systest.jaxrs.BookStore;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+/**
+ * Tests failover within a static cluster.
+ */
+public class LoadDistributorTest extends AbstractBusClientServerTestBase {
+
+ @BeforeClass
+ public static void startServers() throws Exception {
+ assertTrue("server did not launch correctly",
+ launchServer(Server.class, true));
+ boolean activeReplica1Started = false;
+ boolean activeReplica2Started = false;
+ for (int i = 0; i < 60; i++) {
+ if (!activeReplica1Started) {
+ activeReplica1Started = checkReplica(Server.ADDRESS2);
+ }
+ if (!activeReplica2Started) {
+ activeReplica2Started = checkReplica(Server.ADDRESS3);
+ }
+ if (activeReplica1Started && activeReplica2Started) {
+ break;
+ }
+ Thread.sleep(1000);
+ }
+ }
+ private static boolean checkReplica(String address) {
+ try {
+ Response r = WebClient.create(address).query("_wadl").get();
+ return r.getStatus() == 200;
+ } catch (Exception ex) {
+ return false;
+ }
+ }
+
+ @Test
+ public void testSequentialStrategy() throws Exception {
+ FailoverFeature feature = getFeature(Server.ADDRESS2,
Server.ADDRESS3);
+ strategyTest(Server.ADDRESS1, feature);
+ }
+
+
+ private FailoverFeature getFeature(String ...address) {
+ FailoverFeature feature = new FailoverFeature();
+ List<String> alternateAddresses = new ArrayList<String>();
+ for (String s : address) {
+ alternateAddresses.add(s);
+ }
+ SequentialStrategy strategy = new SequentialStrategy();
+ strategy.setAlternateAddresses(alternateAddresses);
+ feature.setStrategy(strategy);
+
+ LoadDistributorTargetSelector selector = new
LoadDistributorTargetSelector();
+ selector.setFailover(false);
+
+ feature.setTargetSelector(selector);
+
+ return feature;
+ }
+
+ protected BookStore getBookStore(String address,
+ FailoverFeature feature) throws Exception
{
+ JAXRSClientFactoryBean bean = createBean(address, feature);
+ bean.setServiceClass(BookStore.class);
+ return bean.create(BookStore.class);
+ }
+
+ protected JAXRSClientFactoryBean createBean(String address,
+ FailoverFeature feature) {
+ JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+ bean.setAddress(address);
+ List<AbstractFeature> features = new ArrayList<AbstractFeature>();
+ features.add(feature);
+ bean.setFeatures(features);
+
+ return bean;
+ }
+
+ protected void strategyTest(String initialAddress,
+ FailoverFeature feature) throws Exception {
+ assertEquals(Server.ADDRESS1, initialAddress);
+ int address2Count = 0;
+ int address3Count = 0;
+ for (int i = 0; i < 20; i++) {
+ BookStore bookStore = getBookStore(initialAddress, feature);
+ verifyStrategy(bookStore, SequentialStrategy.class);
+ String bookId = "123";
+
+ Book book = bookStore.getBook(bookId);
+ assertNotNull("expected non-null response", book);
+ assertEquals("unexpected id", 123L, book.getId());
+
+ String address = getCurrentEndpointAddress(bookStore);
+ System.out.println(address);
+ if (Server.ADDRESS2.equals(address)) {
+ address2Count++;
+ } else if (Server.ADDRESS3.equals(address)) {
+ address3Count++;
+ }
+ }
+ assertEquals(10, address2Count);
+ assertEquals(10, address3Count);
+ }
+
+ protected String getCurrentEndpointAddress(Object client) {
+ return WebClient.getConfig(client).getConduitSelector()
+ .getEndpoint().getEndpointInfo().getAddress();
+ }
+
+ protected void verifyStrategy(Object proxy, Class clz) {
+ ConduitSelector conduitSelector =
+ WebClient.getConfig(proxy).getConduitSelector();
+ if (conduitSelector instanceof FailoverTargetSelector) {
+ Object strategy =
+ ((FailoverTargetSelector)conduitSelector).getStrategy();
+ assertTrue("unexpected strategy", clz.isInstance(strategy));
+ } else {
+ fail("unexpected conduit selector: " + conduitSelector);
+ }
+ }
+
+}
Propchange:
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/LoadDistributorTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/LoadDistributorTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date