CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-springframework-cloud--spring-cloud-commons

Spring Cloud Commons provides foundational abstractions and utilities for service discovery, load balancing, circuit breakers, and cloud-native application development.

Pending
Overview
Eval results
Files

circuit-breakers.mddocs/

Circuit Breakers

Circuit breakers provide resilience patterns for handling service failures and preventing cascading failures in distributed systems. Spring Cloud Commons provides abstractions for both synchronous and reactive circuit breaker implementations.

Capabilities

Enable Circuit Breaker

Enables circuit breaker functionality in your Spring Boot application.

/**
 * Enables circuit breaker functionality
 */
@EnableCircuitBreaker
public @interface EnableCircuitBreaker {}

Usage Example:

@SpringBootApplication
@EnableCircuitBreaker
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

Circuit Breaker Interface

Main interface for synchronous circuit breaker operations.

/**
 * Main interface for synchronous circuit breaker operations
 */
public interface CircuitBreaker {
    /**
     * Execute a supplier within the circuit breaker
     * @param toRun The supplier to execute
     * @return The result from the supplier
     */
    <T> T run(Supplier<T> toRun);
    
    /**
     * Execute a supplier within the circuit breaker with fallback
     * @param toRun The supplier to execute
     * @param fallback The fallback function to execute if the supplier fails
     * @return The result from the supplier or fallback
     */
    <T> T run(Supplier<T> toRun, Function<Throwable, T> fallback);
}

Usage Examples:

@Service
public class UserService {
    
    @Autowired
    private CircuitBreakerFactory circuitBreakerFactory;
    
    private CircuitBreaker circuitBreaker;
    
    @PostConstruct
    public void init() {
        this.circuitBreaker = circuitBreakerFactory.create("user-service");
    }
    
    public String getUser(String userId) {
        return circuitBreaker.run(
            () -> callUserService(userId),
            throwable -> "Default User"
        );
    }
    
    public String getUserWithNoFallback(String userId) {
        return circuitBreaker.run(() -> callUserService(userId));
    }
    
    private String callUserService(String userId) {
        // Make HTTP call to user service
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject("http://user-service/users/" + userId, String.class);
    }
}

Reactive Circuit Breaker

Reactive interface for circuit breaker operations using Project Reactor.

/**
 * Reactive interface for circuit breaker operations
 */
public interface ReactiveCircuitBreaker {
    /**
     * Execute a Mono within the circuit breaker
     * @param toRun The Mono to execute
     * @return The Mono result wrapped in circuit breaker logic
     */
    <T> Mono<T> run(Mono<T> toRun);
    
    /**
     * Execute a Mono within the circuit breaker with fallback
     * @param toRun The Mono to execute
     * @param fallback The fallback function to execute if the Mono fails
     * @return The Mono result or fallback wrapped in circuit breaker logic
     */
    <T> Mono<T> run(Mono<T> toRun, Function<Throwable, Mono<T>> fallback);
    
    /**
     * Execute a Flux within the circuit breaker
     * @param toRun The Flux to execute
     * @return The Flux result wrapped in circuit breaker logic
     */
    <T> Flux<T> run(Flux<T> toRun);
    
    /**
     * Execute a Flux within the circuit breaker with fallback
     * @param toRun The Flux to execute
     * @param fallback The fallback function to execute if the Flux fails
     * @return The Flux result or fallback wrapped in circuit breaker logic
     */
    <T> Flux<T> run(Flux<T> toRun, Function<Throwable, Flux<T>> fallback);
}

Usage Examples:

@Service
public class ReactiveUserService {
    
    @Autowired
    private ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory;
    
    private ReactiveCircuitBreaker circuitBreaker;
    
    @PostConstruct
    public void init() {
        this.circuitBreaker = reactiveCircuitBreakerFactory.create("user-service");
    }
    
    public Mono<String> getUser(String userId) {
        return circuitBreaker.run(
            callUserServiceReactively(userId),
            throwable -> Mono.just("Default User")
        );
    }
    
