View Javadoc
1   package net.secodo.jcircuitbreaker.breaker.impl;
2   
3   import java.util.concurrent.Callable;
4   
5   import net.secodo.jcircuitbreaker.breaker.builder.impl.ReusableCircuitBreakerBuilder;
6   import net.secodo.jcircuitbreaker.breakhandler.BreakHandler;
7   import net.secodo.jcircuitbreaker.breakhandler.exception.BreakHandlerException;
8   import net.secodo.jcircuitbreaker.breakstrategy.BreakStrategy;
9   import net.secodo.jcircuitbreaker.exception.CircuitBreakerException;
10  import net.secodo.jcircuitbreaker.exception.TaskExecutionException;
11  import net.secodo.jcircuitbreaker.task.Task;
12  
13  
14  /**
15   * An abstract implementation of {@link net.secodo.jcircuitbreaker.breaker.CircuitBreaker} which stores its
16   * {@link BreakStrategy} and {@link BreakHandler} as fields, so that there is no need to pass them each time.  This has 
17   * following consequence: both <i>break strategy</i> and <i>break handler</i> will be shared between different 
18   * executions of <i>target-method</i>, so they should be "stateless". If this is not guaranteed 
19   * (for each Task (runtime method) different instances of {@link BreakHandler}) should be created) 
20   * than {@link net.secodo.jcircuitbreaker.breakhandler.BreakHandlerFactory} should be used.
21   *
22   * @param <R> the return type of the called method
23   */
24  public class ReusableCircuitBreaker<R> extends AbstractCircuitBreaker<R> {
25    private final BreakStrategy<R> breakStrategy;
26    private final BreakHandler<R> breakHandler;
27  
28    /**
29     * Constructs new breaker with given break strategy and break handler. Break strategy and break handler will be
30     * applied to each execution of the circuit breaker.
31     *
32     * @param breakStrategy a break strategy to apply to each Task executed by this circuit breaker
33     * @param breakHandler  a break handler to apply fallback value (or fallback behaviour) when execution of task is
34     *                      prohibited by break strategy
35     */
36    public ReusableCircuitBreaker(BreakStrategy<R> breakStrategy, BreakHandler<R> breakHandler) {
37      super();
38      this.breakStrategy = breakStrategy;
39      this.breakHandler = breakHandler;
40    }
41  
42    /**
43     * Builder for {@link ReusableCircuitBreaker}. Allows to create {@link ReusableCircuitBreaker} in a
44     * fluent-interface way.
45     *
46     * @return an instance of builder which is used to construct {@link ReusableCircuitBreaker}
47     */
48    @SuppressWarnings("rawtypes") // for convenience in usage
49    public static ReusableCircuitBreakerBuilder builder() {
50      return new ReusableCircuitBreakerBuilder();
51    }
52  
53    /**
54     * Builder for {@link ReusableCircuitBreaker}. Allows to create {@link ReusableCircuitBreaker} in a
55     * fluent-interface way. This method is parameterized and requires return type of java <i>target-method</i> to be
56     * defined while calling this method.
57     *
58     * @param <R> the return type or <i>target-method</i> to be executed by circuit breaker
59     * @return an instance of builder which is used to construct {@link ReusableCircuitBreaker}
60     */
61    public static <R> ReusableCircuitBreakerBuilder<R> builderP() {
62      return new ReusableCircuitBreakerBuilder<>();
63    }
64  
65  
66    /**
67     * Executes given Task within this breaker using {@link BreakStrategy} and {@link BreakHandler} given as the params.
68     *
69     * @param task the real-method to be executed
70     * @return the output value of the real method
71     * @see net.secodo.jcircuitbreaker.breaker.CircuitBreaker#execute(Task, BreakStrategy, BreakHandler)
72     *
73     * @throws TaskExecutionException if execution of given Task results in exception
74     */
75    public R execute(Task<R> task) throws TaskExecutionException, CircuitBreakerException, BreakHandlerException {
76      return super.execute(task, breakStrategy, breakHandler);
77    }
78  
79    /**
80     * Executes given Task within this breaker using {@link BreakStrategy} and {@link BreakHandler} given as the params
81     * with custom data passed as userData param.
82     *
83     * @param task the real-method to be executed
84     * @param userData custom object with data which will be made available to break strategy and break handler via
85     *                 execution context
86     * @param <U> the type of user data object which will be made available to break strategy and break handler via
87     *           execution context
88     * @return the output value of the real method
89     *
90     * @see net.secodo.jcircuitbreaker.breaker.CircuitBreaker#execute(Task, BreakStrategy, BreakHandler, Object)
91     *
92     * @throws TaskExecutionException if execution of given Task results in exception
93     */
94    public <U> R execute(Task<R> task, U userData) throws TaskExecutionException, CircuitBreakerException,
95                                                              BreakHandlerException {
96      return super.execute(task, breakStrategy, breakHandler, userData);
97    }
98  }