Merge branch 'main' into 4.0.x
This commit is contained in:
@@ -71,12 +71,11 @@ class OnAvailableEndpointCondition extends SpringBootCondition {
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
Environment environment = context.getEnvironment();
|
||||
MergedAnnotation<ConditionalOnAvailableEndpoint> conditionAnnotation = metadata.getAnnotations()
|
||||
.get(ConditionalOnAvailableEndpoint.class);
|
||||
Class<?> target = getTarget(context, metadata, conditionAnnotation);
|
||||
MergedAnnotation<Endpoint> endpointAnnotation = getEndpointAnnotation(target);
|
||||
return getMatchOutcome(environment, conditionAnnotation, endpointAnnotation);
|
||||
return getMatchOutcome(context, conditionAnnotation, endpointAnnotation);
|
||||
}
|
||||
|
||||
private Class<?> getTarget(ConditionContext context, AnnotatedTypeMetadata metadata,
|
||||
@@ -109,16 +108,17 @@ class OnAvailableEndpointCondition extends SpringBootCondition {
|
||||
return getEndpointAnnotation(extension.getClass("endpoint"));
|
||||
}
|
||||
|
||||
private ConditionOutcome getMatchOutcome(Environment environment,
|
||||
private ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
MergedAnnotation<ConditionalOnAvailableEndpoint> conditionAnnotation,
|
||||
MergedAnnotation<Endpoint> endpointAnnotation) {
|
||||
ConditionMessage.Builder message = ConditionMessage.forCondition(ConditionalOnAvailableEndpoint.class);
|
||||
Environment environment = context.getEnvironment();
|
||||
EndpointId endpointId = EndpointId.of(environment, endpointAnnotation.getString("id"));
|
||||
ConditionOutcome accessOutcome = getAccessOutcome(environment, endpointAnnotation, endpointId, message);
|
||||
if (!accessOutcome.isMatch()) {
|
||||
return accessOutcome;
|
||||
}
|
||||
ConditionOutcome exposureOutcome = getExposureOutcome(environment, conditionAnnotation, endpointAnnotation,
|
||||
ConditionOutcome exposureOutcome = getExposureOutcome(context, conditionAnnotation, endpointAnnotation,
|
||||
endpointId, message);
|
||||
return (exposureOutcome != null) ? exposureOutcome : ConditionOutcome.noMatch(message.because("not exposed"));
|
||||
}
|
||||
@@ -137,11 +137,11 @@ class OnAvailableEndpointCondition extends SpringBootCondition {
|
||||
.accessFor(endpointId, defaultAccess);
|
||||
}
|
||||
|
||||
private ConditionOutcome getExposureOutcome(Environment environment,
|
||||
private ConditionOutcome getExposureOutcome(ConditionContext context,
|
||||
MergedAnnotation<ConditionalOnAvailableEndpoint> conditionAnnotation,
|
||||
MergedAnnotation<Endpoint> endpointAnnotation, EndpointId endpointId, Builder message) {
|
||||
Set<EndpointExposure> exposures = getExposures(conditionAnnotation);
|
||||
Set<EndpointExposureOutcomeContributor> outcomeContributors = getExposureOutcomeContributors(environment);
|
||||
Set<EndpointExposureOutcomeContributor> outcomeContributors = getExposureOutcomeContributors(context);
|
||||
for (EndpointExposureOutcomeContributor outcomeContributor : outcomeContributors) {
|
||||
ConditionOutcome outcome = outcomeContributor.getExposureOutcome(endpointId, exposures, message);
|
||||
if (outcome != null && outcome.isMatch()) {
|
||||
@@ -166,7 +166,8 @@ class OnAvailableEndpointCondition extends SpringBootCondition {
|
||||
return result;
|
||||
}
|
||||
|
||||
private Set<EndpointExposureOutcomeContributor> getExposureOutcomeContributors(Environment environment) {
|
||||
private Set<EndpointExposureOutcomeContributor> getExposureOutcomeContributors(ConditionContext context) {
|
||||
Environment environment = context.getEnvironment();
|
||||
Set<EndpointExposureOutcomeContributor> contributors = exposureOutcomeContributorsCache.get(environment);
|
||||
if (contributors == null) {
|
||||
contributors = new LinkedHashSet<>();
|
||||
@@ -174,15 +175,16 @@ class OnAvailableEndpointCondition extends SpringBootCondition {
|
||||
if (environment.getProperty(JMX_ENABLED_KEY, Boolean.class, false)) {
|
||||
contributors.add(new StandardExposureOutcomeContributor(environment, EndpointExposure.JMX));
|
||||
}
|
||||
contributors.addAll(loadExposureOutcomeContributors(environment));
|
||||
contributors.addAll(loadExposureOutcomeContributors(context.getClassLoader(), environment));
|
||||
exposureOutcomeContributorsCache.put(environment, contributors);
|
||||
}
|
||||
return contributors;
|
||||
}
|
||||
|
||||
private List<EndpointExposureOutcomeContributor> loadExposureOutcomeContributors(Environment environment) {
|
||||
private List<EndpointExposureOutcomeContributor> loadExposureOutcomeContributors(ClassLoader classLoader,
|
||||
Environment environment) {
|
||||
ArgumentResolver argumentResolver = ArgumentResolver.of(Environment.class, environment);
|
||||
return SpringFactoriesLoader.forDefaultResourceLocation()
|
||||
return SpringFactoriesLoader.forDefaultResourceLocation(classLoader)
|
||||
.load(EndpointExposureOutcomeContributor.class, argumentResolver);
|
||||
}
|
||||
|
||||
|
||||
@@ -294,6 +294,13 @@ class ConditionalOnAvailableEndpointTests {
|
||||
.run((context) -> assertThat(context).hasSingleBean(DisabledButAccessibleEndpoint.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithTestEndpointOutcomeExposureContributor
|
||||
void exposureOutcomeContributorCanMakeEndpointAvailable() {
|
||||
this.contextRunner.withPropertyValues("management.endpoints.test.exposure.include=test")
|
||||
.run((context) -> assertThat(context).hasSingleBean(TestEndpoint.class));
|
||||
}
|
||||
|
||||
@Endpoint(id = "health")
|
||||
static class HealthEndpoint {
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.endpoint.condition;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.expose.IncludeExcludeEndpointFilter;
|
||||
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionMessage.Builder;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||
import org.springframework.boot.testsupport.classpath.resources.WithResource;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
|
||||
/**
|
||||
* Makes a test {@link EndpointExposureOutcomeContributor} available via
|
||||
* {@link SpringFactoriesLoader}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@WithResource(name = "META-INF/spring.factories",
|
||||
content = """
|
||||
org.springframework.boot.actuate.autoconfigure.endpoint.condition.EndpointExposureOutcomeContributor=\
|
||||
org.springframework.boot.actuate.autoconfigure.endpoint.condition.WithTestEndpointOutcomeExposureContributor.TestEndpointExposureOutcomeContributor
|
||||
""")
|
||||
public @interface WithTestEndpointOutcomeExposureContributor {
|
||||
|
||||
class TestEndpointExposureOutcomeContributor implements EndpointExposureOutcomeContributor {
|
||||
|
||||
private final IncludeExcludeEndpointFilter<?> filter;
|
||||
|
||||
TestEndpointExposureOutcomeContributor(Environment environment) {
|
||||
this.filter = new IncludeExcludeEndpointFilter<>(ExposableEndpoint.class, environment,
|
||||
"management.endpoints.test.exposure");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getExposureOutcome(EndpointId endpointId, Set<EndpointExposure> exposures,
|
||||
Builder message) {
|
||||
if (this.filter.match(endpointId)) {
|
||||
return ConditionOutcome.match();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user