Details
Description
LoadDistributorTargetSelector seems to be confused by subresources.
I'm attaching a test that demonstrates it below.
When no clustering features or FailoverFeature is applied, the client tries to invoke 'http://localhost:1234/sub/name', as expected. – `noClustering` and `failover` pass.
When LoadDistributorFeature is applied, the request is to 'http://localhost:1234/name' (path segment contributed by the root resource is lost) – `loadDistributor` fails.
---------------------------------------
import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import java.util.List; 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 ShowBug { @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")); 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"); 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(); } }