    public Flux<String> getAllUsers() {
        return circuitBreaker.run(
            callAllUsersReactively(),
            throwable -> Flux.just("Default User 1", "Default User 2")
        );
    }
    
    private Mono<String> callUserServiceReactively(String userId) {
        WebClient webClient = WebClient.create();
        return webClient.get()
            .uri("http://user-service/users/{id}", userId)
            .retrieve()
            .bodyToMono(String.class);
    }
    
    private Flux<String> callAllUsersReactively() {
        WebClient webClient = WebClient.create();
        return webClient.get()
            .uri("http://user-service/users")
            .retrieve()
            .bodyToFlux(String.class);
    }
}

Circuit Breaker Factory

Abstract factory for creating circuit breaker instances.

/**
 * Abstract factory for creating circuit breaker instances
 */
public abstract class CircuitBreakerFactory<CONF, CONFB> {
    /**
     * Create a circuit breaker with the given ID
     * @param id The circuit breaker ID
     * @return A new CircuitBreaker instance  
     */
    public abstract CircuitBreaker create(String id);
    
    /**
     * Create a circuit breaker with the given ID and group
     * @param id The circuit breaker ID
     * @param groupName The circuit breaker group name
     * @return A new CircuitBreaker instance
     */
    public CircuitBreaker create(String id, String groupName) {
        return create(id);
    }
    
    /**
     * Configure the factory
     * @param consumer Configuration consumer
     */
    public abstract void configure(Consumer<CONFB> consumer);
    
    /**
     * Configure a specific circuit breaker
     * @param id The circuit breaker ID  
     * @param consumer Configuration consumer
     */
    public abstract void configure(String id, Consumer<CONFB> consumer);
    
    /**
     * Configure a group of circuit breakers
     * @param groupName The group name
     * @param consumer Configuration consumer
     */
    public void configureGroup(String groupName, Consumer<CONFB> consumer) {
        // Default implementation - override as needed
    }
}

/**
 * Abstract factory for reactive circuit breakers
 */
public abstract class ReactiveCircuitBreakerFactory<CONF, CONFB> {
    /**
     * Create a reactive circuit breaker with the given ID
     * @param id The circuit breaker ID
     * @return A new ReactiveCircuitBreaker instance
     */
    public abstract ReactiveCircuitBreaker create(String id);
    
    /**
     * Create a reactive circuit breaker with the given ID and group
     * @param id The circuit breaker ID
     * @param groupName The circuit breaker group name
     * @return A new ReactiveCircuitBreaker instance
     */
    public ReactiveCircuitBreaker create(String id, String groupName) {
        return create(id);
    }
    
    /**
     * Configure the factory
     * @param consumer Configuration consumer
     */
    public abstract void configure(Consumer<CONFB> consumer);
    
    /**
     * Configure a specific reactive circuit breaker
     * @param id The circuit breaker ID
     * @param consumer Configuration consumer  
     */
    public abstract void configure(String id, Consumer<CONFB> consumer);
    
    /**
     * Configure a group of reactive circuit breakers
     * @param groupName The group name
     * @param consumer Configuration consumer
     */
    public void configureGroup(String groupName, Consumer<CONFB> consumer) {
        // Default implementation - override as needed
    }
}

/**
 * Base implementation of circuit breaker factory
 */
public abstract class AbstractCircuitBreakerFactory<CONF, CONFB> extends CircuitBreakerFactory<CONF, CONFB> {
    protected Map<String, CONF> configurations = new ConcurrentHashMap<>();
    protected Map<String, CONF> groupConfigurations = new ConcurrentHashMap<>();
    
    /**
     * Get configuration for a circuit breaker
     * @param id The circuit breaker ID
     * @return The configuration
     */
    protected CONF getConfiguration(String id) {
        return configurations.get(id);
    }
    
    /**
     * Get group configuration
     * @param groupName The group name  
     * @return The group configuration
     */
    protected CONF getGroupConfiguration(String groupName) {
        return groupConfigurations.get(groupName);
    }
}

Configuration Builder

Interface for building circuit breaker configurations.

/**
 * Interface for building circuit breaker configurations
 */
