commit
24ee9737c0
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.availability;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.availability.AvailabilityProbesAutoConfiguration.ProbesCondition;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.availability.LivenessStateHealthIndicator;
|
||||
import org.springframework.boot.actuate.availability.ReadinessStateHealthIndicator;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
||||
import org.springframework.boot.availability.ApplicationAvailability;
|
||||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for availability probes.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Phillip Webb
|
||||
* @since 2.3.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Conditional(ProbesCondition.class)
|
||||
@AutoConfigureAfter(ApplicationAvailabilityAutoConfiguration.class)
|
||||
public class AvailabilityProbesAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnEnabledHealthIndicator("livenessState")
|
||||
@ConditionalOnMissingBean
|
||||
public LivenessStateHealthIndicator livenessStateHealthIndicator(ApplicationAvailability applicationAvailability) {
|
||||
return new LivenessStateHealthIndicator(applicationAvailability);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnEnabledHealthIndicator("readinessState")
|
||||
@ConditionalOnMissingBean
|
||||
public ReadinessStateHealthIndicator readinessStateHealthIndicator(
|
||||
ApplicationAvailability applicationAvailability) {
|
||||
return new ReadinessStateHealthIndicator(applicationAvailability);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AvailabilityProbesHealthEndpointGroupsPostProcessor availabilityProbesHealthEndpointGroupsPostProcessor() {
|
||||
return new AvailabilityProbesHealthEndpointGroupsPostProcessor();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link SpringBootCondition} to enable or disable probes.
|
||||
*/
|
||||
static class ProbesCondition extends SpringBootCondition {
|
||||
|
||||
private static final String ENABLED_PROPERTY = "management.health.probes.enabled";
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
Environment environment = context.getEnvironment();
|
||||
ConditionMessage.Builder message = ConditionMessage.forCondition("Health availability");
|
||||
String enabled = environment.getProperty(ENABLED_PROPERTY);
|
||||
if (enabled != null) {
|
||||
boolean match = !"false".equalsIgnoreCase(enabled);
|
||||
return new ConditionOutcome(match,
|
||||
message.because("'" + ENABLED_PROPERTY + "' set to '" + enabled + "'"));
|
||||
}
|
||||
if (CloudPlatform.getActive(environment) == CloudPlatform.KUBERNETES) {
|
||||
return ConditionOutcome.match(message.because("running on Kubernetes"));
|
||||
}
|
||||
return ConditionOutcome.noMatch(message.because("not running on a supported cloud platform"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.availability;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.SecurityContext;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroup;
|
||||
import org.springframework.boot.actuate.health.HttpCodeStatusMapper;
|
||||
import org.springframework.boot.actuate.health.StatusAggregator;
|
||||
|
||||
/**
|
||||
* {@link HealthEndpointGroup} used to support availability probes.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class AvailabilityProbesHealthEndpointGroup implements HealthEndpointGroup {
|
||||
|
||||
private final Set<String> members;
|
||||
|
||||
AvailabilityProbesHealthEndpointGroup(String... members) {
|
||||
this.members = new HashSet<>(Arrays.asList(members));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMember(String name) {
|
||||
return this.members.contains(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showComponents(SecurityContext securityContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showDetails(SecurityContext securityContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatusAggregator getStatusAggregator() {
|
||||
return StatusAggregator.DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpCodeStatusMapper getHttpCodeStatusMapper() {
|
||||
return HttpCodeStatusMapper.DEFAULT;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.availability;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroup;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroups;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link HealthEndpointGroups} decorator to support availability probes.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class AvailabilityProbesHealthEndpointGroups implements HealthEndpointGroups {
|
||||
|
||||
private static final Map<String, AvailabilityProbesHealthEndpointGroup> GROUPS;
|
||||
static {
|
||||
Map<String, AvailabilityProbesHealthEndpointGroup> groups = new LinkedHashMap<>();
|
||||
groups.put("liveness", new AvailabilityProbesHealthEndpointGroup("livenessState"));
|
||||
groups.put("readiness", new AvailabilityProbesHealthEndpointGroup("readinessState"));
|
||||
GROUPS = Collections.unmodifiableMap(groups);
|
||||
}
|
||||
|
||||
private final HealthEndpointGroups groups;
|
||||
|
||||
private final Set<String> names;
|
||||
|
||||
AvailabilityProbesHealthEndpointGroups(HealthEndpointGroups groups) {
|
||||
Assert.notNull(groups, "Groups must not be null");
|
||||
this.groups = groups;
|
||||
Set<String> names = new LinkedHashSet<>(groups.getNames());
|
||||
names.addAll(GROUPS.keySet());
|
||||
this.names = Collections.unmodifiableSet(names);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroup getPrimary() {
|
||||
return this.groups.getPrimary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getNames() {
|
||||
return this.names;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroup get(String name) {
|
||||
HealthEndpointGroup group = this.groups.get(name);
|
||||
if (group == null) {
|
||||
group = GROUPS.get(name);
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
static boolean containsAllProbeGroups(HealthEndpointGroups groups) {
|
||||
return groups.getNames().containsAll(GROUPS.keySet());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.availability;
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroups;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroupsPostProcessor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
/**
|
||||
* {@link HealthEndpointGroupsPostProcessor} to add
|
||||
* {@link AvailabilityProbesHealthEndpointGroups}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Order(Ordered.LOWEST_PRECEDENCE)
|
||||
class AvailabilityProbesHealthEndpointGroupsPostProcessor implements HealthEndpointGroupsPostProcessor {
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroups postProcessHealthEndpointGroups(HealthEndpointGroups groups) {
|
||||
if (AvailabilityProbesHealthEndpointGroups.containsAllProbeGroups(groups)) {
|
||||
return groups;
|
||||
}
|
||||
return new AvailabilityProbesHealthEndpointGroups(groups);
|
||||
}
|
||||
|
||||
}
|
9
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/DefaultHealthEndpointGroup.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroup.java
9
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/DefaultHealthEndpointGroup.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroup.java
138
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroupsRegistry.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroups.java
138
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroupsRegistry.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroups.java
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.health;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroup;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroup.Show;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroupConfigurer;
|
||||
import org.springframework.boot.actuate.health.HttpCodeStatusMapper;
|
||||
import org.springframework.boot.actuate.health.StatusAggregator;
|
||||
|
||||
/**
|
||||
* Mutable {@link HealthEndpointGroupConfigurer configurer} for
|
||||
* {@link HealthEndpointGroup}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class DefaultHealthEndpointGroupConfigurer implements HealthEndpointGroupConfigurer {
|
||||
|
||||
Set<String> includedIndicators;
|
||||
|
||||
Set<String> excludedIndicators;
|
||||
|
||||
private StatusAggregator statusAggregator;
|
||||
|
||||
private HttpCodeStatusMapper httpCodeStatusMapper;
|
||||
|
||||
private Show showComponents;
|
||||
|
||||
private Show showDetails;
|
||||
|
||||
private Set<String> roles;
|
||||
|
||||
DefaultHealthEndpointGroupConfigurer(StatusAggregator defaultStatusAggregator,
|
||||
HttpCodeStatusMapper defaultHttpCodeStatusMapper, Show defaultShowComponents, Show defaultShowDetails,
|
||||
Set<String> defaultRoles) {
|
||||
this.statusAggregator = defaultStatusAggregator;
|
||||
this.httpCodeStatusMapper = defaultHttpCodeStatusMapper;
|
||||
this.showComponents = defaultShowComponents;
|
||||
this.showDetails = defaultShowDetails;
|
||||
this.roles = new HashSet<>(defaultRoles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer include(String... indicators) {
|
||||
this.includedIndicators = new HashSet<>(Arrays.asList(indicators));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer exclude(String... exclude) {
|
||||
this.excludedIndicators = new HashSet<>(Arrays.asList(exclude));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer statusAggregator(StatusAggregator statusAggregator) {
|
||||
this.statusAggregator = statusAggregator;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer httpCodeStatusMapper(HttpCodeStatusMapper httpCodeStatusMapper) {
|
||||
this.httpCodeStatusMapper = httpCodeStatusMapper;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer showComponents(Show showComponents) {
|
||||
this.showComponents = showComponents;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer showDetails(Show showDetails) {
|
||||
this.showDetails = showDetails;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer roles(String... roles) {
|
||||
this.roles = new HashSet<>(Arrays.asList(roles));
|
||||
return this;
|
||||
}
|
||||
|
||||
HealthEndpointGroup toHealthEndpointGroup() {
|
||||
IncludeExcludeGroupMemberPredicate predicate = new IncludeExcludeGroupMemberPredicate(this.includedIndicators,
|
||||
this.excludedIndicators);
|
||||
return new DefaultHealthEndpointGroup(predicate, this.statusAggregator, this.httpCodeStatusMapper,
|
||||
this.showComponents, this.showDetails, this.roles);
|
||||
}
|
||||
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.kubernetes;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.autoconfigure.kubernetes.ProbesHealthContributorAutoConfiguration.KubernetesOrPropertyCondition;
|
||||
import org.springframework.boot.actuate.availability.LivenessProbeHealthIndicator;
|
||||
import org.springframework.boot.actuate.availability.ReadinessProbeHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroupsRegistryCustomizer;
|
||||
import org.springframework.boot.actuate.kubernetes.ProbesHealthEndpointGroupsRegistrar;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.availability.ApplicationAvailabilityProvider;
|
||||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for
|
||||
* {@link LivenessProbeHealthIndicator} and {@link ReadinessProbeHealthIndicator}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.3.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Conditional(KubernetesOrPropertyCondition.class)
|
||||
@AutoConfigureAfter(ApplicationAvailabilityAutoConfiguration.class)
|
||||
public class ProbesHealthContributorAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnEnabledHealthIndicator("livenessProbe")
|
||||
@ConditionalOnMissingBean
|
||||
public LivenessProbeHealthIndicator livenessProbeHealthIndicator(
|
||||
ApplicationAvailabilityProvider applicationAvailabilityProvider) {
|
||||
return new LivenessProbeHealthIndicator(applicationAvailabilityProvider);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnEnabledHealthIndicator("readinessProbe")
|
||||
@ConditionalOnMissingBean
|
||||
public ReadinessProbeHealthIndicator readinessProbeHealthIndicator(
|
||||
ApplicationAvailabilityProvider applicationAvailabilityProvider) {
|
||||
return new ReadinessProbeHealthIndicator(applicationAvailabilityProvider);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HealthEndpointGroupsRegistryCustomizer probesRegistryCustomizer() {
|
||||
return new ProbesHealthEndpointGroupsRegistrar();
|
||||
}
|
||||
|
||||
static class KubernetesOrPropertyCondition extends AnyNestedCondition {
|
||||
|
||||
KubernetesOrPropertyCondition() {
|
||||
super(ConfigurationPhase.PARSE_CONFIGURATION);
|
||||
}
|
||||
|
||||
@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)
|
||||
static class Kubernetes {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(prefix = "management.health.probes", name = "enabled")
|
||||
static class ProbesIndicatorsEnabled {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.availability;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.availability.LivenessStateHealthIndicator;
|
||||
import org.springframework.boot.actuate.availability.ReadinessStateHealthIndicator;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration;
|
||||
import org.springframework.boot.availability.ApplicationAvailability;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link AvailabilityProbesAutoConfiguration}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class AvailabilityProbesAutoConfigurationTests {
|
||||
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(AutoConfigurations
|
||||
.of(ApplicationAvailabilityAutoConfiguration.class, AvailabilityProbesAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void probesWhenNotKubernetesAddsNoBeans() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
|
||||
.doesNotHaveBean(LivenessStateHealthIndicator.class)
|
||||
.doesNotHaveBean(ReadinessStateHealthIndicator.class)
|
||||
.doesNotHaveBean(AvailabilityProbesHealthEndpointGroupsPostProcessor.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void probesWhenKubernetesAddsBeans() {
|
||||
this.contextRunner.withPropertyValues("spring.main.cloud-platform=kubernetes")
|
||||
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
|
||||
.hasSingleBean(LivenessStateHealthIndicator.class)
|
||||
.hasSingleBean(ReadinessStateHealthIndicator.class)
|
||||
.hasSingleBean(AvailabilityProbesHealthEndpointGroupsPostProcessor.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void probesWhenPropertyEnabledAddsBeans() {
|
||||
this.contextRunner.withPropertyValues("management.health.probes.enabled=true")
|
||||
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
|
||||
.hasSingleBean(LivenessStateHealthIndicator.class)
|
||||
.hasSingleBean(ReadinessStateHealthIndicator.class)
|
||||
.hasSingleBean(AvailabilityProbesHealthEndpointGroupsPostProcessor.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void probesWhenKuberntesAndPropertyDisabledAddsNotBeans() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.main.cloud-platform=kubernetes", "management.health.probes.enabled=false")
|
||||
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
|
||||
.doesNotHaveBean(LivenessStateHealthIndicator.class)
|
||||
.doesNotHaveBean(ReadinessStateHealthIndicator.class)
|
||||
.doesNotHaveBean(AvailabilityProbesHealthEndpointGroupsPostProcessor.class));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.availability;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.SecurityContext;
|
||||
import org.springframework.boot.actuate.health.HttpCodeStatusMapper;
|
||||
import org.springframework.boot.actuate.health.StatusAggregator;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link AvailabilityProbesHealthEndpointGroup}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class AvailabilityProbesHealthEndpointGroupTests {
|
||||
|
||||
private AvailabilityProbesHealthEndpointGroup group = new AvailabilityProbesHealthEndpointGroup("a", "b");
|
||||
|
||||
@Test
|
||||
void isMemberWhenMemberReturnsTrue() {
|
||||
assertThat(this.group.isMember("a")).isTrue();
|
||||
assertThat(this.group.isMember("b")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isMemberWhenNotMemberReturnsFalse() {
|
||||
assertThat(this.group.isMember("c")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void showComponentsReturnsFalse() {
|
||||
assertThat(this.group.showComponents(mock(SecurityContext.class))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void showDetailsReturnsFalse() {
|
||||
assertThat(this.group.showDetails(mock(SecurityContext.class))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getStatusAggregattorReturnsDefaultStatusAggregator() {
|
||||
assertThat(this.group.getStatusAggregator()).isEqualTo(StatusAggregator.DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getHttpCodeStatusMapperReturnsDefaultHttpCodeStatusMapper() {
|
||||
assertThat(this.group.getHttpCodeStatusMapper()).isEqualTo(HttpCodeStatusMapper.DEFAULT);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.availability;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroups;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link AvailabilityProbesHealthEndpointGroupsPostProcessor}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class AvailabilityProbesHealthEndpointGroupsPostProcessorTests {
|
||||
|
||||
private AvailabilityProbesHealthEndpointGroupsPostProcessor postProcessor = new AvailabilityProbesHealthEndpointGroupsPostProcessor();
|
||||
|
||||
@Test
|
||||
void postProcessHealthEndpointGroupsWhenGroupsAlreadyContainedReturnsOriginal() {
|
||||
HealthEndpointGroups groups = mock(HealthEndpointGroups.class);
|
||||
Set<String> names = new LinkedHashSet<>();
|
||||
names.add("test");
|
||||
names.add("readiness");
|
||||
names.add("liveness");
|
||||
given(groups.getNames()).willReturn(names);
|
||||
assertThat(this.postProcessor.postProcessHealthEndpointGroups(groups)).isSameAs(groups);
|
||||
}
|
||||
|
||||
@Test
|
||||
void postProcessHealthEndpointGroupsWhenGroupContainsOneReturnsPostProcessed() {
|
||||
HealthEndpointGroups groups = mock(HealthEndpointGroups.class);
|
||||
Set<String> names = new LinkedHashSet<>();
|
||||
names.add("test");
|
||||
names.add("readiness");
|
||||
given(groups.getNames()).willReturn(names);
|
||||
assertThat(this.postProcessor.postProcessHealthEndpointGroups(groups))
|
||||
.isInstanceOf(AvailabilityProbesHealthEndpointGroups.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void postProcessHealthEndpointGroupsWhenGroupsContainsNoneReturnsProcessed() {
|
||||
HealthEndpointGroups groups = mock(HealthEndpointGroups.class);
|
||||
Set<String> names = new LinkedHashSet<>();
|
||||
names.add("test");
|
||||
names.add("spring");
|
||||
names.add("boot");
|
||||
given(groups.getNames()).willReturn(names);
|
||||
assertThat(this.postProcessor.postProcessHealthEndpointGroups(groups))
|
||||
.isInstanceOf(AvailabilityProbesHealthEndpointGroups.class);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.availability;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroup;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroups;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link AvailabilityProbesHealthEndpointGroups}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class AvailabilityProbesHealthEndpointGroupsTests {
|
||||
|
||||
private HealthEndpointGroups delegate;
|
||||
|
||||
private HealthEndpointGroup group;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.delegate = mock(HealthEndpointGroups.class);
|
||||
this.group = mock(HealthEndpointGroup.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenGroupsIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new AvailabilityProbesHealthEndpointGroups(null))
|
||||
.withMessage("Groups must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPrimaryDelegatesToGroups() {
|
||||
given(this.delegate.getPrimary()).willReturn(this.group);
|
||||
HealthEndpointGroups availabilityProbes = new AvailabilityProbesHealthEndpointGroups(this.delegate);
|
||||
assertThat(availabilityProbes.getPrimary()).isEqualTo(this.group);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getNamesIncludesAvailabilityProbeGroups() {
|
||||
given(this.delegate.getNames()).willReturn(Collections.singleton("test"));
|
||||
HealthEndpointGroups availabilityProbes = new AvailabilityProbesHealthEndpointGroups(this.delegate);
|
||||
assertThat(availabilityProbes.getNames()).containsExactly("test", "liveness", "readiness");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenProbeInDelegateReturnsGroupFromDelegate() {
|
||||
given(this.delegate.get("liveness")).willReturn(this.group);
|
||||
HealthEndpointGroups availabilityProbes = new AvailabilityProbesHealthEndpointGroups(this.delegate);
|
||||
assertThat(availabilityProbes.get("liveness")).isEqualTo(this.group);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenProbeNotInDelegateReturnsProbeGroup() {
|
||||
HealthEndpointGroups availabilityProbes = new AvailabilityProbesHealthEndpointGroups(this.delegate);
|
||||
assertThat(availabilityProbes.get("liveness")).isInstanceOf(AvailabilityProbesHealthEndpointGroup.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenNotProbeAndNotInDelegateReturnsNull() {
|
||||
HealthEndpointGroups availabilityProbes = new AvailabilityProbesHealthEndpointGroups(this.delegate);
|
||||
assertThat(availabilityProbes.get("mygroup")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getLivenessProbeHasOnlyLivenessStateAsMember() {
|
||||
HealthEndpointGroups availabilityProbes = new AvailabilityProbesHealthEndpointGroups(this.delegate);
|
||||
HealthEndpointGroup probeGroup = availabilityProbes.get("liveness");
|
||||
assertThat(probeGroup.isMember("livenessState")).isTrue();
|
||||
assertThat(probeGroup.isMember("readinessState")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getRedinessProbeHasOnlyReadinessStateAsMember() {
|
||||
HealthEndpointGroups availabilityProbes = new AvailabilityProbesHealthEndpointGroups(this.delegate);
|
||||
HealthEndpointGroup probeGroup = availabilityProbes.get("readiness");
|
||||
assertThat(probeGroup.isMember("livenessState")).isFalse();
|
||||
assertThat(probeGroup.isMember("readinessState")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsAllWhenContainsAllReturnTrue() {
|
||||
given(this.delegate.getNames()).willReturn(new LinkedHashSet<>(Arrays.asList("test", "liveness", "readiness")));
|
||||
assertThat(AvailabilityProbesHealthEndpointGroups.containsAllProbeGroups(this.delegate)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsAllWhenContainsOneReturnFalse() {
|
||||
given(this.delegate.getNames()).willReturn(new LinkedHashSet<>(Arrays.asList("test", "liveness")));
|
||||
assertThat(AvailabilityProbesHealthEndpointGroups.containsAllProbeGroups(this.delegate)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsAllWhenContainsNoneReturnFalse() {
|
||||
given(this.delegate.getNames()).willReturn(new LinkedHashSet<>(Arrays.asList("test", "spring")));
|
||||
assertThat(AvailabilityProbesHealthEndpointGroups.containsAllProbeGroups(this.delegate)).isFalse();
|
||||
}
|
||||
|
||||
}
|
98
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/DefaultHealthEndpointGroupTests.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroupTests.java
98
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/DefaultHealthEndpointGroupTests.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroupTests.java
10
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroupsBuilderTests.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroupsTests.java
10
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroupsBuilderTests.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroupsTests.java
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.kubernetes;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.availability.LivenessProbeHealthIndicator;
|
||||
import org.springframework.boot.actuate.availability.ReadinessProbeHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroupsRegistryCustomizer;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration;
|
||||
import org.springframework.boot.availability.ApplicationAvailabilityProvider;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests fos {@link ProbesHealthContributorAutoConfiguration}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class ProbesHealthContributorAutoConfigurationTests {
|
||||
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(AutoConfigurations
|
||||
.of(ApplicationAvailabilityAutoConfiguration.class, ProbesHealthContributorAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void probesNotConfiguredIfNotKubernetes() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailabilityProvider.class)
|
||||
.doesNotHaveBean(LivenessProbeHealthIndicator.class)
|
||||
.doesNotHaveBean(ReadinessProbeHealthIndicator.class)
|
||||
.doesNotHaveBean(HealthEndpointGroupsRegistryCustomizer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void probesConfiguredIfProperty() {
|
||||
this.contextRunner.withPropertyValues("management.health.probes.enabled=true")
|
||||
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailabilityProvider.class)
|
||||
.hasSingleBean(LivenessProbeHealthIndicator.class)
|
||||
.hasSingleBean(ReadinessProbeHealthIndicator.class)
|
||||
.hasSingleBean(HealthEndpointGroupsRegistryCustomizer.class));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.availability;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Health.Builder;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.boot.availability.ApplicationAvailability;
|
||||
import org.springframework.boot.availability.AvailabilityState;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A {@link HealthIndicator} that checks a specific {@link AvailabilityState} of the
|
||||
* application.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Brian Clozel
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class AvailabilityStateHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
private final ApplicationAvailability applicationAvailability;
|
||||
|
||||
private Class<? extends AvailabilityState> stateType;
|
||||
|
||||
private final Map<AvailabilityState, Status> statusMappings = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Create a new {@link AvailabilityStateHealthIndicator} instance.
|
||||
* @param <S> the availability state type
|
||||
* @param applicationAvailability the application availability
|
||||
* @param stateType the availability state type
|
||||
* @param statusMappings consumer used to setup the status mappings
|
||||
*/
|
||||
public <S extends AvailabilityState> AvailabilityStateHealthIndicator(
|
||||
ApplicationAvailability applicationAvailability, Class<S> stateType,
|
||||
Consumer<StatusMappings<S>> statusMappings) {
|
||||
Assert.notNull(applicationAvailability, "ApplicationAvailability must not be null");
|
||||
Assert.notNull(stateType, "StateType must not be null");
|
||||
Assert.notNull(statusMappings, "StatusMappings must not be null");
|
||||
this.applicationAvailability = applicationAvailability;
|
||||
this.stateType = stateType;
|
||||
statusMappings.accept(this.statusMappings::put);
|
||||
assertAllEnumsMapped(stateType);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private <S extends AvailabilityState> void assertAllEnumsMapped(Class<S> stateType) {
|
||||
if (!this.statusMappings.containsKey(null) && Enum.class.isAssignableFrom(stateType)) {
|
||||
EnumSet elements = EnumSet.allOf((Class) stateType);
|
||||
for (Object element : elements) {
|
||||
Assert.isTrue(this.statusMappings.containsKey(element), "StatusMappings does not include " + element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Builder builder) throws Exception {
|
||||
AvailabilityState state = getState(this.applicationAvailability);
|
||||
Status status = this.statusMappings.get(state);
|
||||
if (status == null) {
|
||||
status = this.statusMappings.get(null);
|
||||
}
|
||||
Assert.state(status != null, "No mapping provided for " + state);
|
||||
builder.status(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current availability state. Subclasses can override this method if a
|
||||
* different retrieval mechanism is needed.
|
||||
* @param applicationAvailability the application availability
|
||||
* @return the current availability state
|
||||
*/
|
||||
protected AvailabilityState getState(ApplicationAvailability applicationAvailability) {
|
||||
return applicationAvailability.getState(this.stateType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used to add status mappings.
|
||||
*
|
||||
* @param <S> the availability state type
|
||||
*/
|
||||
public interface StatusMappings<S extends AvailabilityState> {
|
||||
|
||||
/**
|
||||
* Add the status that should be used if no explicit mapping is defined.
|
||||
* @param status the default status
|
||||
*/
|
||||
default void addDefaultStatus(Status status) {
|
||||
add(null, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new status mapping .
|
||||
* @param availabilityState the availability state
|
||||
* @param status the mapped status
|
||||
*/
|
||||
void add(S availabilityState, Status status);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.health;
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroup.Show;
|
||||
|
||||
/**
|
||||
* A configurer for customizing an {@link HealthEndpointGroup} being built.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public interface HealthEndpointGroupConfigurer {
|
||||
|
||||
/**
|
||||
* Configure the indicator endpoint ids to include in this group.
|
||||
* @param indicators the indicator endpoint ids
|
||||
* @return the configurer instance
|
||||
*/
|
||||
HealthEndpointGroupConfigurer include(String... indicators);
|
||||
|
||||
/**
|
||||
* Configure the indicator endpoint ids to exclude from this group.
|
||||
* @param indicators the indicator endpoint ids
|
||||
* @return the configurer instance
|
||||
*/
|
||||
HealthEndpointGroupConfigurer exclude(String... indicators);
|
||||
|
||||
/**
|
||||
* Configure the {@link StatusAggregator} to use for this group.
|
||||
* <p>
|
||||
* If none set, this will default to the globally configured {@link StatusAggregator}.
|
||||
* @param statusAggregator the status aggregator
|
||||
* @return the configurer instance
|
||||
*/
|
||||
HealthEndpointGroupConfigurer statusAggregator(StatusAggregator statusAggregator);
|
||||
|
||||
/**
|
||||
* Configure the {@link HttpCodeStatusMapper} to use for this group.
|
||||
* <p>
|
||||
* If none set, this will default to the globally configured
|
||||
* {@link HttpCodeStatusMapper}.
|
||||
* @param httpCodeStatusMapper the status code mapper
|
||||
* @return the configurer instance
|
||||
*/
|
||||
HealthEndpointGroupConfigurer httpCodeStatusMapper(HttpCodeStatusMapper httpCodeStatusMapper);
|
||||
|
||||
/**
|
||||
* Configure the {@link Show visibility option} for showing components of this group.
|
||||
* @param showComponents the components visibility
|
||||
* @return the configurer instance
|
||||
*/
|
||||
HealthEndpointGroupConfigurer showComponents(Show showComponents);
|
||||
|
||||
/**
|
||||
* Configure the {@link Show visibility option} for showing details of this group.
|
||||
* @param showDetails the details visibility
|
||||
* @return the configurer instance
|
||||
*/
|
||||
HealthEndpointGroupConfigurer showDetails(Show showDetails);
|
||||
|
||||
/**
|
||||
* Configure roles used to determine whether or not a user is authorized to be shown
|
||||
* details.
|
||||
* @param roles the roles
|
||||
* @return the configurer instance
|
||||
*/
|
||||
HealthEndpointGroupConfigurer roles(String... roles);
|
||||
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.health;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Builder for an {@link HealthEndpointGroups} immutable instance.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public interface HealthEndpointGroupsRegistry extends HealthEndpointGroups {
|
||||
|
||||
/**
|
||||
* Add a new {@link HealthEndpointGroup}.
|
||||
* @param groupName the name of the group to add
|
||||
* @param builder the group to add
|
||||
* @return the builder instance
|
||||
*/
|
||||
HealthEndpointGroupsRegistry add(String groupName, Consumer<HealthEndpointGroupConfigurer> builder);
|
||||
|
||||
/**
|
||||
* Remove an existing {@link HealthEndpointGroup}.
|
||||
* @param groupName the name of the group to remove
|
||||
* @return the builder instance
|
||||
*/
|
||||
HealthEndpointGroupsRegistry remove(String groupName);
|
||||
|
||||
/**
|
||||
* Build an immutable {@link HealthEndpointGroups}.
|
||||
* @return the {@link HealthEndpointGroups}
|
||||
*/
|
||||
HealthEndpointGroups toGroups();
|
||||
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.kubernetes;
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroup;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroupsRegistry;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroupsRegistryCustomizer;
|
||||
|
||||
/**
|
||||
* {@link HealthEndpointGroupsRegistryCustomizer} that registers {@code "liveness"} and
|
||||
* {@code "readiness"} {@link HealthEndpointGroup groups} if they don't exist already.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class ProbesHealthEndpointGroupsRegistrar implements HealthEndpointGroupsRegistryCustomizer {
|
||||
|
||||
private static final String LIVENESS_GROUP_NAME = "liveness";
|
||||
|
||||
private static final String READINESS_GROUP_NAME = "readiness";
|
||||
|
||||
private static final String LIVENESS_PROBE_INDICATOR = "livenessProbe";
|
||||
|
||||
private static final String READINESS_PROBE_INDICATOR = "readinessProbe";
|
||||
|
||||
@Override
|
||||
public void customize(HealthEndpointGroupsRegistry registry) {
|
||||
if (registry.get(LIVENESS_GROUP_NAME) == null) {
|
||||
registry.add(LIVENESS_GROUP_NAME, (configurer) -> configurer.include(LIVENESS_PROBE_INDICATOR));
|
||||
}
|
||||
if (registry.get(READINESS_GROUP_NAME) == null) {
|
||||
registry.add(READINESS_GROUP_NAME, (configurer) -> configurer.include(READINESS_PROBE_INDICATOR));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.availability;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.boot.availability.ApplicationAvailability;
|
||||
import org.springframework.boot.availability.AvailabilityState;
|
||||
import org.springframework.boot.availability.LivenessState;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* Tests for {@link AvailabilityStateHealthIndicator}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class AvailabilityStateHealthIndicatorTests {
|
||||
|
||||
@Mock
|
||||
private ApplicationAvailability applicationAvailability;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenApplicationAvailabilityIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new AvailabilityStateHealthIndicator(null, LivenessState.class, (statusMappings) -> {
|
||||
})).withMessage("ApplicationAvailability must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenStateTypeIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> new AvailabilityStateHealthIndicator(this.applicationAvailability, null, (statusMappings) -> {
|
||||
})).withMessage("StateType must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenStatusMappingIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> new AvailabilityStateHealthIndicator(this.applicationAvailability, LivenessState.class, null))
|
||||
.withMessage("StatusMappings must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenStatusMappingDoesNotCoverAllEnumsThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new AvailabilityStateHealthIndicator(this.applicationAvailability,
|
||||
LivenessState.class, (statusMappings) -> statusMappings.add(LivenessState.CORRECT, Status.UP)))
|
||||
.withMessage("StatusMappings does not include BROKEN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void healthReturnsMappedStatus() {
|
||||
AvailabilityStateHealthIndicator indicator = new AvailabilityStateHealthIndicator(this.applicationAvailability,
|
||||
LivenessState.class, (statusMappings) -> {
|
||||
statusMappings.add(LivenessState.CORRECT, Status.UP);
|
||||
statusMappings.add(LivenessState.BROKEN, Status.DOWN);
|
||||
});
|
||||
given(this.applicationAvailability.getState(LivenessState.class)).willReturn(LivenessState.BROKEN);
|
||||
assertThat(indicator.getHealth(false).getStatus()).isEqualTo(Status.DOWN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void healthReturnsDefaultStatus() {
|
||||
AvailabilityStateHealthIndicator indicator = new AvailabilityStateHealthIndicator(this.applicationAvailability,
|
||||
LivenessState.class, (statusMappings) -> {
|
||||
statusMappings.add(LivenessState.CORRECT, Status.UP);
|
||||
statusMappings.addDefaultStatus(Status.UNKNOWN);
|
||||
});
|
||||
given(this.applicationAvailability.getState(LivenessState.class)).willReturn(LivenessState.BROKEN);
|
||||
assertThat(indicator.getHealth(false).getStatus()).isEqualTo(Status.UNKNOWN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void healthWhenNotEnumReturnsMappedStatus() {
|
||||
AvailabilityStateHealthIndicator indicator = new AvailabilityStateHealthIndicator(this.applicationAvailability,
|
||||
TestAvailabilityState.class, (statusMappings) -> {
|
||||
statusMappings.add(TestAvailabilityState.ONE, Status.UP);
|
||||
statusMappings.addDefaultStatus(Status.DOWN);
|
||||
});
|
||||
given(this.applicationAvailability.getState(TestAvailabilityState.class)).willReturn(TestAvailabilityState.TWO);
|
||||
assertThat(indicator.getHealth(false).getStatus()).isEqualTo(Status.DOWN);
|
||||
}
|
||||
|
||||
static class TestAvailabilityState implements AvailabilityState {
|
||||
|
||||
static final TestAvailabilityState ONE = new TestAvailabilityState();
|
||||
|
||||
static final TestAvailabilityState TWO = new TestAvailabilityState();
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.health;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Test implementation for {@link HealthEndpointGroupsRegistry}
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
public class TestHealthEndpointGroupsRegistry implements HealthEndpointGroupsRegistry {
|
||||
|
||||
private TestHealthEndpointGroup primary = new TestHealthEndpointGroup();
|
||||
|
||||
private Map<String, TestHealthEndpointGroup> groups = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupsRegistry add(String groupName, Consumer<HealthEndpointGroupConfigurer> builder) {
|
||||
TestHealthEndpointGroupConfigurer configurer = new TestHealthEndpointGroupConfigurer();
|
||||
builder.accept(configurer);
|
||||
this.groups.put(groupName, configurer.toHealthEndpointGroup());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupsRegistry remove(String groupName) {
|
||||
this.groups.remove(groupName);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroups toGroups() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroup getPrimary() {
|
||||
return this.primary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getNames() {
|
||||
return this.groups.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroup get(String name) {
|
||||
return this.groups.get(name);
|
||||
}
|
||||
|
||||
class TestHealthEndpointGroupConfigurer implements HealthEndpointGroupConfigurer {
|
||||
|
||||
private Predicate<String> predicate = (name) -> true;
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer include(String... indicators) {
|
||||
Predicate<String> included = Arrays.asList(indicators).stream()
|
||||
.map((group) -> (Predicate<String>) (s) -> s.equals(group)).reduce(Predicate::or)
|
||||
.orElse((s) -> true);
|
||||
this.predicate = this.predicate.and(included);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer exclude(String... indicators) {
|
||||
Predicate<String> excluded = Arrays.asList(indicators).stream()
|
||||
.map((group) -> (Predicate<String>) (s) -> !s.equals(group)).reduce(Predicate::or)
|
||||
.orElse((s) -> true);
|
||||
this.predicate = this.predicate.and(excluded);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer statusAggregator(StatusAggregator statusAggregator) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer httpCodeStatusMapper(HttpCodeStatusMapper httpCodeStatusMapper) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer showComponents(HealthEndpointGroup.Show showComponents) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer showDetails(HealthEndpointGroup.Show showDetails) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthEndpointGroupConfigurer roles(String... roles) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
TestHealthEndpointGroup toHealthEndpointGroup() {
|
||||
return new TestHealthEndpointGroup(this.predicate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.kubernetes;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroup;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroupsRegistry;
|
||||
import org.springframework.boot.actuate.health.TestHealthEndpointGroupsRegistry;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@code ProbesHealthEndpointGroupsRegistrar }
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class ProbesHealthEndpointGroupsRegistrarTests {
|
||||
|
||||
private ProbesHealthEndpointGroupsRegistrar registrar = new ProbesHealthEndpointGroupsRegistrar();
|
||||
|
||||
@Test
|
||||
void shouldAddKubernetesProbes() {
|
||||
HealthEndpointGroupsRegistry registry = new TestHealthEndpointGroupsRegistry();
|
||||
this.registrar.customize(registry);
|
||||
HealthEndpointGroup liveness = registry.get("liveness");
|
||||
assertThat(liveness).isNotNull();
|
||||
assertThat(liveness.isMember("livenessProbe")).isTrue();
|
||||
HealthEndpointGroup readiness = registry.get("readiness");
|
||||
assertThat(readiness).isNotNull();
|
||||
assertThat(readiness.isMember("readinessProbe")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotAddProbeIfGroupExists() {
|
||||
HealthEndpointGroupsRegistry registry = new TestHealthEndpointGroupsRegistry();
|
||||
registry.add("readiness", (configurer) -> configurer.include("test"));
|
||||
this.registrar.customize(registry);
|
||||
|
||||
HealthEndpointGroup liveness = registry.get("liveness");
|
||||
assertThat(liveness).isNotNull();
|
||||
assertThat(liveness.isMember("livenessProbe")).isTrue();
|
||||
|
||||
HealthEndpointGroup readiness = registry.get("readiness");
|
||||
assertThat(readiness).isNotNull();
|
||||
assertThat(readiness.isMember("readinessProbe")).isFalse();
|
||||
assertThat(readiness.isMember("test")).isTrue();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.availability;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* Provides {@link AvailabilityState availability state} information for the application.
|
||||
* <p>
|
||||
* Components can inject this class to get the current state information. To update the
|
||||
* state of the application an {@link AvailabilityChangeEvent} should be
|
||||
* {@link ApplicationContext#publishEvent published} to the application context with
|
||||
* directly or via {@link AvailabilityChangeEvent#publish}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Phillip Webb
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public interface ApplicationAvailability {
|
||||
|
||||
/**
|
||||
* Return the {@link LivenessState} of the application.
|
||||
* @return the liveness state
|
||||
*/
|
||||
default LivenessState getLivenessState() {
|
||||
return getState(LivenessState.class, LivenessState.BROKEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link ReadinessState} of the application.
|
||||
* @return the readiness state
|
||||
*/
|
||||
default ReadinessState getReadinessState() {
|
||||
return getState(ReadinessState.class, ReadinessState.REFUSING_TRAFFIC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@link AvailabilityState} information for the application.
|
||||
* @param <S> the state type
|
||||
* @param stateType the state type
|
||||
* @param defaultState the default state to return if no event of the given type has
|
||||
* been published yet (must not be {@code null}.
|
||||
* @return the readiness state
|
||||
* @see #getState(Class)
|
||||
*/
|
||||
<S extends AvailabilityState> S getState(Class<S> stateType, S defaultState);
|
||||
|
||||
/**
|
||||
* Return {@link AvailabilityState} information for the application.
|
||||
* @param <S> the state type
|
||||
* @param stateType the state type
|
||||
* @return the readiness state or {@code null} if no event of the given type has been
|
||||
* published yet
|
||||
* @see #getState(Class, AvailabilityState)
|
||||
*/
|
||||
<S extends AvailabilityState> S getState(Class<S> stateType);
|
||||
|
||||
/**
|
||||
* Return the last {@link AvailabilityChangeEvent} received for a given state type.
|
||||
* @param <S> the state type
|
||||
* @param stateType the state type
|
||||
* @return the readiness state or {@code null} if no event of the given type has been
|
||||
* published yet
|
||||
*/
|
||||
<S extends AvailabilityState> AvailabilityChangeEvent<S> getLastChangeEvent(Class<S> stateType);
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.availability;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Bean that provides an {@link ApplicationAvailability} implementation by listening for
|
||||
* {@link AvailabilityChangeEvent change events}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Phillip Webb
|
||||
* @since 2.3.0
|
||||
* @see ApplicationAvailability
|
||||
*/
|
||||
public class ApplicationAvailabilityBean
|
||||
implements ApplicationAvailability, ApplicationListener<AvailabilityChangeEvent<?>> {
|
||||
|
||||
private final Map<Class<? extends AvailabilityState>, AvailabilityChangeEvent<?>> events = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public <S extends AvailabilityState> S getState(Class<S> stateType, S defaultState) {
|
||||
Assert.notNull(stateType, "StateType must not be null");
|
||||
Assert.notNull(defaultState, "DefaultState must not be null");
|
||||
S state = getState(stateType);
|
||||
return (state != null) ? state : defaultState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends AvailabilityState> S getState(Class<S> stateType) {
|
||||
AvailabilityChangeEvent<S> event = getLastChangeEvent(stateType);
|
||||
return (event != null) ? event.getState() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S extends AvailabilityState> AvailabilityChangeEvent<S> getLastChangeEvent(Class<S> stateType) {
|
||||
return (AvailabilityChangeEvent<S>) this.events.get(stateType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(AvailabilityChangeEvent<?> event) {
|
||||
Class<? extends AvailabilityState> stateType = getStateType(event.getState());
|
||||
this.events.put(stateType, event);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Class<? extends AvailabilityState> getStateType(AvailabilityState state) {
|
||||
if (state instanceof Enum) {
|
||||
return (Class<? extends AvailabilityState>) ((Enum<?>) state).getDeclaringClass();
|
||||
}
|
||||
return state.getClass();
|
||||
}
|
||||
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.availability;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Holds the availability state of the application.
|
||||
* <p>
|
||||
* Other application components can get the current state information from the
|
||||
* {@code ApplicationAvailabilityProvider}, or publish application evens such as
|
||||
* {@link ReadinessStateChangedEvent} and {@link LivenessStateChangedEvent} to update the
|
||||
* state of the application.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class ApplicationAvailabilityProvider implements ApplicationListener<ApplicationEvent> {
|
||||
|
||||
private LivenessState livenessState;
|
||||
|
||||
private ReadinessState readinessState;
|
||||
|
||||
/**
|
||||
* Create a new {@link ApplicationAvailabilityProvider} instance with
|
||||
* {@link LivenessState#BROKEN} and {@link ReadinessState#UNREADY}.
|
||||
*/
|
||||
public ApplicationAvailabilityProvider() {
|
||||
this(LivenessState.BROKEN, ReadinessState.UNREADY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link ApplicationAvailabilityProvider} with the given states.
|
||||
* @param livenessState the liveness state
|
||||
* @param readinessState the readiness state
|
||||
*/
|
||||
public ApplicationAvailabilityProvider(LivenessState livenessState, ReadinessState readinessState) {
|
||||
Assert.notNull(livenessState, "LivenessState must not be null");
|
||||
Assert.notNull(readinessState, "ReadinessState must not be null");
|
||||
this.livenessState = livenessState;
|
||||
this.readinessState = readinessState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link LivenessState} of the application.
|
||||
* @return the liveness state
|
||||
*/
|
||||
public LivenessState getLivenessState() {
|
||||
return this.livenessState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link ReadinessState} of the application.
|
||||
* @return the readiness state
|
||||
*/
|
||||
public ReadinessState getReadinessState() {
|
||||
return this.readinessState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (event instanceof LivenessStateChangedEvent) {
|
||||
LivenessStateChangedEvent livenessEvent = (LivenessStateChangedEvent) event;
|
||||
this.livenessState = livenessEvent.getLivenessState();
|
||||
}
|
||||
else if (event instanceof ReadinessStateChangedEvent) {
|
||||
ReadinessStateChangedEvent readinessEvent = (ReadinessStateChangedEvent) event;
|
||||
this.readinessState = readinessEvent.getReadinessState();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.availability;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link ApplicationEvent} sent when the {@link AvailabilityState} of the application
|
||||
* changes.
|
||||
* <p>
|
||||
* Any application component can send such events to update the state of the application.
|
||||
*
|
||||
* @param <S> the availability state type
|
||||
* @author Brian Clozel
|
||||
* @author Phillip Webb
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class AvailabilityChangeEvent<S extends AvailabilityState> extends ApplicationEvent {
|
||||
|
||||
private final S state;
|
||||
|
||||
/**
|
||||
* Create a new {@link AvailabilityChangeEvent} instance.
|
||||
* @param source the source of the event
|
||||
* @param state the availability state (never {@code null})
|
||||
*/
|
||||
public AvailabilityChangeEvent(Object source, S state) {
|
||||
super(source);
|
||||
Assert.notNull(state, "State must not be null");
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the changed availability state.
|
||||
* @return the availability state
|
||||
*/
|
||||
public S getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that can be used to publish an {@link AvailabilityChangeEvent}
|
||||
* to the given application context.
|
||||
* @param <S> the availability state type
|
||||
* @param context the context used to publish the event
|
||||
* @param state the changed availability state
|
||||
*/
|
||||
public static <S extends AvailabilityState> void publish(ApplicationContext context, S state) {
|
||||
Assert.notNull(context, "Context must not be null");
|
||||
publish(context, context, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that can be used to publish an {@link AvailabilityChangeEvent}
|
||||
* to the given application context.
|
||||
* @param <S> the availability state type
|
||||
* @param publisher the publisher used to publish the event
|
||||
* @param source the source of the event
|
||||
* @param state the changed availability state
|
||||
*/
|
||||
public static <S extends AvailabilityState> void publish(ApplicationEventPublisher publisher, Object source,
|
||||
S state) {
|
||||
Assert.notNull(publisher, "Publisher must not be null");
|
||||
publisher.publishEvent(new AvailabilityChangeEvent<>(source, state));
|
||||
}
|
||||
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.availability;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* {@link ApplicationEvent} sent when the {@link LivenessState} of the application
|
||||
* changes.
|
||||
* <p>
|
||||
* Any application component can send such events to update the state of the application.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class LivenessStateChangedEvent extends ApplicationEvent {
|
||||
|
||||
private final String cause;
|
||||
|
||||
LivenessStateChangedEvent(LivenessState state, String cause) {
|
||||
super(state);
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
public LivenessState getLivenessState() {
|
||||
return (LivenessState) getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code ApplicationEvent} signaling that the {@link LivenessState} is
|
||||
* live.
|
||||
* @param cause the cause of the live internal state of the application
|
||||
* @return the application event
|
||||
*/
|
||||
public static LivenessStateChangedEvent live(String cause) {
|
||||
return new LivenessStateChangedEvent(LivenessState.LIVE, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code ApplicationEvent} signaling that the {@link LivenessState} is
|
||||
* broken.
|
||||
* @param cause the cause of the broken internal state of the application
|
||||
* @return the application event
|
||||
*/
|
||||
public static LivenessStateChangedEvent broken(String cause) {
|
||||
return new LivenessStateChangedEvent(LivenessState.BROKEN, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code ApplicationEvent} signaling that the {@link LivenessState} is
|
||||
* broken.
|
||||
* @param throwable the exception that caused the broken internal state of the
|
||||
* application
|
||||
* @return the application event
|
||||
*/
|
||||
public static LivenessStateChangedEvent broken(Throwable throwable) {
|
||||
return new LivenessStateChangedEvent(LivenessState.BROKEN, throwable.getMessage());
|
||||
}
|
||||
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.availability;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* {@link ApplicationEvent} sent when the {@link ReadinessState} of the application
|
||||
* changes.
|
||||
* <p>
|
||||
* Any application component can send such events to update the state of the application.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class ReadinessStateChangedEvent extends ApplicationEvent {
|
||||
|
||||
ReadinessStateChangedEvent(ReadinessState state) {
|
||||
super(state);
|
||||
}
|
||||
|
||||
public ReadinessState getReadinessState() {
|
||||
return (ReadinessState) getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code ApplicationEvent} signaling that the {@link ReadinessState} is
|
||||
* ready.
|
||||
* @return the application event
|
||||
*/
|
||||
public static ReadinessStateChangedEvent ready() {
|
||||
return new ReadinessStateChangedEvent(ReadinessState.READY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code ApplicationEvent} signaling that the {@link ReadinessState} is
|
||||
* unready.
|
||||
* @return the application event
|
||||
*/
|
||||
public static ReadinessStateChangedEvent unready() {
|
||||
return new ReadinessStateChangedEvent(ReadinessState.UNREADY);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.availability;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ApplicationAvailabilityBean}
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ApplicationAvailabilityBeanTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
private ApplicationAvailabilityBean availability;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.context = new AnnotationConfigApplicationContext(ApplicationAvailabilityBean.class);
|
||||
this.availability = this.context.getBean(ApplicationAvailabilityBean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getLivenessStateWhenNoEventHasBeenPublishedReturnsDefaultState() {
|
||||
assertThat(this.availability.getLivenessState()).isEqualTo(LivenessState.BROKEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getLivenessStateWhenEventHasBeenPublishedReturnsPublishedState() {
|
||||
AvailabilityChangeEvent.publish(this.context, LivenessState.CORRECT);
|
||||
assertThat(this.availability.getLivenessState()).isEqualTo(LivenessState.CORRECT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getReadinessStateWhenNoEventHasBeenPublishedReturnsDefaultState() {
|
||||
assertThat(this.availability.getReadinessState()).isEqualTo(ReadinessState.REFUSING_TRAFFIC);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getReadinessStateWhenEventHasBeenPublishedReturnsPublishedState() {
|
||||
AvailabilityChangeEvent.publish(this.context, ReadinessState.ACCEPTING_TRAFFIC);
|
||||
assertThat(this.availability.getReadinessState()).isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getStateWhenNoEventHasBeenPublishedReturnsDefaultState() {
|
||||
assertThat(this.availability.getState(TestState.class)).isNull();
|
||||
assertThat(this.availability.getState(TestState.class, TestState.ONE)).isEqualTo(TestState.ONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getStateWhenEventHasBeenPublishedReturnsPublishedState() {
|
||||
AvailabilityChangeEvent.publish(this.context, TestState.TWO);
|
||||
assertThat(this.availability.getState(TestState.class)).isEqualTo(TestState.TWO);
|
||||
assertThat(this.availability.getState(TestState.class, TestState.ONE)).isEqualTo(TestState.TWO);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getLastChangeEventWhenNoEventHasBeenPublishedReturnsDefaultState() {
|
||||
assertThat(this.availability.getLastChangeEvent(TestState.class)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getLastChangeEventWhenEventHasBeenPublishedReturnsPublishedState() {
|
||||
AvailabilityChangeEvent.publish(this.context, TestState.TWO);
|
||||
assertThat(this.availability.getLastChangeEvent(TestState.class)).isNotNull();
|
||||
}
|
||||
|
||||
enum TestState implements AvailabilityState {
|
||||
|
||||
ONE {
|
||||
@Override
|
||||
public String test() {
|
||||
return "spring";
|
||||
}
|
||||
},
|
||||
|
||||
TWO {
|
||||
@Override
|
||||
public String test() {
|
||||
return "boot";
|
||||
}
|
||||
};
|
||||
|
||||
abstract String test();
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.availability;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ApplicationAvailabilityProvider}
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class ApplicationAvailabilityProviderTests {
|
||||
|
||||
@Test
|
||||
void initialStateShouldBeFailures() {
|
||||
ApplicationAvailabilityProvider stateProvider = new ApplicationAvailabilityProvider();
|
||||
assertThat(stateProvider.getLivenessState()).isEqualTo(LivenessState.BROKEN);
|
||||
assertThat(stateProvider.getReadinessState()).isEqualTo(ReadinessState.UNREADY);
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateLivenessState() {
|
||||
ApplicationAvailabilityProvider stateProvider = new ApplicationAvailabilityProvider();
|
||||
LivenessState livenessState = LivenessState.LIVE;
|
||||
stateProvider.onApplicationEvent(new LivenessStateChangedEvent(livenessState, "Startup complete"));
|
||||
assertThat(stateProvider.getLivenessState()).isEqualTo(livenessState);
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateReadiessState() {
|
||||
ApplicationAvailabilityProvider stateProvider = new ApplicationAvailabilityProvider();
|
||||
stateProvider.onApplicationEvent(ReadinessStateChangedEvent.ready());
|
||||
assertThat(stateProvider.getReadinessState()).isEqualTo(ReadinessState.READY);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.availability;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link AvailabilityChangeEvent}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class AvailabilityChangeEventTests {
|
||||
|
||||
private Object source = new Object();
|
||||
|
||||
@Test
|
||||
void createWhenStateIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new AvailabilityChangeEvent<>(this.source, null))
|
||||
.withMessage("State must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getStateReturnsState() {
|
||||
LivenessState state = LivenessState.CORRECT;
|
||||
AvailabilityChangeEvent<LivenessState> event = new AvailabilityChangeEvent<>(this.source, state);
|
||||
assertThat(event.getState()).isEqualTo(state);
|
||||
}
|
||||
|
||||
@Test
|
||||
void publishPublishesEvent() {
|
||||
ApplicationContext context = mock(ApplicationContext.class);
|
||||
AvailabilityState state = LivenessState.CORRECT;
|
||||
AvailabilityChangeEvent.publish(context, state);
|
||||
ArgumentCaptor<ApplicationEvent> captor = ArgumentCaptor.forClass(ApplicationEvent.class);
|
||||
verify(context).publishEvent(captor.capture());
|
||||
AvailabilityChangeEvent<?> event = (AvailabilityChangeEvent<?>) captor.getValue();
|
||||
assertThat(event.getSource()).isEqualTo(context);
|
||||
assertThat(event.getState()).isEqualTo(state);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue