0

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.

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;
}

}

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();
}

}

<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>

Log containing stack traces (available here).

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.

I would like to get a second opinion on whether my understanding is correct.

1 Answers1

1

You have opened issue https://issues.apache.org/jira/browse/CXF-7663 in parallel, so I share the response from Colm here:

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

Dennis Kieselhorst
  • 1,280
  • 1
  • 13
  • 23