Skip to content

Commit 14a6c60

Browse files
committed
Rework some aspects of the probes support
Closes spring-projectsgh-20962
2 parents 7c3369c + f62dbc9 commit 14a6c60

File tree

56 files changed

+1649
-1131
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1649
-1131
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Copyright 2012-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.availability;
18+
19+
import org.springframework.boot.actuate.autoconfigure.availability.AvailabilityProbesAutoConfiguration.ProbesCondition;
20+
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
21+
import org.springframework.boot.actuate.availability.LivenessStateHealthIndicator;
22+
import org.springframework.boot.actuate.availability.ReadinessStateHealthIndicator;
23+
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
24+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
25+
import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration;
26+
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
27+
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
28+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
29+
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
30+
import org.springframework.boot.availability.ApplicationAvailability;
31+
import org.springframework.boot.cloud.CloudPlatform;
32+
import org.springframework.context.annotation.Bean;
33+
import org.springframework.context.annotation.ConditionContext;
34+
import org.springframework.context.annotation.Conditional;
35+
import org.springframework.context.annotation.Configuration;
36+
import org.springframework.core.env.Environment;
37+
import org.springframework.core.type.AnnotatedTypeMetadata;
38+
39+
/**
40+
* {@link EnableAutoConfiguration Auto-configuration} for availability probes.
41+
*
42+
* @author Brian Clozel
43+
* @author Phillip Webb
44+
* @since 2.3.0
45+
*/
46+
@Configuration(proxyBeanMethods = false)
47+
@Conditional(ProbesCondition.class)
48+
@AutoConfigureAfter(ApplicationAvailabilityAutoConfiguration.class)
49+
public class AvailabilityProbesAutoConfiguration {
50+
51+
@Bean
52+
@ConditionalOnEnabledHealthIndicator("livenessState")
53+
@ConditionalOnMissingBean
54+
public LivenessStateHealthIndicator livenessStateHealthIndicator(ApplicationAvailability applicationAvailability) {
55+
return new LivenessStateHealthIndicator(applicationAvailability);
56+
}
57+
58+
@Bean
59+
@ConditionalOnEnabledHealthIndicator("readinessState")
60+
@ConditionalOnMissingBean
61+
public ReadinessStateHealthIndicator readinessStateHealthIndicator(
62+
ApplicationAvailability applicationAvailability) {
63+
return new ReadinessStateHealthIndicator(applicationAvailability);
64+
}
65+
66+
@Bean
67+
public AvailabilityProbesHealthEndpointGroupsPostProcessor availabilityProbesHealthEndpointGroupsPostProcessor() {
68+
return new AvailabilityProbesHealthEndpointGroupsPostProcessor();
69+
}
70+
71+
/**
72+
* {@link SpringBootCondition} to enable or disable probes.
73+
*/
74+
static class ProbesCondition extends SpringBootCondition {
75+
76+
private static final String ENABLED_PROPERTY = "management.health.probes.enabled";
77+
78+
@Override
79+
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
80+
Environment environment = context.getEnvironment();
81+
ConditionMessage.Builder message = ConditionMessage.forCondition("Health availability");
82+
String enabled = environment.getProperty(ENABLED_PROPERTY);
83+
if (enabled != null) {
84+
boolean match = !"false".equalsIgnoreCase(enabled);
85+
return new ConditionOutcome(match,
86+
message.because("'" + ENABLED_PROPERTY + "' set to '" + enabled + "'"));
87+
}
88+
if (CloudPlatform.getActive(environment) == CloudPlatform.KUBERNETES) {
89+
return ConditionOutcome.match(message.because("running on Kubernetes"));
90+
}
91+
return ConditionOutcome.noMatch(message.because("not running on a supported cloud platform"));
92+
}
93+
94+
}
95+
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright 2012-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.availability;
18+
19+
import java.util.Arrays;
20+
import java.util.HashSet;
21+
import java.util.Set;
22+
23+
import org.springframework.boot.actuate.endpoint.SecurityContext;
24+
import org.springframework.boot.actuate.health.HealthEndpointGroup;
25+
import org.springframework.boot.actuate.health.HttpCodeStatusMapper;
26+
import org.springframework.boot.actuate.health.StatusAggregator;
27+
28+
/**
29+
* {@link HealthEndpointGroup} used to support availability probes.
30+
*
31+
* @author Phillip Webb
32+
* @author Brian Clozel
33+
*/
34+
class AvailabilityProbesHealthEndpointGroup implements HealthEndpointGroup {
35+
36+
private final Set<String> members;
37+
38+
AvailabilityProbesHealthEndpointGroup(String... members) {
39+
this.members = new HashSet<>(Arrays.asList(members));
40+
}
41+
42+
@Override
43+
public boolean isMember(String name) {
44+
return this.members.contains(name);
45+
}
46+
47+
@Override
48+
public boolean showComponents(SecurityContext securityContext) {
49+
return false;
50+
}
51+
52+
@Override
53+
public boolean showDetails(SecurityContext securityContext) {
54+
return false;
55+
}
56+
57+
@Override
58+
public StatusAggregator getStatusAggregator() {
59+
return StatusAggregator.DEFAULT;
60+
}
61+
62+
@Override
63+
public HttpCodeStatusMapper getHttpCodeStatusMapper() {
64+
return HttpCodeStatusMapper.DEFAULT;
65+
}
66+
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright 2012-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.availability;
18+
19+
import java.util.Collections;
20+
import java.util.LinkedHashMap;
21+
import java.util.LinkedHashSet;
22+
import java.util.Map;
23+
import java.util.Set;
24+
25+
import org.springframework.boot.actuate.health.HealthEndpointGroup;
26+
import org.springframework.boot.actuate.health.HealthEndpointGroups;
27+
import org.springframework.util.Assert;
28+
29+
/**
30+
* {@link HealthEndpointGroups} decorator to support availability probes.
31+
*
32+
* @author Phillip Webb
33+
* @author Brian Clozel
34+
*/
35+
class AvailabilityProbesHealthEndpointGroups implements HealthEndpointGroups {
36+
37+
private static final Map<String, AvailabilityProbesHealthEndpointGroup> GROUPS;
38+
static {
39+
Map<String, AvailabilityProbesHealthEndpointGroup> groups = new LinkedHashMap<>();
40+
groups.put("liveness", new AvailabilityProbesHealthEndpointGroup("livenessState"));
41+
groups.put("readiness", new AvailabilityProbesHealthEndpointGroup("readinessState"));
42+
GROUPS = Collections.unmodifiableMap(groups);
43+
}
44+
45+
private final HealthEndpointGroups groups;
46+
47+
private final Set<String> names;
48+
49+
AvailabilityProbesHealthEndpointGroups(HealthEndpointGroups groups) {
50+
Assert.notNull(groups, "Groups must not be null");
51+
this.groups = groups;
52+
Set<String> names = new LinkedHashSet<>(groups.getNames());
53+
names.addAll(GROUPS.keySet());
54+
this.names = Collections.unmodifiableSet(names);
55+
}
56+
57+
@Override
58+
public HealthEndpointGroup getPrimary() {
59+
return this.groups.getPrimary();
60+
}
61+
62+
@Override
63+
public Set<String> getNames() {
64+
return this.names;
65+
}
66+
67+
@Override
68+
public HealthEndpointGroup get(String name) {
69+
HealthEndpointGroup group = this.groups.get(name);
70+
if (group == null) {
71+
group = GROUPS.get(name);
72+
}
73+
return group;
74+
}
75+
76+
static boolean containsAllProbeGroups(HealthEndpointGroups groups) {
77+
return groups.getNames().containsAll(GROUPS.keySet());
78+
}
79+
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2012-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.availability;
18+
19+
import org.springframework.boot.actuate.health.HealthEndpointGroups;
20+
import org.springframework.boot.actuate.health.HealthEndpointGroupsPostProcessor;
21+
import org.springframework.core.Ordered;
22+
import org.springframework.core.annotation.Order;
23+
24+
/**
25+
* {@link HealthEndpointGroupsPostProcessor} to add
26+
* {@link AvailabilityProbesHealthEndpointGroups}.
27+
*
28+
* @author Phillip Webb
29+
*/
30+
@Order(Ordered.LOWEST_PRECEDENCE)
31+
class AvailabilityProbesHealthEndpointGroupsPostProcessor implements HealthEndpointGroupsPostProcessor {
32+
33+
@Override
34+
public HealthEndpointGroups postProcessHealthEndpointGroups(HealthEndpointGroups groups) {
35+
if (AvailabilityProbesHealthEndpointGroups.containsAllProbeGroups(groups)) {
36+
return groups;
37+
}
38+
return new AvailabilityProbesHealthEndpointGroups(groups);
39+
}
40+
41+
}
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
/**
18-
* Auto-configuration for actuator kubernetes concerns.
18+
* Auto-configuration that extends health endpoints so that they can be used as
19+
* availability probes.
1920
*/
20-
package org.springframework.boot.actuate.autoconfigure.kubernetes;
21+
package org.springframework.boot.actuate.autoconfigure.availability;
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Collection;
2121
import java.util.function.Predicate;
2222

23+
import org.springframework.boot.actuate.autoconfigure.health.HealthProperties.Show;
2324
import org.springframework.boot.actuate.endpoint.SecurityContext;
2425
import org.springframework.boot.actuate.health.HealthEndpointGroup;
2526
import org.springframework.boot.actuate.health.HttpCodeStatusMapper;
@@ -30,12 +31,12 @@
3031
import org.springframework.util.CollectionUtils;
3132

3233
/**
33-
* Auto-configured {@link HealthEndpointGroup}.
34+
* Auto-configured {@link HealthEndpointGroup} backed by {@link HealthProperties}.
3435
*
3536
* @author Phillip Webb
3637
* @author Andy Wilkinson
3738
*/
38-
class DefaultHealthEndpointGroup implements HealthEndpointGroup {
39+
class AutoConfiguredHealthEndpointGroup implements HealthEndpointGroup {
3940

4041
private final Predicate<String> members;
4142

@@ -50,15 +51,15 @@ class DefaultHealthEndpointGroup implements HealthEndpointGroup {
5051
private final Collection<String> roles;
5152

5253
/**
53-
* Create a new {@link DefaultHealthEndpointGroup} instance.
54+
* Create a new {@link AutoConfiguredHealthEndpointGroup} instance.
5455
* @param members a predicate used to test for group membership
5556
* @param statusAggregator the status aggregator to use
5657
* @param httpCodeStatusMapper the HTTP code status mapper to use
5758
* @param showComponents the show components setting
5859
* @param showDetails the show details setting
5960
* @param roles the roles to match
6061
*/
61-
DefaultHealthEndpointGroup(Predicate<String> members, StatusAggregator statusAggregator,
62+
AutoConfiguredHealthEndpointGroup(Predicate<String> members, StatusAggregator statusAggregator,
6263
HttpCodeStatusMapper httpCodeStatusMapper, Show showComponents, Show showDetails,
6364
Collection<String> roles) {
6465
this.members = members;

0 commit comments

Comments
 (0)