17
17
package org .springframework .boot .actuate .autoconfigure .jdbc ;
18
18
19
19
import java .util .Collection ;
20
+ import java .util .Iterator ;
20
21
import java .util .Map ;
22
+ import java .util .function .Function ;
21
23
import java .util .stream .Collectors ;
22
24
23
25
import javax .sql .DataSource ;
24
26
25
27
import org .springframework .beans .factory .InitializingBean ;
26
28
import org .springframework .beans .factory .ObjectProvider ;
27
- import org .springframework .boot .actuate .autoconfigure .health .CompositeHealthContributorConfiguration ;
28
29
import org .springframework .boot .actuate .autoconfigure .health .ConditionalOnEnabledHealthIndicator ;
29
- import org .springframework .boot .actuate .health .AbstractHealthIndicator ;
30
- import org .springframework .boot .actuate .health .Health .Builder ;
30
+ import org .springframework .boot .actuate .health .CompositeHealthContributor ;
31
31
import org .springframework .boot .actuate .health .HealthContributor ;
32
- import org .springframework .boot .actuate .health .HealthIndicator ;
32
+ import org .springframework .boot .actuate .health .NamedContributor ;
33
33
import org .springframework .boot .actuate .jdbc .DataSourceHealthIndicator ;
34
34
import org .springframework .boot .autoconfigure .AutoConfigureAfter ;
35
35
import org .springframework .boot .autoconfigure .EnableAutoConfiguration ;
45
45
import org .springframework .context .annotation .Configuration ;
46
46
import org .springframework .jdbc .core .JdbcTemplate ;
47
47
import org .springframework .jdbc .datasource .lookup .AbstractRoutingDataSource ;
48
+ import org .springframework .util .Assert ;
48
49
49
50
/**
50
51
* {@link EnableAutoConfiguration Auto-configuration} for
64
65
@ ConditionalOnEnabledHealthIndicator ("db" )
65
66
@ AutoConfigureAfter (DataSourceAutoConfiguration .class )
66
67
@ EnableConfigurationProperties (DataSourceHealthIndicatorProperties .class )
67
- public class DataSourceHealthContributorAutoConfiguration extends
68
- CompositeHealthContributorConfiguration <AbstractHealthIndicator , DataSource > implements InitializingBean {
68
+ public class DataSourceHealthContributorAutoConfiguration implements InitializingBean {
69
69
70
70
private final Collection <DataSourcePoolMetadataProvider > metadataProviders ;
71
71
@@ -94,10 +94,18 @@ public HealthContributor dbHealthContributor(Map<String, DataSource> dataSources
94
94
return createContributor (dataSources );
95
95
}
96
96
97
- @ Override
98
- protected AbstractHealthIndicator createIndicator (DataSource source ) {
97
+ private HealthContributor createContributor (Map <String , DataSource > beans ) {
98
+ Assert .notEmpty (beans , "Beans must not be empty" );
99
+ if (beans .size () == 1 ) {
100
+ return createIndicator (beans .values ().iterator ().next ());
101
+ }
102
+ return CompositeHealthContributor .fromMap (beans , this ::createIndicator );
103
+ }
104
+
105
+ private HealthContributor createIndicator (DataSource source ) {
99
106
if (source instanceof AbstractRoutingDataSource ) {
100
- return new RoutingDataSourceHealthIndicator ();
107
+ AbstractRoutingDataSource routingDataSource = (AbstractRoutingDataSource ) source ;
108
+ return new RoutingDataSourceHealthIndicator (routingDataSource , this ::createIndicator );
101
109
}
102
110
return new DataSourceHealthIndicator (source , getValidationQuery (source ));
103
111
}
@@ -108,14 +116,29 @@ private String getValidationQuery(DataSource source) {
108
116
}
109
117
110
118
/**
111
- * {@link HealthIndicator} used for {@link AbstractRoutingDataSource} beans where we
112
- * can't actually query for the status.
119
+ * {@link CompositeHealthContributor} used for {@link AbstractRoutingDataSource} beans
120
+ * where the overall health is composed of a {@link DataSourceHealthIndicator} for
121
+ * each routed datasource.
113
122
*/
114
- static class RoutingDataSourceHealthIndicator extends AbstractHealthIndicator {
123
+ static class RoutingDataSourceHealthIndicator implements CompositeHealthContributor {
124
+
125
+ private CompositeHealthContributor delegate ;
126
+
127
+ RoutingDataSourceHealthIndicator (AbstractRoutingDataSource routingDataSource ,
128
+ Function <DataSource , HealthContributor > indicatorFunction ) {
129
+ Map <String , DataSource > routedDataSources = routingDataSource .getResolvedDataSources ().entrySet ().stream ()
130
+ .collect (Collectors .toMap ((e ) -> e .getKey ().toString (), Map .Entry ::getValue ));
131
+ this .delegate = CompositeHealthContributor .fromMap (routedDataSources , indicatorFunction );
132
+ }
133
+
134
+ @ Override
135
+ public HealthContributor getContributor (String name ) {
136
+ return this .delegate .getContributor (name );
137
+ }
115
138
116
139
@ Override
117
- protected void doHealthCheck ( Builder builder ) throws Exception {
118
- builder . unknown (). withDetail ( "routing" , true );
140
+ public Iterator < NamedContributor < HealthContributor >> iterator () {
141
+ return this . delegate . iterator ( );
119
142
}
120
143
121
144
}
0 commit comments