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 }