16
16
17
17
package org .springframework .boot .actuate .health ;
18
18
19
- import java .util .LinkedHashMap ;
20
19
import java .util .Map ;
21
- import java .util .concurrent .CompletableFuture ;
22
- import java .util .concurrent .ExecutionException ;
23
- import java .util .concurrent .Executor ;
24
- import java .util .concurrent .Future ;
25
- import java .util .concurrent .TimeUnit ;
26
- import java .util .concurrent .TimeoutException ;
27
-
28
- import org .springframework .util .Assert ;
29
20
30
21
/**
31
- * {@link HealthIndicator} that returns health indications from all registered delegates.
22
+ * {@link HealthIndicator} that returns health indications from all registered delegates
23
+ * using the {@link HealthIndicatorStrategy} and aggregates the result via
24
+ * {@link HealthAggregator} into a final one.
32
25
*
33
26
* @author Tyler J. Frederick
34
27
* @author Phillip Webb
@@ -41,7 +34,7 @@ public class CompositeHealthIndicator implements HealthIndicator {
41
34
42
35
private final HealthAggregator aggregator ;
43
36
44
- private final HealthStrategy strategy ;
37
+ private final HealthIndicatorStrategy strategy ;
45
38
46
39
/**
47
40
* Create a new {@link CompositeHealthIndicator} from the specified indicators.
@@ -60,11 +53,20 @@ public CompositeHealthIndicator(HealthAggregator healthAggregator, Map<String, H
60
53
* @param registry the registry of {@link HealthIndicator HealthIndicators}.
61
54
*/
62
55
public CompositeHealthIndicator (HealthAggregator healthAggregator , HealthIndicatorRegistry registry ) {
63
- this (healthAggregator , registry , new SequentialStrategy ());
56
+ this (healthAggregator , registry , new DefaultHealthIndicatorStrategy ());
64
57
}
65
58
66
- private CompositeHealthIndicator (HealthAggregator healthAggregator , HealthIndicatorRegistry registry ,
67
- HealthStrategy strategy ) {
59
+ /**
60
+ * Create a new {@link CompositeHealthIndicator} from the indicators in the given
61
+ * {@code registry}.
62
+ * @param healthAggregator the health aggregator
63
+ * @param registry the registry of {@link HealthIndicator HealthIndicators}.
64
+ * @param strategy the strategy how {@link HealthIndicator HealthIndicator} instnaces
65
+ * should be called.
66
+ * @since 2.2.0
67
+ */
68
+ public CompositeHealthIndicator (HealthAggregator healthAggregator , HealthIndicatorRegistry registry ,
69
+ HealthIndicatorStrategy strategy ) {
68
70
this .aggregator = healthAggregator ;
69
71
this .registry = registry ;
70
72
this .strategy = strategy ;
@@ -79,117 +81,10 @@ public HealthIndicatorRegistry getRegistry() {
79
81
return this .registry ;
80
82
}
81
83
82
- /**
83
- * Returns a new {@link CompositeHealthIndicator} with a parallel strategy that
84
- * returns health indications from all registered delegates concurrently.
85
- * @param timeout number of milliseconds to wait before using the
86
- * {@code timeoutHealth}
87
- * @param timeoutHealth the {@link Health} to use if an health indicator reached the
88
- * {@code timeout}. Defaults to {@code unknown} status.
89
- * @param executor the executor to submit {@link HealthIndicator HealthIndicators} on.
90
- * @return new instance with a parallel strategy
91
- * @since 2.2.0
92
- */
93
- public CompositeHealthIndicator parallel (Executor executor , long timeout , Health timeoutHealth ) {
94
- Assert .notNull (executor , "Executor must not be null" );
95
- ParallelStrategy strategy = new ParallelStrategy (executor , timeout , timeoutHealth );
96
- return new CompositeHealthIndicator (this .aggregator , this .registry , strategy );
97
- }
98
-
99
- /**
100
- * Returns a new {@link CompositeHealthIndicator} with a parallel strategy that
101
- * returns health indications from all registered delegates concurrently.
102
- * @param executor the executor to submit {@link HealthIndicator HealthIndicators} on.
103
- * @return new instance with a parallel strategy
104
- * @since 2.2.0
105
- */
106
- public CompositeHealthIndicator parallel (Executor executor ) {
107
- Assert .notNull (executor , "Executor must not be null" );
108
- ParallelStrategy strategy = new ParallelStrategy (executor , null , null );
109
- return new CompositeHealthIndicator (this .aggregator , this .registry , strategy );
110
- }
111
-
112
- /**
113
- * Returns a new {@link CompositeHealthIndicator} with a sequential strategy that
114
- * returns health indications from all registered delegates sequentially.
115
- * @return new instance with a sequential strategy
116
- * @since 2.2.0
117
- */
118
- public CompositeHealthIndicator sequential () {
119
- return new CompositeHealthIndicator (this .aggregator , this .registry , new SequentialStrategy ());
120
- }
121
-
122
84
@ Override
123
85
public Health health () {
124
86
Map <String , Health > healths = this .strategy .doHealth (this .registry .getAll ());
125
87
return this .aggregator .aggregate (healths );
126
88
}
127
89
128
- @ FunctionalInterface
129
- private interface HealthStrategy {
130
-
131
- Map <String , Health > doHealth (Map <String , HealthIndicator > healthIndicators );
132
-
133
- }
134
-
135
- private static final class SequentialStrategy implements HealthStrategy {
136
-
137
- @ Override
138
- public Map <String , Health > doHealth (Map <String , HealthIndicator > healthIndicators ) {
139
- Map <String , Health > healths = new LinkedHashMap <>();
140
- for (Map .Entry <String , HealthIndicator > entry : healthIndicators .entrySet ()) {
141
- healths .put (entry .getKey (), entry .getValue ().health ());
142
- }
143
- return healths ;
144
- }
145
-
146
- }
147
-
148
- private static final class ParallelStrategy implements HealthStrategy {
149
-
150
- private final Executor executor ;
151
-
152
- private final Long timeout ;
153
-
154
- private final Health timeoutHealth ;
155
-
156
- private ParallelStrategy (Executor executor , Long timeout , Health timeoutHealth ) {
157
- this .executor = executor ;
158
- this .timeout = timeout ;
159
- this .timeoutHealth = (timeoutHealth != null ) ? timeoutHealth : Health .unknown ().build ();
160
- }
161
-
162
- @ Override
163
- public Map <String , Health > doHealth (Map <String , HealthIndicator > healthIndicators ) {
164
- Map <String , Future <Health >> healthsFutures = new LinkedHashMap <>();
165
- for (Map .Entry <String , HealthIndicator > entry : healthIndicators .entrySet ()) {
166
- healthsFutures .put (entry .getKey (),
167
- CompletableFuture .supplyAsync (entry .getValue ()::health , this .executor ));
168
- }
169
- Map <String , Health > healths = new LinkedHashMap <>();
170
- for (Map .Entry <String , Future <Health >> entry : healthsFutures .entrySet ()) {
171
- healths .put (entry .getKey (), getHealth (entry .getValue (), this .timeout , this .timeoutHealth ));
172
- }
173
- return healths ;
174
- }
175
-
176
- private static Health getHealth (Future <Health > healthFuture , Long timeout , Health timeoutHealth ) {
177
- try {
178
- return (timeout != null ) ? healthFuture .get (timeout , TimeUnit .MILLISECONDS ) : healthFuture .get ();
179
- }
180
- catch (InterruptedException ex ) {
181
- Thread .currentThread ().interrupt ();
182
- return Health .unknown ().withException (ex ).build ();
183
- }
184
- catch (TimeoutException ex ) {
185
- return timeoutHealth ;
186
- }
187
- catch (ExecutionException ex ) {
188
- Throwable cause = ex .getCause ();
189
- return Health .down ((cause instanceof Exception ) ? ((Exception ) cause ) : ex ).build ();
190
- }
191
- }
192
-
193
- }
194
-
195
90
}
0 commit comments