All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.resilience4j.micronaut.util.RxJava2PublisherExtension Maven / Gradle / Ivy

Go to download

Resilience4j is a lightweight, easy-to-use fault tolerance library designed for Java8 and functional programming

There is a newer version: 2.2.0
Show newest version
package io.github.resilience4j.micronaut.util;

import io.github.resilience4j.AbstractSubscriber;
import io.github.resilience4j.bulkhead.Bulkhead;
import io.github.resilience4j.bulkhead.operator.BulkheadOperator;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.operator.CircuitBreakerOperator;
import io.github.resilience4j.ratelimiter.RateLimiter;
import io.github.resilience4j.ratelimiter.operator.RateLimiterOperator;
import io.github.resilience4j.retry.Retry;
import io.github.resilience4j.retry.transformer.RetryTransformer;
import io.github.resilience4j.timelimiter.TimeLimiter;
import io.github.resilience4j.timelimiter.transformer.TimeLimiterTransformer;
import io.micronaut.aop.MethodInvocationContext;
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.convert.ConversionService;
import io.micronaut.inject.MethodExecutionHandle;
import io.micronaut.retry.exception.FallbackException;
import io.reactivex.Flowable;
import jakarta.inject.Singleton;
import org.reactivestreams.Publisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Optional;
import java.util.function.Function;

@Singleton
@Requires(classes = {Flowable.class, AbstractSubscriber.class})
public class RxJava2PublisherExtension implements PublisherExtension {
    private static final Logger logger = LoggerFactory.getLogger(RxJava2PublisherExtension.class);

    @Override
    public  Publisher bulkhead(Publisher publisher, Bulkhead bulkhead) {
        return Flowable.fromPublisher(publisher).compose(BulkheadOperator.of(bulkhead));
    }

    @Override
    public  Publisher circuitBreaker(Publisher publisher, CircuitBreaker circuitBreaker) {
        return Flowable.fromPublisher(publisher).compose(CircuitBreakerOperator.of(circuitBreaker));
    }

    @Override
    public  Publisher timeLimiter(Publisher publisher, TimeLimiter timeLimiter) {
        return Flowable.fromPublisher(publisher).compose(TimeLimiterTransformer.of(timeLimiter));
    }

    @Override
    public  Publisher retry(Publisher publisher, Retry retry) {
        return Flowable.fromPublisher(publisher).compose(RetryTransformer.of(retry));
    }

    @Override
    public  Publisher rateLimiter(Publisher publisher, RateLimiter rateLimiter) {
        return Flowable.fromPublisher(publisher).compose(RateLimiterOperator.of(rateLimiter));
    }

    @Override
    public  Publisher fallbackPublisher(Publisher publisher, MethodInvocationContext context, Function, Optional>> handler) {
        return Flowable.fromPublisher(publisher).onErrorResumeNext(throwable -> {
            Optional> fallbackMethod = handler.apply(context);
            if (fallbackMethod.isPresent()) {
                MethodExecutionHandle fallbackHandle = fallbackMethod.get();
                if (logger.isDebugEnabled()) {
                    logger.debug("Type [{}] resolved fallback: {}", context.getTarget().getClass(), fallbackHandle);
                }
                Object fallbackResult;
                try {
                    fallbackResult = fallbackHandle.invoke(context.getParameterValues());
                } catch (Exception e) {
                    return Flowable.error(throwable);
                }
                if (fallbackResult == null) {
                    return Flowable.error(new FallbackException("Fallback handler [" + fallbackHandle + "] returned null value"));
                } else {
                    return ConversionService.SHARED.convert(fallbackResult, Publisher.class)
                        .orElseThrow(() -> new FallbackException("Unsupported Reactive type: " + fallbackResult));
                }
            }
            return Flowable.error(throwable);
        });
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy