Fixes: #458
* Fix code formatting violations
* * Make `retryContextToSample` as an `IdentityHashMap` and use `RetryContext` as a key
* Change `setCustomTags()` to the `@Nullable Iterable<Tag>` argument
* Use `exception = none` tag for successful executions to avoid time-series conflicts
* Add @Nullable in RetryContext to easier detect possible NPE
Both getParent() and getLastThrowable() might return null, as mentioned
in javadoc. @Nullable helps an IDE warns developers about potential NPE.
* Rephrase Javadoc for RetryContext.getLastThrowable()
* Review fixes
Fixes: #456
The random logic in the `ExponentialRandomBackOffPolicy` may end up with close to the `1`.
And after casting to `long` we got the same `1000`
* Fix test respectively to include that possibility.
Fixes: #441
* Replace `Classifier` with more widely used `Predicate` in `RetryTemplateBuilder`
* Introduce `PredicateRetryPolicy` to avoid backward incompatible changes
Fixes: #82
There are some use-cases when `ExhaustedRetryException` does not fit into the logic around Circuit Breaker pattern.
The `RetryTemplate` has already a `throwLastExceptionOnExhausted` flag for stateful retries
* Expose `@CircuitBreaker.throwLastExceptionOnExhausted()` and propagate it down to the `RetryTemplate`
in the `AnnotationAwareRetryOperationsInterceptor`
Fixes: #427
No randomness with configuration like:
```
@Retryable(retryFor = {RuntimeException.class}, maxAttemptsExpression = "${retry.max-attempts}", backoff = @Backoff(delayExpression = "${retry.delay}", multiplierExpression = "${retry.multiplier}", randomExpression = "${retry.random}"))
```
The random logic in the `AnnotationAwareRetryOperationsInterceptor` if `multiplierExpression` is for runtime evaluation.
* Fix `AnnotationAwareRetryOperationsInterceptor` to check for `if (multiplier > 0 || parsedMultExp != null) {` before evaluating `random`
* Fix `@BackOff(randomExpression)` Javadoc to indicate that it is always evaluated on configuration phase.
Fixes: #422
* Push `MethodInvocationRetryCallback.getLabel()` to the `default` method in the `RetryCallback`
* Use `ClassUtils.getQualifiedMethodName(invocation.getMethod())` for default label in the `MethodInvocationRetryCallback`
if not provided from the outside
* Refactor some logic in the `RetryOperationsInterceptor` to cover `context.removeAttribute("__proxy__")`
for use-case when `recoverer` is not provided.
Remove extra label resolution since it is already done in the `MethodInvocationRetryCallback`
* Fix Javadoc typos in the affected classes
Fixes#212
The `classifiable` class checked twice: by itself
and then as a first iteration for the next loop for subclasses.
* Fix `SubclassClassifier.classify()` to start subclasses loop
from the `exceptionClass.getSuperclass()`