Simple, quick and most flexible solution could be :
Put the number of failure in an exchange property.
Put circuit state in an exchange property (2 status : Open / closed, as halfOpen do the same as closed in term of business)
use a Content Based Router to perform something like
.circuitBreaker(3, 3000L, MyCustomException.class)
.when(property(Exchange.CircuitBreaker_errorCount).isEqualTo("1")) //First error encountered, send an alert to monitoring
I also see the current solution is not enough robust.
when halfOpen is reached, (System.currentTimeMillis() - lastFailure < halfOpenAfter) there is no restriction on the number of calls (threads) that will perform a retry.
When retry timeout is reached, we should let only 1 thread go in "halfOpen" mode, all other should be kept in "open" state until an halfOpen succeed.
(will create new issue for this)