[ 
https://issues.apache.org/jira/browse/CXF-7663?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

RANADEEP SHARMA updated CXF-7663:
---------------------------------
    Description: 
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!

 

 

  was:
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.

!Reason_UnableToOpenCircuit_WebClient_ProgramaticApproach.png!

 

1) Is my understanding correct?

2) Kindly help with a working example, as the one mentioned in CWIKI 
documentation is not working.


> 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