public interface ConfigBuilder<CONF> {
    /**
     * Build the configuration
     * @return The built configuration
     */
    CONF build();
}

Customization Support

Interface for customizing circuit breaker components.

/**
 * Interface for customizing components
 */
public interface Customizer<TOCUSTOMIZE> {
    /**
     * Customize the component
     * @param t The component to customize
     */
    void customize(TOCUSTOMIZE t);
}

Exception Handling

Exception thrown when no fallback is available.

/**
 * Exception thrown when no fallback is available
 */
public class NoFallbackAvailableException extends RuntimeException {
    /**
     * Create exception with message
     * @param message The error message
     */
    public NoFallbackAvailableException(String message);
    
    /**
     * Create exception with message and cause
     * @param message The error message
     * @param cause The underlying cause
     */
    public NoFallbackAvailableException(String message, Throwable cause);
}

Configuration Examples

Basic Circuit Breaker Configuration:

@Configuration
public class CircuitBreakerConfig {
    
    @Bean
    public Customizer<ReactiveResilience4JCircuitBreakerFactory> defaultCustomizer() {
        return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
            .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
            .timeLimiterConfig(TimeLimiterConfig.custom()
                .timeoutDuration(Duration.ofSeconds(4))
                .build())
            .build());
    }
    
    @Bean  
    public Customizer<ReactiveResilience4JCircuitBreakerFactory> specificCustomizer() {
        return factory -> factory.configure(builder -> builder
            .circuitBreakerConfig(CircuitBreakerConfig.custom()
                .failureRateThreshold(50)
                .waitDurationInOpenState(Duration.ofMillis(1000))
                .slidingWindowSize(2)
                .build())
            .timeLimiterConfig(TimeLimiterConfig.custom()
                .timeoutDuration(Duration.ofSeconds(2))
                .build()), "user-service", "order-service");
    }
}

Circuit Breaker with Custom Fallback:

@Service
public class OrderService {
    
    @Autowired
    private CircuitBreakerFactory circuitBreakerFactory;
    
    private CircuitBreaker circuitBreaker;
    
    @PostConstruct
    public void init() {
        this.circuitBreaker = circuitBreakerFactory.create("order-service");
    }
    
    public Order getOrder(String orderId) {
        return circuitBreaker.run(
            () -> fetchOrderFromService(orderId),
            throwable -> {
                log.error("Failed to fetch order, using fallback", throwable);
                return Order.builder()
                    .id(orderId)
                    .status("UNKNOWN")
                    .build();
            }
        );
    }
    
    private Order fetchOrderFromService(String orderId) {
        // Simulate service call that might fail
        if (Math.random() > 0.5) {
            throw new RuntimeException("Service unavailable");
        }
        return new Order(orderId, "CONFIRMED");
    }
}

Reactive Circuit Breaker with WebClient:

@Service
public class ReactiveOrderService {
    
    @Autowired
    private ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory;
    
    private ReactiveCircuitBreaker circuitBreaker;
    private WebClient webClient;
    
    @PostConstruct
    public void init() {
        this.circuitBreaker = reactiveCircuitBreakerFactory.create("order-service");
        this.webClient = WebClient.create("http://order-service");
    }
    
    public Mono<Order> getOrder(String orderId) {
        return circuitBreaker.run(
            webClient.get()
                .uri("/orders/{id}", orderId)
                .retrieve()
                .bodyToMono(Order.class),
            throwable -> Mono.just(Order.builder()
                .id(orderId)
                .status("FALLBACK")
                .build())
        );
    }
    
    public Flux<Order> getAllOrders() {
        return circuitBreaker.run(
            webClient.get()
                .uri("/orders")
                .retrieve()
                .bodyToFlux(Order.class),
            throwable -> Flux.just(
                Order.builder().id("1").status("FALLBACK").build(),
                Order.builder().id("2").status("FALLBACK").build()
            )
        );
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-springframework-cloud--spring-cloud-commons

docs

circuit-breakers.md

http-clients.md

index.md

load-balancing.md

reactive-support.md

service-discovery.md

service-registration.md

tile.json