This is an automated email from the ASF dual-hosted git repository.
ffang pushed a commit to branch 4.0.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/4.0.x-fixes by this push:
new b7d2dfcc96 [CXF-9052]LoadDistributorFeature not comaptible with JAX-RS
subresources
b7d2dfcc96 is described below
commit b7d2dfcc960e6bb816692b96c63cec4b1ca1151a
Author: Freeman Fang <[email protected]>
AuthorDate: Thu Nov 14 15:40:45 2024 -0500
[CXF-9052]LoadDistributorFeature not comaptible with JAX-RS subresources
(cherry picked from commit 49a6ed5aa831629396cca3c90db4fb5974e63195)
---
.../clustering/LoadDistributorTargetSelector.java | 40 +++++++++++
.../cxf/systest/jaxrs/failover/CXF9052Test.java | 79 ++++++++++++++++++++++
2 files changed, 119 insertions(+)
diff --git
a/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorTargetSelector.java
b/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorTargetSelector.java
index 467e3e735c..2ae2b04cdf 100644
---
a/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorTargetSelector.java
+++
b/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorTargetSelector.java
@@ -21,6 +21,7 @@ package org.apache.cxf.clustering;
import java.util.List;
import java.util.logging.Logger;
+import org.apache.cxf.clustering.FailoverTargetSelector.InvocationContext;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.message.Exchange;
@@ -169,6 +170,45 @@ public class LoadDistributorTargetSelector extends
FailoverTargetSelector {
}
return failoverTarget;
}
+
+ // 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 boolean replaceEndpointAddressPropertyIfNeeded(Message message,
+ String
endpointAddress,
+ Conduit cond) {
+ String requestURI = (String)message.get(Message.REQUEST_URI);
+ if (requestURI != null && endpointAddress != null &&
!requestURI.equals(endpointAddress)) {
+ String basePath = (String)message.get(Message.BASE_PATH);
+ if (basePath.startsWith(endpointAddress)) {
+ endpointAddress = basePath;
+ }
+ if (basePath != null && requestURI.startsWith(basePath)) {
+ String pathInfo = requestURI.substring(basePath.length());
+ message.put(Message.BASE_PATH, endpointAddress);
+ 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);
+ message.put(Message.REQUEST_URI, endpointAddress);
+
+ Exchange exchange = message.getExchange();
+ String key = String.valueOf(System.identityHashCode(exchange));
+ InvocationContext invocation = getInvocationContext(key);
+ if (invocation != null) {
+ overrideAddressProperty(invocation.getContext(),
+
cond.getTarget().getAddress().getValue());
+ }
+ return true;
+ }
+ }
+ return false;
+ }
/**
* Get the distribution target endpoint, if a suitable one is available.
diff --git
a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/CXF9052Test.java
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/CXF9052Test.java
new file mode 100644
index 0000000000..fd4891bc4f
--- /dev/null
+++
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/CXF9052Test.java
@@ -0,0 +1,79 @@
+/**
+ * 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.List;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import org.apache.cxf.clustering.FailoverFeature;
+import org.apache.cxf.clustering.LoadDistributorFeature;
+import org.apache.cxf.clustering.SequentialStrategy;
+import org.apache.cxf.feature.Feature;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
+
+import org.junit.Assert;
+import org.junit.Test;
+public class CXF9052Test {
+ @Test
+ public void noClustering() {
+ makeRequest(List.of());
+ }
+
+ @Test
+ public void failover() {
+ var failover = new FailoverFeature();
+ failover.setStrategy(makeStrategy());
+ makeRequest(List.of(failover));
+ }
+
+ @Test
+ public void loadDistributor() {
+ var distro = new LoadDistributorFeature();
+ distro.setStrategy(makeStrategy());
+ makeRequest(List.of(distro));
+ }
+
+ private static SequentialStrategy makeStrategy() {
+ var s = new SequentialStrategy();
+ s.setAlternateAddresses(List.of("http://localhost:1234/test"));
+ return s;
+ }
+
+ private static void makeRequest(List<Feature> features) {
+ var fct = new JAXRSClientFactoryBean();
+ fct.setFeatures(features);
+ fct.setServiceClass(Root.class);
+ fct.setAddress("http://localhost:1234/test");
+ try {
+ fct.create(Root.class).sub().name();
+ } catch (Exception e) {
+ Assert.assertTrue(e.getMessage(),
e.getMessage().contains("/sub/name"));
+ }
+ }
+
+ interface Root {
+ @Path("/sub") Sub sub();
+ }
+
+ interface Sub {
+ @GET @Path("/name") String name();
+ }
+}