[ 
https://issues.apache.org/jira/browse/CXF-7663?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16383546#comment-16383546
 ] 

Colm O hEigeartaigh commented on CXF-7663:
------------------------------------------

If you want to use the Circuit-Breaker feature then you need to use the same 
Webclient instance for all of the invocations - it won't work if you are 
creating a new WebClient per-call. Here's a test that shows how it works:

https://github.com/coheigea/testcases/blob/218044e3126cff9339e27a69cd8d3c5f3fe308ea/apache/cxf/cxf-failover/src/test/java/org/apache/coheigea/cxf/failover/feature/FailoverTest.java#L90

> Programmatic approach for Circuit-Breaker feature is not working
> ----------------------------------------------------------------
>
>                 Key: CXF-7663
>                 URL: https://issues.apache.org/jira/browse/CXF-7663
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-RS
>    Affects Versions: 3.2.1
>         Environment: * which version of the software - Apache CXF 3.2.1
>  * what platform and JDK - Tomcat 7, JDK 1.8.0_131
>            Reporter: RANADEEP SHARMA
>            Priority: Major
>         Attachments: 
> Reason_UnableToOpenCircuit_WebClient_ProgramaticApproach.png, app.log
>
>
> As per the documentation - 
> [https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Failover#JAX-RSFailover-Code.1],
>  I tried running the following code along with associated configurations, but 
> the circuit breaker mechanism is not opening up once the threshold count for 
> connectivity failures have exceeded. As the circuit stays closed, the 
> invocation attempts are still being accepted which is against expected 
> behaviour.
>  
> {code:java}
> public class CustomerRestClient {
>     private CustomerRestClientFactory customerRestClientFactory;
>     public List<Customer> filterByFirstName(String firstName) {
>         List<Customer> filteredCustomers = new ArrayList<>();
>         CircuitBreakerFailoverFeature cbFailoverFeature = new 
> CircuitBreakerFailoverFeature(4, 180000L);
>         SequentialStrategy strategy = new SequentialStrategy();
>         cbFailoverFeature.setStrategy(strategy);
>         
>         List<Feature> featureList = new ArrayList<Feature>();
>         featureList.add(cbFailoverFeature);
>         WebClient client = 
> customerRestClientFactory.getClient(featureList).path("/");
>         // Call service to get all customers
>         List<Customer> customers = client.get(new 
> GenericType<List<Customer>>() {});
>         return filteredCustomers;
>     }
>     public void setCustomerRestClientFactory(CustomerRestClientFactory 
> customerRestClientFactory) {
>         this.customerRestClientFactory = customerRestClientFactory;
>     }
> }
> {code}
>  
> {code:java}
> public class CustomerRestClientFactory implements InitializingBean {
>     private List providerList;  // Value is injected by Spring
>     private String serviceUrl;  // Value is injected by Spring
>     public WebClient getClient(List<? extends Feature> featureList) {
>         if (featureList == null || featureList.isEmpty()) {
>             throw new IllegalArgumentException("featureList is not 
> initialized.");
>         }
>         JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
>         bean.setAddress(serviceUrl);
>         bean.setServiceClass(WebClient.class);
>         bean.setProviders(providerList);
>         bean.setFeatures(featureList);
>         return bean.createWebClient();
>     }
> }{code}
> {code:java}
> <bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">  
>            <property name="dateFormat">
>         <bean class="java.text.SimpleDateFormat"> <constructor-arg 
> type="java.lang.String" value="yyyy-MM-dd'T'HH:mm:ss"/>
>         </bean>
> </property>
> <property name="serializationInclusion">
>     <value 
> type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value> 
> </property>
> </bean>
> <bean id="jsonProvider" 
> class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider">
>      <property name="mapper" ref="objectMapper"/>
> </bean>
> <util:list id="providerList">
>     <ref bean="jsonProvider" />
>     <bean name="exceptionHandler" 
> class="com.mycompany.refapp.exception.AppExceptionHandler" />
> </util:list>
> <bean id="customerRestClientFactory" 
> class="com.mycompany.refapp.client.CustomerRestClientFactory">
>     <property name="providerList" ref="providerList" />
>     <property name="serviceUrl" value="${customer.rest.service.url}" />
> </bean>
> {code}
> Log containing stack traces (attached).
> After a lot of debugging, I came to an understanding that the *counter* for 
> connection failures never exceeds the threshold limit because the state of 
> the data (including the *counter*) is specific to each of the WebClient 
> objects, instantiated for each call. I assumed that if the same instance of a 
> WebClient is used across multiple calls that fail, then the *counter* would 
> have been updated and eventually open the circuit. Please find attached 
> screenshot for details.
> 1) Is my understanding correct?
> 2) Kindly help with a working example, as the one mentioned in [CWIKI 
> documentation|https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Failover#JAX-RSFailover-Code.1]
>  is not working.
> !Reason_UnableToOpenCircuit_WebClient_ProgramaticApproach.png!
>  
>  



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to