Repository: cxf Updated Branches: refs/heads/3.1.x-fixes 8501d7acf -> 85ced5e73
Adding a Eureka failover feature to the demo Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/85ced5e7 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/85ced5e7 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/85ced5e7 Branch: refs/heads/3.1.x-fixes Commit: 85ced5e73b84fdbc25e84a5429af2e3ff17d581c Parents: 8501d7a Author: Sergey Beryozkin <[email protected]> Authored: Fri Jul 15 17:45:03 2016 +0300 Committer: Sergey Beryozkin <[email protected]> Committed: Fri Jul 15 17:50:13 2016 +0300 ---------------------------------------------------------------------- .../jax_rs/spring_boot_scan/application/pom.xml | 5 ++ .../rs/client/SampleRestClientApplication.java | 49 ++++++++++++++++---- .../src/main/resources/application.yml | 3 ++ .../apache/cxf/clustering/FailoverFeature.java | 18 ++++++- .../cxf/clustering/FailoverTargetSelector.java | 24 ++++++++++ .../cxf/clustering/LoadDistributorFeature.java | 10 +++- .../LoadDistributorTargetSelector.java | 5 ++ .../AbstractSpringComponentScanServer.java | 2 +- .../AbstractJaxRsClientConfiguration.java | 29 ++++++++++-- .../spring/JaxRsProxyClientConfiguration.java | 2 +- .../spring/JaxRsWebClientConfiguration.java | 2 +- 11 files changed, 132 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/85ced5e7/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/pom.xml ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/pom.xml b/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/pom.xml index 15a9599..d0ecc63 100644 --- a/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/pom.xml +++ b/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/pom.xml @@ -28,6 +28,11 @@ <artifactId>cxf-rt-rs-service-description-swagger</artifactId> <version>${cxf.version}</version> </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-features-clustering</artifactId> + <version>${cxf.version}</version> + </dependency> <!-- Eureka Service Discovery Client --> <dependency> <groupId>org.springframework.cloud</groupId> http://git-wip-us.apache.org/repos/asf/cxf/blob/85ced5e7/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/src/main/java/sample/rs/client/SampleRestClientApplication.java ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/src/main/java/sample/rs/client/SampleRestClientApplication.java b/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/src/main/java/sample/rs/client/SampleRestClientApplication.java index 47ef38c..4ec4e60 100644 --- a/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/src/main/java/sample/rs/client/SampleRestClientApplication.java +++ b/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/src/main/java/sample/rs/client/SampleRestClientApplication.java @@ -18,9 +18,18 @@ */ package sample.rs.client; +import java.util.LinkedList; +import java.util.List; + import javax.ws.rs.core.UriBuilder; -import org.apache.cxf.jaxrs.client.JAXRSClientFactory; +import org.apache.cxf.annotations.Provider; +import org.apache.cxf.annotations.Provider.Type; +import org.apache.cxf.clustering.FailoverFeature; +import org.apache.cxf.clustering.FailoverStrategy; +import org.apache.cxf.clustering.RandomStrategy; +import org.apache.cxf.jaxrs.client.spring.EnableJaxRsProxyClient; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -28,11 +37,13 @@ import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; import sample.rs.service.HelloService; @SpringBootApplication @EnableEurekaClient +@EnableJaxRsProxyClient public class SampleRestClientApplication { public static void main(String[] args) { new SpringApplicationBuilder(SampleRestClientApplication.class) @@ -40,23 +51,45 @@ public class SampleRestClientApplication { .run(args); } @Bean - CommandLineRunner initDiscoveryClient(final DiscoveryClient discoveryClient) { + CommandLineRunner initProxyClient(final HelloService service) { return new CommandLineRunner() { - @Override public void run(String... runArgs) throws Exception { - //TODO: Wire it in a CXF FailoverStrategy + System.out.println(service.sayHello("ApacheCxfProxyUser1")); + System.out.println(service.sayHello("ApacheCxfProxyUser2")); + } + }; + } + + /** + * Basic Random selection of statically prepared addresses. + * More advanced strategies will periodically pull DiscoveryClient + * to update the addresses list + */ + @Component + @Provider(Type.Feature) + static class EurekaFailoverFeature extends FailoverFeature { + @Autowired + DiscoveryClient discoveryClient; + List<String> addresses = new LinkedList<String>(); + + public EurekaFailoverFeature() { + super("eureka://registry"); + } + + @Override + public FailoverStrategy getStrategy() { for (ServiceInstance s : discoveryClient.getInstances("jaxrs-hello-world-service")) { UriBuilder ub = UriBuilder.fromUri(s.getUri()); if (s.getMetadata().containsKey("servletPath")) { ub.path(s.getMetadata().get("servletPath")); } - HelloService service = JAXRSClientFactory.create(ub.build(), HelloService.class); - System.out.println(service.sayHello("ApacheCxfProxyUser")); + addresses.add(ub.build().toString()); } - + RandomStrategy rs = new RandomStrategy(); + rs.setAlternateAddresses(addresses); + return rs; } - }; } } http://git-wip-us.apache.org/repos/asf/cxf/blob/85ced5e7/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/src/main/resources/application.yml ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/src/main/resources/application.yml b/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/src/main/resources/application.yml index 45ddf9b..26fb5aa 100644 --- a/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/src/main/resources/application.yml +++ b/distribution/src/main/release/samples/jax_rs/spring_boot_scan/application/src/main/resources/application.yml @@ -9,6 +9,9 @@ cxf: jaxrs: component-scan: true classes-scan-packages: org.apache.cxf.jaxrs.swagger + client: + address: eureka://registry + classes-scan-packages: sample.rs.service eureka: client: http://git-wip-us.apache.org/repos/asf/cxf/blob/85ced5e7/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverFeature.java ---------------------------------------------------------------------- diff --git a/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverFeature.java b/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverFeature.java index 8c25733..c9278f4 100644 --- a/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverFeature.java +++ b/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverFeature.java @@ -39,6 +39,14 @@ public class FailoverFeature extends AbstractFeature { private FailoverStrategy failoverStrategy; private FailoverTargetSelector targetSelector; + private String clientBootstrapAddress; + + public FailoverFeature() { + + } + public FailoverFeature(String clientBootstrapAddress) { + this.clientBootstrapAddress = clientBootstrapAddress; + } @Override protected void initializeProvider(InterceptorProvider provider, Bus bus) { @@ -67,7 +75,7 @@ public class FailoverFeature extends AbstractFeature { public FailoverTargetSelector getTargetSelector() { if (this.targetSelector == null) { - this.targetSelector = new FailoverTargetSelector(); + this.targetSelector = new FailoverTargetSelector(clientBootstrapAddress); } return this.targetSelector; } @@ -83,4 +91,12 @@ public class FailoverFeature extends AbstractFeature { public FailoverStrategy getStrategy() { return failoverStrategy; } + + public String getClientBootstrapAddress() { + return clientBootstrapAddress; + } + + public void setClientBootstrapAddress(String clientBootstrapAddress) { + this.clientBootstrapAddress = clientBootstrapAddress; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/85ced5e7/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java ---------------------------------------------------------------------- diff --git a/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java b/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java index d364a55..44e1795 100644 --- a/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java +++ b/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java @@ -55,6 +55,7 @@ public class FailoverTargetSelector extends AbstractConduitSelector { = new ConcurrentHashMap<InvocationKey, InvocationContext>(); protected FailoverStrategy failoverStrategy; private boolean supportNotAvailableErrorsOnly = true; + private String clientBootstrapAddress; /** * Normal constructor. */ @@ -62,6 +63,11 @@ public class FailoverTargetSelector extends AbstractConduitSelector { super(); } + public FailoverTargetSelector(String clientBootstrapAddress) { + super(); + this.setClientBootstrapAddress(clientBootstrapAddress); + } + /** * Constructor, allowing a specific conduit to override normal selection. * @@ -85,6 +91,16 @@ public class FailoverTargetSelector extends AbstractConduitSelector { InvocationKey key = new InvocationKey(exchange); if (getInvocationContext(key) == null) { + + if (getClientBootstrapAddress() != null + && getClientBootstrapAddress().equals(message.get(Message.ENDPOINT_ADDRESS))) { + List<String> addresses = failoverStrategy.getAlternateAddresses(exchange); + if (addresses != null && !addresses.isEmpty()) { + getEndpoint().getEndpointInfo().setAddress(addresses.get(0)); + message.put(Message.ENDPOINT_ADDRESS, addresses.get(0)); + } + } + Endpoint endpoint = exchange.getEndpoint(); BindingOperationInfo bindingOperationInfo = exchange.getBindingOperationInfo(); @@ -392,6 +408,14 @@ public class FailoverTargetSelector extends AbstractConduitSelector { this.supportNotAvailableErrorsOnly = support; } + public String getClientBootstrapAddress() { + return clientBootstrapAddress; + } + + public void setClientBootstrapAddress(String clientBootstrapAddress) { + this.clientBootstrapAddress = clientBootstrapAddress; + } + /** * 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 http://git-wip-us.apache.org/repos/asf/cxf/blob/85ced5e7/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorFeature.java ---------------------------------------------------------------------- diff --git a/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorFeature.java b/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorFeature.java index 9eee0e3..97840f2 100644 --- a/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorFeature.java +++ b/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorFeature.java @@ -29,8 +29,16 @@ import org.apache.cxf.common.injection.NoJSR250Annotations; @NoJSR250Annotations public class LoadDistributorFeature extends FailoverFeature { + + public LoadDistributorFeature() { + + } + public LoadDistributorFeature(String clientBootstrapAddress) { + super(clientBootstrapAddress); + } + @Override public FailoverTargetSelector getTargetSelector() { - return new LoadDistributorTargetSelector(); + return new LoadDistributorTargetSelector(getClientBootstrapAddress()); } } http://git-wip-us.apache.org/repos/asf/cxf/blob/85ced5e7/rt/features/clustering/src/main/java/org/apache/cxf/clustering/LoadDistributorTargetSelector.java ---------------------------------------------------------------------- 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 c4cd273..571883d 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 @@ -20,6 +20,7 @@ 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; @@ -66,6 +67,10 @@ public class LoadDistributorTargetSelector extends FailoverTargetSelector { public LoadDistributorTargetSelector() { super(); } + + public LoadDistributorTargetSelector(String clientBootstrapAddress) { + super(clientBootstrapAddress); + } /** * Constructor, allowing a specific conduit to override normal selection. http://git-wip-us.apache.org/repos/asf/cxf/blob/85ced5e7/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/AbstractSpringComponentScanServer.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/AbstractSpringComponentScanServer.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/AbstractSpringComponentScanServer.java index e1e6e21..a2a7094 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/AbstractSpringComponentScanServer.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/AbstractSpringComponentScanServer.java @@ -48,7 +48,7 @@ import org.springframework.context.annotation.FilterType; ) public abstract class AbstractSpringComponentScanServer extends AbstractSpringConfigurationFactory { - @Value("${cxf.jaxrs.classes-scan-packages:''}") + @Value("${cxf.jaxrs.classes-scan-packages:}") private String classesScanPackages; private List<ResourceProvider> resourceProviders = new LinkedList<ResourceProvider>(); http://git-wip-us.apache.org/repos/asf/cxf/blob/85ced5e7/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/AbstractJaxRsClientConfiguration.java ---------------------------------------------------------------------- diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/AbstractJaxRsClientConfiguration.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/AbstractJaxRsClientConfiguration.java index 4541c72..8286980 100644 --- a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/AbstractJaxRsClientConfiguration.java +++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/AbstractJaxRsClientConfiguration.java @@ -24,7 +24,10 @@ import java.util.Map; import javax.ws.rs.ext.Provider; import org.apache.cxf.Bus; +import org.apache.cxf.annotations.Provider.Scope; import org.apache.cxf.common.util.StringUtils; +import org.apache.cxf.feature.Feature; +import org.apache.cxf.interceptor.Interceptor; import org.apache.cxf.jaxrs.client.Client; import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean; import org.apache.cxf.jaxrs.spring.JaxRsConfig; @@ -40,7 +43,8 @@ import org.springframework.context.annotation.Import; @Import(JaxRsConfig.class) @ComponentScan( includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, - value = {Provider.class}) + value = {Provider.class, + org.apache.cxf.annotations.Provider.class}) ) public abstract class AbstractJaxRsClientConfiguration implements ApplicationContextAware { @@ -51,9 +55,9 @@ public abstract class AbstractJaxRsClientConfiguration implements ApplicationCon private String address; @Value("${cxf.jaxrs.client.thread-safe:false}") private Boolean threadSafe; - @Value("${cxf.jaxrs.client.headers.accept:''}") + @Value("${cxf.jaxrs.client.headers.accept:}") private String accept; - @Value("${cxf.jaxrs.client.headers.content-type:''}") + @Value("${cxf.jaxrs.client.headers.content-type:}") private String contentType; @@ -67,8 +71,11 @@ public abstract class AbstractJaxRsClientConfiguration implements ApplicationCon for (String beanName : context.getBeanDefinitionNames()) { if (context.findAnnotationOnBean(beanName, Provider.class) != null) { bean.setProvider(context.getBean(beanName)); + } else if (context.findAnnotationOnBean(beanName, org.apache.cxf.annotations.Provider.class) != null) { + addCxfProvider(bean, context.getBean(beanName)); } } + Map<String, String> extraHeaders = new HashMap<String, String>(); if (!StringUtils.isEmpty(accept)) { extraHeaders.put("Accept", accept); @@ -81,7 +88,21 @@ public abstract class AbstractJaxRsClientConfiguration implements ApplicationCon } return bean.create(); } - + protected void addCxfProvider(JAXRSClientFactoryBean factory, Object provider) { + org.apache.cxf.annotations.Provider ann = + provider.getClass().getAnnotation(org.apache.cxf.annotations.Provider.class); + if (ann.scope() == Scope.Server) { + return; + } + if (ann.value() == org.apache.cxf.annotations.Provider.Type.Feature) { + factory.getFeatures().add((Feature)provider); + } else if (ann.value() == org.apache.cxf.annotations.Provider.Type.InInterceptor) { + factory.getInInterceptors().add((Interceptor<?>)provider); + } else if (ann.value() == org.apache.cxf.annotations.Provider.Type.OutInterceptor) { + factory.getOutInterceptors().add((Interceptor<?>)provider); + } + + } protected abstract void setJaxrsResources(JAXRSClientFactoryBean factory); @Override http://git-wip-us.apache.org/repos/asf/cxf/blob/85ced5e7/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsProxyClientConfiguration.java ---------------------------------------------------------------------- diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsProxyClientConfiguration.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsProxyClientConfiguration.java index 26a83bb..00a8443 100644 --- a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsProxyClientConfiguration.java +++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsProxyClientConfiguration.java @@ -34,7 +34,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; public class JaxRsProxyClientConfiguration extends AbstractJaxRsClientConfiguration { - @Value("${cxf.jaxrs.client.classes-scan-packages:''}") + @Value("${cxf.jaxrs.client.classes-scan-packages:}") private String scanPackages; @Bean http://git-wip-us.apache.org/repos/asf/cxf/blob/85ced5e7/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsWebClientConfiguration.java ---------------------------------------------------------------------- diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsWebClientConfiguration.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsWebClientConfiguration.java index acc0824..f90b4ae 100644 --- a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsWebClientConfiguration.java +++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsWebClientConfiguration.java @@ -35,7 +35,7 @@ import org.springframework.context.annotation.Bean; public class JaxRsWebClientConfiguration extends AbstractJaxRsClientConfiguration { - @Value("${cxf.jaxrs.client.classes-scan-packages:''}") + @Value("${cxf.jaxrs.client.classes-scan-packages:}") private String scanPackages; @Bean
