use of io.micronaut.aop.InterceptedMethod in project resilience4j by resilience4j.
the class RateLimiterInterceptor method intercept.
@Override
public Object intercept(MethodInvocationContext<Object, Object> context) {
Optional<AnnotationValue<io.github.resilience4j.micronaut.annotation.RateLimiter>> opt = context.findAnnotation(io.github.resilience4j.micronaut.annotation.RateLimiter.class);
if (!opt.isPresent()) {
return context.proceed();
}
ExecutableMethod executableMethod = context.getExecutableMethod();
final String name = executableMethod.stringValue(io.github.resilience4j.micronaut.annotation.RateLimiter.class, "name").orElse("default");
RateLimiter rateLimiter = this.rateLimiterRegistry.rateLimiter(name);
InterceptedMethod interceptedMethod = InterceptedMethod.of(context);
try {
switch(interceptedMethod.resultType()) {
case PUBLISHER:
return interceptedMethod.handleResult(fallbackReactiveTypes(Flowable.fromPublisher(interceptedMethod.interceptResultAsPublisher()).compose(RateLimiterOperator.of(rateLimiter)), context));
case COMPLETION_STAGE:
return interceptedMethod.handleResult(fallbackForFuture(rateLimiter.executeCompletionStage(() -> {
try {
return interceptedMethod.interceptResultAsCompletionStage();
} catch (Exception e) {
throw new CompletionException(e);
}
}), context));
case SYNCHRONOUS:
try {
return rateLimiter.executeCheckedSupplier(context::proceed);
} catch (Throwable exception) {
return fallback(context, exception);
}
default:
return interceptedMethod.unsupported();
}
} catch (Exception e) {
return interceptedMethod.handleException(e);
}
}
use of io.micronaut.aop.InterceptedMethod in project resilience4j by resilience4j.
the class BulkheadInterceptor method intercept.
@Override
public Object intercept(MethodInvocationContext<Object, Object> context) {
Optional<AnnotationValue<io.github.resilience4j.micronaut.annotation.Bulkhead>> opt = context.findAnnotation(io.github.resilience4j.micronaut.annotation.Bulkhead.class);
if (!opt.isPresent()) {
return context.proceed();
}
final io.github.resilience4j.micronaut.annotation.Bulkhead.Type type = opt.get().enumValue("type", io.github.resilience4j.micronaut.annotation.Bulkhead.Type.class).orElse(io.github.resilience4j.micronaut.annotation.Bulkhead.Type.SEMAPHORE);
if (type == io.github.resilience4j.micronaut.annotation.Bulkhead.Type.THREADPOOL) {
return handleThreadPoolBulkhead(context, opt.get());
} else {
final String name = opt.get().stringValue("name").orElse("default");
Bulkhead bulkhead = this.bulkheadRegistry.bulkhead(name);
InterceptedMethod interceptedMethod = InterceptedMethod.of(context);
try {
switch(interceptedMethod.resultType()) {
case PUBLISHER:
return interceptedMethod.handleResult(fallbackReactiveTypes(Flowable.fromPublisher(interceptedMethod.interceptResultAsPublisher()).compose(BulkheadOperator.of(bulkhead)), context));
case COMPLETION_STAGE:
return interceptedMethod.handleResult(fallbackForFuture(bulkhead.executeCompletionStage(() -> {
try {
return interceptedMethod.interceptResultAsCompletionStage();
} catch (Exception e) {
throw new CompletionException(e);
}
}), context));
case SYNCHRONOUS:
try {
return bulkhead.executeCheckedSupplier(context::proceed);
} catch (Throwable exception) {
return fallback(context, exception);
}
default:
return interceptedMethod.unsupported();
}
} catch (Exception e) {
return interceptedMethod.handleException(e);
}
}
}
use of io.micronaut.aop.InterceptedMethod in project resilience4j by resilience4j.
the class RetryInterceptor method intercept.
@Override
public Object intercept(MethodInvocationContext<Object, Object> context) {
Optional<AnnotationValue<io.github.resilience4j.micronaut.annotation.Retry>> opt = context.findAnnotation(io.github.resilience4j.micronaut.annotation.Retry.class);
if (!opt.isPresent()) {
return context.proceed();
}
ExecutableMethod executableMethod = context.getExecutableMethod();
final String name = executableMethod.stringValue(io.github.resilience4j.micronaut.annotation.Retry.class, "name").orElse("default");
Retry retry = retryRegistry.retry(name);
InterceptedMethod interceptedMethod = InterceptedMethod.of(context);
try {
switch(interceptedMethod.resultType()) {
case PUBLISHER:
return interceptedMethod.handleResult(fallbackReactiveTypes(Flowable.fromPublisher(interceptedMethod.interceptResultAsPublisher()).compose(RetryTransformer.of(retry)), context));
case COMPLETION_STAGE:
return interceptedMethod.handleResult(fallbackForFuture(retry.executeCompletionStage(executorService, () -> {
try {
return interceptedMethod.interceptResultAsCompletionStage();
} catch (Exception e) {
throw new CompletionException(e);
}
}), context));
case SYNCHRONOUS:
try {
return retry.executeCheckedSupplier(context::proceed);
} catch (Throwable exception) {
return fallback(context, exception);
}
default:
return interceptedMethod.unsupported();
}
} catch (Exception e) {
return interceptedMethod.handleException(e);
}
}
use of io.micronaut.aop.InterceptedMethod in project micronaut-micrometer by micronaut-projects.
the class CountedInterceptor method intercept.
@Override
public Object intercept(MethodInvocationContext<Object, Object> context) {
final AnnotationMetadata metadata = context.getAnnotationMetadata();
final String metricName = metadata.stringValue(Counted.class).orElse(DEFAULT_METRIC_NAME);
if (StringUtils.isNotEmpty(metricName)) {
InterceptedMethod interceptedMethod = InterceptedMethod.of(context);
try {
InterceptedMethod.ResultType resultType = interceptedMethod.resultType();
switch(resultType) {
case PUBLISHER:
Object interceptResult = context.proceed();
if (interceptResult == null) {
return null;
}
Object reactiveResult;
if (context.getReturnType().isSingleResult()) {
Mono<?> single = Publishers.convertPublisher(interceptResult, Mono.class);
reactiveResult = single.doOnError(throwable -> doCount(metadata, metricName, throwable)).doOnSuccess(o -> doCount(metadata, metricName, null));
} else {
Flux<?> flowable = Publishers.convertPublisher(interceptResult, Flux.class);
reactiveResult = flowable.doOnError(throwable -> doCount(metadata, metricName, throwable)).doOnComplete(() -> doCount(metadata, metricName, null));
}
return Publishers.convertPublisher(reactiveResult, context.getReturnType().getType());
case COMPLETION_STAGE:
CompletionStage<?> completionStage = interceptedMethod.interceptResultAsCompletionStage();
CompletionStage<?> completionStageResult = completionStage.whenComplete((o, throwable) -> doCount(metadata, metricName, throwable));
return interceptedMethod.handleResult(completionStageResult);
case SYNCHRONOUS:
final Object result = context.proceed();
try {
return result;
} finally {
if (metadata.isFalse(Counted.class, "recordFailuresOnly")) {
doCount(metadata, metricName, null);
}
}
default:
return interceptedMethod.unsupported();
}
} catch (Exception e) {
try {
return interceptedMethod.handleException(e);
} finally {
doCount(metadata, metricName, e);
}
}
}
return context.proceed();
}
use of io.micronaut.aop.InterceptedMethod in project resilience4j by resilience4j.
the class BulkheadInterceptor method handleThreadPoolBulkhead.
private CompletionStage<?> handleThreadPoolBulkhead(MethodInvocationContext<Object, Object> context, AnnotationValue<io.github.resilience4j.micronaut.annotation.Bulkhead> bulkheadAnnotationValue) {
final String name = bulkheadAnnotationValue.stringValue().orElse("default");
ThreadPoolBulkhead bulkhead = this.threadPoolBulkheadRegistry.bulkhead(name);
InterceptedMethod interceptedMethod = InterceptedMethod.of(context);
if (interceptedMethod.resultType() == InterceptedMethod.ResultType.COMPLETION_STAGE) {
try {
return this.fallbackForFuture(bulkhead.executeSupplier(() -> {
try {
return ((CompletableFuture<?>) context.proceed()).get();
} catch (ExecutionException e) {
throw new CompletionException(e.getCause());
} catch (Throwable e) {
throw new CompletionException(e);
}
}), context);
} catch (BulkheadFullException ex) {
CompletableFuture<?> future = new CompletableFuture<>();
future.completeExceptionally(ex);
return future;
}
}
throw new IllegalStateException("ThreadPool bulkhead is only applicable for completable futures");
}
Aggregations