Move remaining integration tests out of actuator-autoconfigure-all
See gh-46071
This commit is contained in:
parent
9860168d3e
commit
76719a4e28
|
@ -59,7 +59,6 @@ include "spring-boot-project:spring-boot"
|
|||
include "spring-boot-project:spring-boot-activemq"
|
||||
include "spring-boot-project:spring-boot-actuator"
|
||||
include "spring-boot-project:spring-boot-actuator-autoconfigure"
|
||||
include "spring-boot-project:spring-boot-actuator-autoconfigure-all"
|
||||
include "spring-boot-project:spring-boot-actuator-docs"
|
||||
include "spring-boot-project:spring-boot-actuator-integration-tests"
|
||||
include "spring-boot-project:spring-boot-amqp"
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.
|
||||
*/
|
||||
|
||||
|
||||
plugins {
|
||||
id "java-library"
|
||||
id "org.springframework.boot.deployed"
|
||||
id "org.springframework.boot.optional-dependencies"
|
||||
}
|
||||
|
||||
description = "Spring Boot Actuator AutoConfigure All"
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.eachDependency {
|
||||
if (it.requested.group == 'org.opensaml') {
|
||||
it.useVersion '4.0.1'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))
|
||||
api(project(":spring-boot-project:spring-boot-autoconfigure"))
|
||||
|
||||
optional(project(":spring-boot-project:spring-boot-jersey"))
|
||||
optional(project(":spring-boot-project:spring-boot-security"))
|
||||
optional(project(":spring-boot-project:spring-boot-security-oauth2-client"))
|
||||
optional(project(":spring-boot-project:spring-boot-security-oauth2-resource-server"))
|
||||
optional(project(":spring-boot-project:spring-boot-security-saml2"))
|
||||
optional(project(":spring-boot-project:spring-boot-web-server"))
|
||||
optional(project(":spring-boot-project:spring-boot-webmvc"))
|
||||
optional("io.projectreactor:reactor-core")
|
||||
optional("jakarta.servlet:jakarta.servlet-api")
|
||||
|
||||
testImplementation(project(":spring-boot-project:spring-boot-data-cassandra"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-data-rest"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-hateoas"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-http-codec"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-http-converter"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-jackson"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-reactor-netty"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-test"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-tomcat"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-webflux"))
|
||||
testImplementation("org.springframework.security:spring-security-test")
|
||||
|
||||
testRuntimeOnly("ch.qos.logback:logback-classic")
|
||||
}
|
||||
|
||||
tasks.named("test") {
|
||||
jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED"
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.integrationtest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.audit.AuditEventsEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.condition.ConditionsReportEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.context.ShutdownEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.context.properties.ConfigurationPropertiesReportEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.env.EnvironmentEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.management.ThreadDumpEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAutoConfiguration;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* A list of all endpoint auto-configuration classes for use in tests.
|
||||
*/
|
||||
final class EndpointAutoConfigurationClasses {
|
||||
|
||||
static final Class<?>[] ALL;
|
||||
|
||||
static {
|
||||
List<Class<?>> all = new ArrayList<>();
|
||||
all.add(AuditEventsEndpointAutoConfiguration.class);
|
||||
all.add(BeansEndpointAutoConfiguration.class);
|
||||
all.add(ConditionsReportEndpointAutoConfiguration.class);
|
||||
all.add(ConfigurationPropertiesReportEndpointAutoConfiguration.class);
|
||||
all.add(ShutdownEndpointAutoConfiguration.class);
|
||||
all.add(EnvironmentEndpointAutoConfiguration.class);
|
||||
all.add(HealthEndpointAutoConfiguration.class);
|
||||
all.add(InfoEndpointAutoConfiguration.class);
|
||||
all.add(ThreadDumpEndpointAutoConfiguration.class);
|
||||
all.add(HttpExchangesEndpointAutoConfiguration.class);
|
||||
all.add(MappingsEndpointAutoConfiguration.class);
|
||||
ALL = ClassUtils.toClassArray(all);
|
||||
}
|
||||
|
||||
private EndpointAutoConfigurationClasses() {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.integrationtest;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.jackson.EndpointObjectMapper;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
|
||||
/**
|
||||
* {@link Configuration @Configuration} that creates an {@link EndpointObjectMapper} that
|
||||
* reverses all strings.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Configuration
|
||||
@SuppressWarnings("removal")
|
||||
class EndpointObjectMapperConfiguration {
|
||||
|
||||
@Bean
|
||||
EndpointObjectMapper endpointObjectMapper() {
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.addSerializer(String.class, new ReverseStringSerializer());
|
||||
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modules(module).build();
|
||||
return () -> objectMapper;
|
||||
}
|
||||
|
||||
static class ReverseStringSerializer extends StdScalarSerializer<Object> {
|
||||
|
||||
ReverseStringSerializer() {
|
||||
super(String.class, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty(SerializerProvider prov, Object value) {
|
||||
return ((String) value).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
serialize(value, gen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider,
|
||||
TypeSerializer typeSer) throws IOException {
|
||||
serialize(value, gen);
|
||||
}
|
||||
|
||||
private void serialize(Object value, JsonGenerator gen) throws IOException {
|
||||
StringBuilder builder = new StringBuilder((String) value);
|
||||
gen.writeString(builder.reverse().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -40,6 +40,7 @@ dependencies {
|
|||
optional("jakarta.servlet:jakarta.servlet-api")
|
||||
optional("org.springframework.security:spring-security-config")
|
||||
|
||||
testFixturesImplementation(project(":spring-boot-project:spring-boot-test"))
|
||||
testFixturesImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
|
||||
|
||||
testImplementation(project(":spring-boot-project:spring-boot-test"))
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.actuate.autoconfigure.endpoint.jmx;
|
||||
|
||||
import javax.management.MBeanOperationInfo;
|
||||
import javax.management.MBeanServer;
|
||||
|
@ -23,8 +23,8 @@ import javax.management.ObjectName;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
|
@ -49,7 +49,7 @@ class JmxEndpointAccessIntegrationTests {
|
|||
JmxEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class))
|
||||
.withUserConfiguration(CustomJmxEndpoint.class)
|
||||
.withPropertyValues("spring.jmx.enabled=true")
|
||||
.withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL));
|
||||
.withConfiguration(AutoConfigurations.of(BeansEndpointAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void accessIsUnrestrictedByDefault() {
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.actuate.autoconfigure.endpoint.jmx;
|
||||
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.IntrospectionException;
|
||||
|
@ -28,9 +28,11 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor;
|
||||
import org.springframework.boot.actuate.audit.InMemoryAuditEventRepository;
|
||||
import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.context.ShutdownEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||
|
@ -54,14 +56,14 @@ class JmxEndpointIntegrationTests {
|
|||
JmxEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class))
|
||||
.withUserConfiguration(HttpExchangeRepositoryConfiguration.class, AuditEventRepositoryConfiguration.class)
|
||||
.withPropertyValues("spring.jmx.enabled=true")
|
||||
.withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL));
|
||||
.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class,
|
||||
BeansEndpointAutoConfiguration.class, ShutdownEndpointAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void jmxEndpointsExposeHealthByDefault() {
|
||||
this.contextRunner.run((context) -> {
|
||||
MBeanServer mBeanServer = context.getBean(MBeanServer.class);
|
||||
checkEndpointMBeans(mBeanServer, new String[] { "health" }, new String[] { "beans", "conditions",
|
||||
"configprops", "env", "info", "mappings", "threaddump", "httpexchanges", "shutdown" });
|
||||
checkEndpointMBeans(mBeanServer, new String[] { "health" }, new String[] { "beans", "shutdown" });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -71,8 +73,7 @@ class JmxEndpointIntegrationTests {
|
|||
.withBean(LazyInitializationBeanFactoryPostProcessor.class, LazyInitializationBeanFactoryPostProcessor::new)
|
||||
.run((context) -> {
|
||||
MBeanServer mBeanServer = context.getBean(MBeanServer.class);
|
||||
checkEndpointMBeans(mBeanServer, new String[] { "beans", "conditions", "configprops", "env", "health",
|
||||
"info", "mappings", "threaddump", "httpexchanges" }, new String[] { "shutdown" });
|
||||
checkEndpointMBeans(mBeanServer, new String[] { "beans", "health" }, new String[] { "shutdown" });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -80,8 +81,7 @@ class JmxEndpointIntegrationTests {
|
|||
void jmxEndpointsCanBeExcluded() {
|
||||
this.contextRunner.withPropertyValues("management.endpoints.jmx.exposure.exclude:*").run((context) -> {
|
||||
MBeanServer mBeanServer = context.getBean(MBeanServer.class);
|
||||
checkEndpointMBeans(mBeanServer, new String[0], new String[] { "beans", "conditions", "configprops", "env",
|
||||
"health", "mappings", "shutdown", "threaddump", "httpexchanges" });
|
||||
checkEndpointMBeans(mBeanServer, new String[0], new String[] { "beans", "health", "shutdown" });
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -90,8 +90,7 @@ class JmxEndpointIntegrationTests {
|
|||
void singleJmxEndpointCanBeExposed() {
|
||||
this.contextRunner.withPropertyValues("management.endpoints.jmx.exposure.include=beans").run((context) -> {
|
||||
MBeanServer mBeanServer = context.getBean(MBeanServer.class);
|
||||
checkEndpointMBeans(mBeanServer, new String[] { "beans" }, new String[] { "conditions", "configprops",
|
||||
"env", "health", "mappings", "shutdown", "threaddump", "httpexchanges" });
|
||||
checkEndpointMBeans(mBeanServer, new String[] { "beans" }, new String[] { "health", "shutdown" });
|
||||
});
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.actuate.autoconfigure.endpoint.web;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -22,13 +22,9 @@ import org.springframework.boot.SpringBootConfiguration;
|
|||
import org.springframework.boot.actuate.health.HealthEndpointWebExtension;
|
||||
import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration;
|
||||
import org.springframework.boot.context.annotation.UserConfigurations;
|
||||
import org.springframework.boot.data.cassandra.autoconfigure.CassandraDataAutoConfiguration;
|
||||
import org.springframework.boot.data.rest.autoconfigure.RepositoryRestMvcAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
@ -46,7 +42,6 @@ class WebEndpointsAutoConfigurationIntegrationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ClassPathExclusions({ "spring-security-oauth2-client-*.jar", "spring-security-oauth2-resource-server-*.jar" })
|
||||
void healthEndpointReactiveWebExtensionIsAutoConfigured() {
|
||||
reactiveWebRunner()
|
||||
.run((context) -> assertThat(context).hasSingleBean(ReactiveHealthEndpointWebExtension.class));
|
||||
|
@ -64,8 +59,7 @@ class WebEndpointsAutoConfigurationIntegrationTests {
|
|||
.withPropertyValues("management.defaults.metrics.export.enabled=false");
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration(exclude = { CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class,
|
||||
RepositoryRestMvcAutoConfiguration.class })
|
||||
@EnableAutoConfiguration
|
||||
@SpringBootConfiguration
|
||||
static class WebEndpointTestApplication {
|
||||
|
|
@ -37,11 +37,11 @@ import static org.assertj.core.api.Assertions.assertThatNoException;
|
|||
* @param <A> the assertions
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
abstract class AbstractHealthEndpointAdditionalPathIntegrationTests<T extends AbstractApplicationContextRunner<T, C, A>, C extends ConfigurableApplicationContext, A extends ApplicationContextAssertProvider<C>> {
|
||||
public abstract class AbstractHealthEndpointAdditionalPathIntegrationTests<T extends AbstractApplicationContextRunner<T, C, A>, C extends ConfigurableApplicationContext, A extends ApplicationContextAssertProvider<C>> {
|
||||
|
||||
private final T runner;
|
||||
|
||||
AbstractHealthEndpointAdditionalPathIntegrationTests(T runner) {
|
||||
protected AbstractHealthEndpointAdditionalPathIntegrationTests(T runner) {
|
||||
this.runner = runner;
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ plugins {
|
|||
description = "Spring Boot Actuator Docs"
|
||||
|
||||
dependencies {
|
||||
testImplementation(project(":spring-boot-project:spring-boot-actuator-autoconfigure-all"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-cache"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-flyway"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-http-converter"))
|
||||
|
|
|
@ -1986,7 +1986,6 @@ bom {
|
|||
"spring-boot-activemq",
|
||||
"spring-boot-actuator",
|
||||
"spring-boot-actuator-autoconfigure",
|
||||
"spring-boot-actuator-autoconfigure-all",
|
||||
"spring-boot-amqp",
|
||||
"spring-boot-artemis",
|
||||
"spring-boot-autoconfigure",
|
||||
|
|
|
@ -374,7 +374,7 @@ dependencies {
|
|||
springApplicationExample(platform(project(":spring-boot-project:spring-boot-dependencies")))
|
||||
springApplicationExample(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-web"))
|
||||
|
||||
testImplementation(project(":spring-boot-project:spring-boot-actuator-autoconfigure-all"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
|
||||
|
||||
testRuntimeOnly(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web"))
|
||||
|
|
|
@ -55,6 +55,7 @@ dependencies {
|
|||
testImplementation(project(":spring-boot-project:spring-boot-web-server-test"))
|
||||
testImplementation(testFixtures(project(":spring-boot-project:spring-boot-actuator-autoconfigure")))
|
||||
testImplementation("jakarta.servlet:jakarta.servlet-api")
|
||||
testImplementation("org.springframework:spring-webflux")
|
||||
|
||||
testRuntimeOnly("ch.qos.logback:logback-classic")
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.jersey.actuate.autoconfigure;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
|
@ -33,7 +33,6 @@ import org.springframework.boot.actuate.autoconfigure.web.server.ManagementConte
|
|||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
|
@ -44,7 +43,6 @@ import org.springframework.http.HttpStatus;
|
|||
import org.springframework.test.web.reactive.server.EntityExchangeResult;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.reactive.function.client.ExchangeStrategies;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
@ -61,7 +59,6 @@ class JerseyEndpointAccessIntegrationTests {
|
|||
EndpointAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class,
|
||||
WebEndpointAutoConfiguration.class, ManagementContextAutoConfiguration.class,
|
||||
BeansEndpointAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader(DispatcherServlet.class))
|
||||
.withUserConfiguration(CustomServletEndpoint.class)
|
||||
.withPropertyValues("server.port:0");
|
||||
|
|
@ -14,14 +14,21 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.jersey.actuate.autoconfigure;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -29,19 +36,16 @@ import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoCon
|
|||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.jackson.EndpointObjectMapper;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.security.actuate.autoconfigure.servlet.ManagementWebSecurityAutoConfiguration;
|
||||
import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
@ -79,23 +83,6 @@ class JerseyEndpointIntegrationTests {
|
|||
testJerseyEndpoints(new Class<?>[] { EndpointsConfiguration.class });
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorEndpointsWhenSecurityAvailable() {
|
||||
WebApplicationContextRunner contextRunner = getContextRunner(
|
||||
new Class<?>[] { EndpointsConfiguration.class, ResourceConfigConfiguration.class },
|
||||
getAutoconfigurations(SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class));
|
||||
contextRunner.run((context) -> {
|
||||
int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class)
|
||||
.getWebServer()
|
||||
.getPort();
|
||||
WebTestClient client = WebTestClient.bindToServer()
|
||||
.baseUrl("http://localhost:" + port)
|
||||
.responseTimeout(Duration.ofMinutes(5))
|
||||
.build();
|
||||
client.get().uri("/actuator").exchange().expectStatus().isUnauthorized();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void endpointObjectMapperCanBeApplied() {
|
||||
WebApplicationContextRunner contextRunner = getContextRunner(new Class<?>[] { EndpointsConfiguration.class,
|
||||
|
@ -141,9 +128,7 @@ class JerseyEndpointIntegrationTests {
|
|||
|
||||
WebApplicationContextRunner getContextRunner(Class<?>[] userConfigurations,
|
||||
Class<?>... additionalAutoConfigurations) {
|
||||
FilteredClassLoader classLoader = new FilteredClassLoader(DispatcherServlet.class);
|
||||
return new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
|
||||
.withClassLoader(classLoader)
|
||||
.withConfiguration(AutoConfigurations.of(getAutoconfigurations(additionalAutoConfigurations)))
|
||||
.withUserConfiguration(userConfigurations)
|
||||
.withPropertyValues("management.endpoints.web.exposure.include:*", "server.port:0");
|
||||
|
@ -195,4 +180,49 @@ class JerseyEndpointIntegrationTests {
|
|||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@SuppressWarnings({ "deprecation", "removal" })
|
||||
static class EndpointObjectMapperConfiguration {
|
||||
|
||||
@Bean
|
||||
EndpointObjectMapper endpointObjectMapper() {
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.addSerializer(String.class, new ReverseStringSerializer());
|
||||
ObjectMapper objectMapper = org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.json()
|
||||
.modules(module)
|
||||
.build();
|
||||
return () -> objectMapper;
|
||||
}
|
||||
|
||||
static class ReverseStringSerializer extends StdScalarSerializer<Object> {
|
||||
|
||||
ReverseStringSerializer() {
|
||||
super(String.class, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty(SerializerProvider prov, Object value) {
|
||||
return ((String) value).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
serialize(value, gen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider,
|
||||
TypeSerializer typeSer) throws IOException {
|
||||
serialize(value, gen);
|
||||
}
|
||||
|
||||
private void serialize(Object value, JsonGenerator gen) throws IOException {
|
||||
StringBuilder builder = new StringBuilder((String) value);
|
||||
gen.writeString(builder.reverse().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -14,11 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.jersey.actuate.autoconfigure;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.integrationtest.AbstractHealthEndpointAdditionalPathIntegrationTests;
|
||||
import org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
|
@ -26,7 +27,6 @@ import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
|||
import org.springframework.boot.jersey.actuate.autoconfigure.health.HealthEndpointJerseyExtensionAutoConfiguration;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.servlet.actuate.autoconfigure.ServletManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.tomcat.actuate.autoconfigure.web.TomcatServletManagementContextAutoConfiguration;
|
||||
|
@ -34,7 +34,6 @@ import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebSer
|
|||
import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer;
|
||||
import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
/**
|
||||
* Integration tests for health groups on an additional path on Jersey.
|
||||
|
@ -54,7 +53,6 @@ class JerseyHealthEndpointAdditionalPathIntegrationTests extends
|
|||
HealthEndpointJerseyExtensionAutoConfiguration.class,
|
||||
DiskSpaceHealthContributorAutoConfiguration.class))
|
||||
.withInitializer(new ServerPortInfoApplicationContextInitializer())
|
||||
.withClassLoader(new FilteredClassLoader(DispatcherServlet.class))
|
||||
.withPropertyValues("server.port=0"));
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ plugins {
|
|||
description = "Starter for using Spring Boot's Actuator which provides production ready features to help you monitor and manage your application"
|
||||
|
||||
dependencies {
|
||||
api(project(":spring-boot-project:spring-boot-actuator-autoconfigure-all"))
|
||||
api(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))
|
||||
api(project(":spring-boot-project:spring-boot-metrics"))
|
||||
api(project(":spring-boot-project:spring-boot-tracing"))
|
||||
api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter"))
|
||||
|
|
|
@ -145,7 +145,7 @@ dependencies {
|
|||
optional("io.micrometer:micrometer-tracing")
|
||||
|
||||
testImplementation(project(":spring-boot-project:spring-boot-actuator"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-actuator-autoconfigure-all"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-freemarker"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-gson"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-mustache"))
|
||||
|
|
|
@ -39,7 +39,6 @@ if (project.hasProperty("oldVersion") && project.hasProperty("newVersion")) {
|
|||
["spring-boot",
|
||||
"spring-boot-actuator",
|
||||
"spring-boot-actuator-autoconfigure",
|
||||
"spring-boot-actuator-autoconfigure-all",
|
||||
"spring-boot-autoconfigure",
|
||||
"spring-boot-devtools",
|
||||
"spring-boot-test-autoconfigure"].each {
|
||||
|
|
|
@ -45,6 +45,7 @@ dependencies {
|
|||
testFixturesImplementation(project(":spring-boot-project:spring-boot-jackson"))
|
||||
testFixturesImplementation(project(":spring-boot-project:spring-boot-reactor-netty"))
|
||||
|
||||
testImplementation(project(":spring-boot-project:spring-boot-jackson"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-mustache"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-reactor-netty"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-test"))
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.webflux.actuate.autoconfigure.web;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -28,13 +28,10 @@ import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoi
|
|||
import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration;
|
||||
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.boot.web.context.reactive.AnnotationConfigReactiveWebApplicationContext;
|
||||
import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.test.context.TestSecurityContextHolder;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
|
@ -51,14 +48,11 @@ class ControllerEndpointWebFluxIntegrationTests {
|
|||
|
||||
@AfterEach
|
||||
void close() {
|
||||
TestSecurityContextHolder.clearContext();
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void endpointsCanBeAccessed() {
|
||||
TestSecurityContextHolder.getContext()
|
||||
.setAuthentication(new TestingAuthenticationToken("user", "N/A", "ROLE_ACTUATOR"));
|
||||
this.context = new AnnotationConfigReactiveWebApplicationContext();
|
||||
this.context.register(DefaultConfiguration.class, ExampleController.class);
|
||||
TestPropertyValues.of("management.endpoints.web.exposure.include=*").applyTo(this.context);
|
||||
|
@ -67,8 +61,8 @@ class ControllerEndpointWebFluxIntegrationTests {
|
|||
webClient.get().uri("/actuator/example").exchange().expectStatus().isOk();
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
|
||||
EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||
@ImportAutoConfiguration({ JacksonAutoConfiguration.class, EndpointAutoConfiguration.class,
|
||||
WebEndpointAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, WebFluxAutoConfiguration.class,
|
||||
ManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class })
|
||||
static class DefaultConfiguration {
|
|
@ -14,12 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.webflux.actuate.autoconfigure.web;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
|
@ -56,7 +57,7 @@ class WebFluxEndpointAccessIntegrationTests {
|
|||
HttpHandlerAutoConfiguration.class, JacksonAutoConfiguration.class, CodecsAutoConfiguration.class,
|
||||
WebFluxAutoConfiguration.class, EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class,
|
||||
ManagementContextAutoConfiguration.class))
|
||||
.withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL))
|
||||
.withConfiguration(AutoConfigurations.of(BeansEndpointAutoConfiguration.class))
|
||||
.withUserConfiguration(CustomWebFluxEndpoint.class)
|
||||
.withPropertyValues("server.port:0");
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.webflux.actuate.autoconfigure.web;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
|
@ -14,16 +14,24 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.webflux.actuate.autoconfigure.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.jackson.EndpointObjectMapper;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration;
|
||||
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
|
@ -131,4 +139,49 @@ class WebFluxEndpointIntegrationTests {
|
|||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@SuppressWarnings({ "deprecation", "removal" })
|
||||
static class EndpointObjectMapperConfiguration {
|
||||
|
||||
@Bean
|
||||
EndpointObjectMapper endpointObjectMapper() {
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.addSerializer(String.class, new ReverseStringSerializer());
|
||||
ObjectMapper objectMapper = org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.json()
|
||||
.modules(module)
|
||||
.build();
|
||||
return () -> objectMapper;
|
||||
}
|
||||
|
||||
static class ReverseStringSerializer extends StdScalarSerializer<Object> {
|
||||
|
||||
ReverseStringSerializer() {
|
||||
super(String.class, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty(SerializerProvider prov, Object value) {
|
||||
return ((String) value).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
serialize(value, gen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider,
|
||||
TypeSerializer typeSer) throws IOException {
|
||||
serialize(value, gen);
|
||||
}
|
||||
|
||||
private void serialize(Object value, JsonGenerator gen) throws IOException {
|
||||
StringBuilder builder = new StringBuilder((String) value);
|
||||
gen.writeString(builder.reverse().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -14,12 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.webflux.actuate.autoconfigure.web;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.integrationtest.AbstractHealthEndpointAdditionalPathIntegrationTests;
|
||||
import org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
|
@ -51,6 +51,7 @@ dependencies {
|
|||
testFixturesImplementation(project(":spring-boot-project:spring-boot-jackson"))
|
||||
|
||||
testImplementation(project(":spring-boot-project:spring-boot-freemarker"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-jackson"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-restclient"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-test"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-tomcat"))
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.webmvc.actuate.autoconfigure.endpoint.web;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -28,24 +28,16 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
|||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration;
|
||||
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.servlet.actuate.autoconfigure.ServletManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext;
|
||||
import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.test.context.TestSecurityContextHolder;
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcConfigurer;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
||||
|
||||
/**
|
||||
* Integration tests for the Actuator's MVC
|
||||
|
@ -61,45 +53,24 @@ class ControllerEndpointWebMvcIntegrationTests {
|
|||
|
||||
@AfterEach
|
||||
void close() {
|
||||
TestSecurityContextHolder.clearContext();
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void endpointsAreSecureByDefault() {
|
||||
this.context = new AnnotationConfigServletWebApplicationContext();
|
||||
this.context.register(SecureConfiguration.class, ExampleController.class);
|
||||
MockMvcTester mvc = createSecureMockMvcTester();
|
||||
assertThat(mvc.get().uri("/actuator/example").accept(MediaType.APPLICATION_JSON))
|
||||
.hasStatus(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void endpointsCanBeAccessed() {
|
||||
TestSecurityContextHolder.getContext()
|
||||
.setAuthentication(new TestingAuthenticationToken("user", "N/A", "ROLE_ACTUATOR"));
|
||||
this.context = new AnnotationConfigServletWebApplicationContext();
|
||||
this.context.register(SecureConfiguration.class, ExampleController.class);
|
||||
this.context.register(DefaultConfiguration.class, ExampleController.class);
|
||||
TestPropertyValues
|
||||
.of("management.endpoints.web.base-path:/management", "management.endpoints.web.exposure.include=*")
|
||||
.applyTo(this.context);
|
||||
MockMvcTester mvc = createSecureMockMvcTester();
|
||||
MockMvcTester mvc = createMockMvcTester();
|
||||
assertThat(mvc.get().uri("/management/example")).hasStatusOk();
|
||||
}
|
||||
|
||||
private MockMvcTester createSecureMockMvcTester() {
|
||||
return doCreateMockMvcTester(springSecurity());
|
||||
}
|
||||
|
||||
private MockMvcTester doCreateMockMvcTester(MockMvcConfigurer... configurers) {
|
||||
private MockMvcTester createMockMvcTester() {
|
||||
this.context.setServletContext(new MockServletContext());
|
||||
this.context.refresh();
|
||||
return MockMvcTester.from(this.context, (builder) -> {
|
||||
for (MockMvcConfigurer configurer : configurers) {
|
||||
builder.apply(configurer);
|
||||
}
|
||||
return builder.build();
|
||||
});
|
||||
return MockMvcTester.from(this.context);
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
|
||||
|
@ -112,12 +83,6 @@ class ControllerEndpointWebMvcIntegrationTests {
|
|||
|
||||
}
|
||||
|
||||
@Import(DefaultConfiguration.class)
|
||||
@ImportAutoConfiguration({ SecurityAutoConfiguration.class })
|
||||
static class SecureConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "example")
|
||||
@SuppressWarnings("removal")
|
||||
static class ExampleController {
|
|
@ -14,10 +14,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.webmvc.actuate.autoconfigure.endpoint.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
|
@ -26,6 +25,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
|||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
|
||||
|
@ -43,11 +43,10 @@ import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfig
|
|||
import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.test.web.reactive.server.EntityExchangeResult;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.reactive.function.client.ExchangeStrategies;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
@ -65,15 +64,14 @@ class WebMvcEndpointAccessIntegrationTests {
|
|||
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
|
||||
WebMvcAutoConfiguration.class, EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class,
|
||||
ManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class,
|
||||
HealthContributorAutoConfiguration.class))
|
||||
.withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL))
|
||||
HealthContributorAutoConfiguration.class, BeansEndpointAutoConfiguration.class))
|
||||
.withUserConfiguration(CustomMvcEndpoint.class, CustomServletEndpoint.class)
|
||||
.withPropertyValues("server.port:0");
|
||||
|
||||
@Test
|
||||
void accessIsUnrestrictedByDefault() {
|
||||
this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=*").run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
RestClient client = createClient(context);
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isTrue();
|
||||
|
@ -88,7 +86,7 @@ class WebMvcEndpointAccessIntegrationTests {
|
|||
.withPropertyValues("management.endpoints.web.exposure.include=*",
|
||||
"management.endpoints.access.default=READ_ONLY")
|
||||
.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
RestClient client = createClient(context);
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse();
|
||||
|
@ -103,7 +101,7 @@ class WebMvcEndpointAccessIntegrationTests {
|
|||
.withPropertyValues("management.endpoints.web.exposure.include=*",
|
||||
"management.endpoints.access.default=NONE")
|
||||
.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
RestClient client = createClient(context);
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "beans")).isFalse();
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isFalse();
|
||||
assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse();
|
||||
|
@ -119,7 +117,7 @@ class WebMvcEndpointAccessIntegrationTests {
|
|||
"management.endpoints.access.default=READ_ONLY",
|
||||
"management.endpoint.customservlet.access=UNRESTRICTED")
|
||||
.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
RestClient client = createClient(context);
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse();
|
||||
|
@ -135,7 +133,7 @@ class WebMvcEndpointAccessIntegrationTests {
|
|||
"management.endpoints.access.default=UNRESTRICTED",
|
||||
"management.endpoints.access.max-permitted=READ_ONLY")
|
||||
.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
RestClient client = createClient(context);
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse();
|
||||
|
@ -149,7 +147,7 @@ class WebMvcEndpointAccessIntegrationTests {
|
|||
this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=*",
|
||||
"management.endpoints.access.default=UNRESTRICTED", "management.endpoints.access.max-permitted=NONE")
|
||||
.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
RestClient client = createClient(context);
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "beans")).isFalse();
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isFalse();
|
||||
assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse();
|
||||
|
@ -158,31 +156,25 @@ class WebMvcEndpointAccessIntegrationTests {
|
|||
});
|
||||
}
|
||||
|
||||
private WebTestClient createClient(AssertableWebApplicationContext context) {
|
||||
private RestClient createClient(AssertableWebApplicationContext context) {
|
||||
int port = context.getSourceApplicationContext(ServletWebServerApplicationContext.class)
|
||||
.getWebServer()
|
||||
.getPort();
|
||||
ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder()
|
||||
.codecs((configurer) -> configurer.defaultCodecs().maxInMemorySize(-1))
|
||||
.build();
|
||||
return WebTestClient.bindToServer()
|
||||
.baseUrl("http://localhost:" + port)
|
||||
.exchangeStrategies(exchangeStrategies)
|
||||
.responseTimeout(Duration.ofMinutes(5))
|
||||
.build();
|
||||
return RestClient.builder().defaultStatusHandler((status) -> true, (request, response) -> {
|
||||
}).baseUrl("http://localhost:" + port).build();
|
||||
}
|
||||
|
||||
private boolean isAccessible(WebTestClient client, HttpMethod method, String path) {
|
||||
private boolean isAccessible(RestClient client, HttpMethod method, String path) {
|
||||
path = "/actuator/" + path;
|
||||
EntityExchangeResult<byte[]> result = client.method(method).uri(path).exchange().expectBody().returnResult();
|
||||
if (result.getStatus() == HttpStatus.OK) {
|
||||
ResponseEntity<byte[]> result = client.method(method).uri(path).retrieve().toEntity(byte[].class);
|
||||
if (result.getStatusCode() == HttpStatus.OK) {
|
||||
return true;
|
||||
}
|
||||
if (result.getStatus() == HttpStatus.NOT_FOUND || result.getStatus() == HttpStatus.METHOD_NOT_ALLOWED) {
|
||||
if (result.getStatusCode() == HttpStatus.NOT_FOUND || result.getStatusCode() == HttpStatus.METHOD_NOT_ALLOWED) {
|
||||
return false;
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
String.format("Unexpected %s HTTP status for endpoint %s", result.getStatus(), path));
|
||||
String.format("Unexpected %s HTTP status for endpoint %s", result.getStatusCode(), path));
|
||||
}
|
||||
|
||||
@org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "custommvc")
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.webmvc.actuate.autoconfigure.endpoint.web;
|
||||
|
||||
import org.assertj.core.api.ThrowingConsumer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -29,7 +29,6 @@ import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
|||
import org.springframework.boot.servlet.actuate.autoconfigure.ServletManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.webmvc.actuate.autoconfigure.endpoint.web.WebMvcEndpointManagementContextConfiguration;
|
||||
import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration;
|
||||
import org.springframework.http.HttpHeaders;
|
|
@ -14,10 +14,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.webmvc.actuate.autoconfigure.endpoint.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
|
@ -27,9 +26,12 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.audit.InMemoryAuditEventRepository;
|
||||
import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.context.ShutdownEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
|
@ -48,10 +50,9 @@ import org.springframework.context.annotation.Bean;
|
|||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.test.web.reactive.server.EntityExchangeResult;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.reactive.function.client.ExchangeStrategies;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
@ -71,28 +72,19 @@ class WebMvcEndpointExposureIntegrationTests {
|
|||
WebMvcAutoConfiguration.class, EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class,
|
||||
ManagementContextAutoConfiguration.class, ManagementContextAutoConfiguration.class,
|
||||
ServletManagementContextAutoConfiguration.class, ServletHttpExchangesAutoConfiguration.class,
|
||||
HealthContributorAutoConfiguration.class))
|
||||
.withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL))
|
||||
HealthContributorAutoConfiguration.class, BeansEndpointAutoConfiguration.class,
|
||||
HealthEndpointAutoConfiguration.class, ShutdownEndpointAutoConfiguration.class))
|
||||
.withUserConfiguration(CustomMvcEndpoint.class, CustomServletEndpoint.class,
|
||||
HttpExchangeRepositoryConfiguration.class, AuditEventRepositoryConfiguration.class)
|
||||
.withPropertyValues("server.port:0");
|
||||
|
||||
@Test
|
||||
void webEndpointsAreDisabledByDefault() {
|
||||
void webEndpointsExceptHealthAreDisabledByDefault() {
|
||||
this.contextRunner.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
RestClient client = createClient(context);
|
||||
assertThat(isExposed(client, HttpMethod.GET, "beans")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "conditions")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "configprops")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "custommvc")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "customservlet")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "env")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "health")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "info")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "mappings")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.POST, "shutdown")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "threaddump")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "httpexchanges")).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -101,19 +93,10 @@ class WebMvcEndpointExposureIntegrationTests {
|
|||
WebApplicationContextRunner contextRunner = this.contextRunner
|
||||
.withPropertyValues("management.endpoints.web.exposure.include=*");
|
||||
contextRunner.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
RestClient client = createClient(context);
|
||||
assertThat(isExposed(client, HttpMethod.GET, "beans")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "conditions")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "configprops")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "custommvc")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "customservlet")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "env")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "health")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "info")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "mappings")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.POST, "shutdown")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "threaddump")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "httpexchanges")).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -122,68 +105,44 @@ class WebMvcEndpointExposureIntegrationTests {
|
|||
WebApplicationContextRunner contextRunner = this.contextRunner
|
||||
.withPropertyValues("management.endpoints.web.exposure.include=beans");
|
||||
contextRunner.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
RestClient client = createClient(context);
|
||||
assertThat(isExposed(client, HttpMethod.GET, "beans")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "conditions")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "configprops")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "custommvc")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "customservlet")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "env")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "health")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "info")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "mappings")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.POST, "shutdown")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "threaddump")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "httpexchanges")).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void singleWebEndpointCanBeExcluded() {
|
||||
WebApplicationContextRunner contextRunner = this.contextRunner.withPropertyValues(
|
||||
"management.endpoints.web.exposure.include=*", "management.endpoints.web.exposure.exclude=shutdown");
|
||||
"management.endpoints.web.exposure.include=*", "management.endpoints.web.exposure.exclude=beans");
|
||||
contextRunner.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
assertThat(isExposed(client, HttpMethod.GET, "beans")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "conditions")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "configprops")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "custommvc")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "customservlet")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "env")).isTrue();
|
||||
RestClient client = createClient(context);
|
||||
assertThat(isExposed(client, HttpMethod.GET, "beans")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "health")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "info")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "mappings")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.POST, "shutdown")).isFalse();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "threaddump")).isTrue();
|
||||
assertThat(isExposed(client, HttpMethod.GET, "httpexchanges")).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
private WebTestClient createClient(AssertableWebApplicationContext context) {
|
||||
private RestClient createClient(AssertableWebApplicationContext context) {
|
||||
int port = context.getSourceApplicationContext(ServletWebServerApplicationContext.class)
|
||||
.getWebServer()
|
||||
.getPort();
|
||||
ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder()
|
||||
.codecs((configurer) -> configurer.defaultCodecs().maxInMemorySize(-1))
|
||||
.build();
|
||||
return WebTestClient.bindToServer()
|
||||
.baseUrl("http://localhost:" + port)
|
||||
.exchangeStrategies(exchangeStrategies)
|
||||
.responseTimeout(Duration.ofMinutes(5))
|
||||
.build();
|
||||
return RestClient.builder().defaultStatusHandler((status) -> true, (request, response) -> {
|
||||
}).baseUrl("http://localhost:" + port).build();
|
||||
}
|
||||
|
||||
private boolean isExposed(WebTestClient client, HttpMethod method, String path) {
|
||||
private boolean isExposed(RestClient client, HttpMethod method, String path) {
|
||||
path = "/actuator/" + path;
|
||||
EntityExchangeResult<byte[]> result = client.method(method).uri(path).exchange().expectBody().returnResult();
|
||||
if (result.getStatus() == HttpStatus.OK) {
|
||||
ResponseEntity<byte[]> result = client.method(method).uri(path).retrieve().toEntity(byte[].class);
|
||||
if (result.getStatusCode() == HttpStatus.OK) {
|
||||
return true;
|
||||
}
|
||||
if (result.getStatus() == HttpStatus.NOT_FOUND) {
|
||||
if (result.getStatusCode() == HttpStatus.NOT_FOUND) {
|
||||
return false;
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
String.format("Unexpected %s HTTP status for endpoint %s", result.getStatus(), path));
|
||||
String.format("Unexpected %s HTTP status for endpoint %s", result.getStatusCode(), path));
|
||||
}
|
||||
|
||||
@org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "custommvc")
|
|
@ -14,12 +14,18 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.webmvc.actuate.autoconfigure.endpoint.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.audit.AuditAutoConfiguration;
|
||||
|
@ -27,13 +33,11 @@ import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoCon
|
|||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.jackson.EndpointObjectMapper;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.data.rest.autoconfigure.RepositoryRestMvcAutoConfiguration;
|
||||
import org.springframework.boot.hateoas.autoconfigure.HypermediaAutoConfiguration;
|
||||
import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration;
|
||||
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.servlet.actuate.autoconfigure.ServletManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext;
|
||||
|
@ -42,18 +46,12 @@ import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfig
|
|||
import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.test.context.TestSecurityContextHolder;
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcConfigurer;
|
||||
import org.springframework.web.util.pattern.PathPatternParser;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
||||
|
||||
/**
|
||||
* Integration tests for the Actuator's MVC endpoints.
|
||||
|
@ -64,12 +62,6 @@ class WebMvcEndpointIntegrationTests {
|
|||
|
||||
private AnnotationConfigServletWebApplicationContext context;
|
||||
|
||||
@AfterEach
|
||||
void close() {
|
||||
TestSecurityContextHolder.clearContext();
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void webMvcEndpointHandlerMappingIsConfiguredWithPathPatternParser() {
|
||||
this.context = new AnnotationConfigServletWebApplicationContext();
|
||||
|
@ -80,38 +72,6 @@ class WebMvcEndpointIntegrationTests {
|
|||
assertThat(handlerMapping.getPatternParser()).isInstanceOf(PathPatternParser.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void endpointsAreSecureByDefault() {
|
||||
this.context = new AnnotationConfigServletWebApplicationContext();
|
||||
this.context.register(SecureConfiguration.class);
|
||||
MockMvcTester mvc = createSecureMockMvcTester();
|
||||
assertThat(mvc.get().uri("/actuator/beans").accept(MediaType.APPLICATION_JSON))
|
||||
.hasStatus(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void endpointsAreSecureByDefaultWithCustomBasePath() {
|
||||
this.context = new AnnotationConfigServletWebApplicationContext();
|
||||
this.context.register(SecureConfiguration.class);
|
||||
TestPropertyValues.of("management.endpoints.web.base-path:/management").applyTo(this.context);
|
||||
MockMvcTester mvc = createSecureMockMvcTester();
|
||||
assertThat(mvc.get().uri("/management/beans").accept(MediaType.APPLICATION_JSON))
|
||||
.hasStatus(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void endpointsAreSecureWithActuatorRoleWithCustomBasePath() {
|
||||
TestSecurityContextHolder.getContext()
|
||||
.setAuthentication(new TestingAuthenticationToken("user", "N/A", "ROLE_ACTUATOR"));
|
||||
this.context = new AnnotationConfigServletWebApplicationContext();
|
||||
this.context.register(SecureConfiguration.class);
|
||||
TestPropertyValues
|
||||
.of("management.endpoints.web.base-path:/management", "management.endpoints.web.exposure.include=*")
|
||||
.applyTo(this.context);
|
||||
MockMvcTester mvc = createSecureMockMvcTester();
|
||||
assertThat(mvc.get().uri("/management/beans")).hasStatusOk();
|
||||
}
|
||||
|
||||
@Test
|
||||
void linksAreProvidedToAllEndpointTypes() {
|
||||
this.context = new AnnotationConfigServletWebApplicationContext();
|
||||
|
@ -143,19 +103,10 @@ class WebMvcEndpointIntegrationTests {
|
|||
assertThat(mvc.get().uri("/actuator/beans")).hasStatusOk().bodyText().contains("\"scope\":\"notelgnis\"");
|
||||
}
|
||||
|
||||
private MockMvcTester createSecureMockMvcTester() {
|
||||
return doCreateMockMvcTester(springSecurity());
|
||||
}
|
||||
|
||||
private MockMvcTester doCreateMockMvcTester(MockMvcConfigurer... configurers) {
|
||||
private MockMvcTester doCreateMockMvcTester() {
|
||||
this.context.setServletContext(new MockServletContext());
|
||||
this.context.refresh();
|
||||
return MockMvcTester.from(this.context, (builder) -> {
|
||||
for (MockMvcConfigurer configurer : configurers) {
|
||||
builder.apply(configurer);
|
||||
}
|
||||
return builder.build();
|
||||
});
|
||||
return MockMvcTester.from(this.context);
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
|
||||
|
@ -168,24 +119,6 @@ class WebMvcEndpointIntegrationTests {
|
|||
|
||||
}
|
||||
|
||||
@Import(SecureConfiguration.class)
|
||||
@ImportAutoConfiguration({ HypermediaAutoConfiguration.class })
|
||||
static class SpringHateoasConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Import(SecureConfiguration.class)
|
||||
@ImportAutoConfiguration({ HypermediaAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class })
|
||||
static class SpringDataRestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Import(DefaultConfiguration.class)
|
||||
@ImportAutoConfiguration({ SecurityAutoConfiguration.class })
|
||||
static class SecureConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint(id = "servlet")
|
||||
@SuppressWarnings({ "deprecation", "removal" })
|
||||
static class TestServletEndpoint
|
||||
|
@ -231,4 +164,49 @@ class WebMvcEndpointIntegrationTests {
|
|||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@SuppressWarnings({ "deprecation", "removal" })
|
||||
static class EndpointObjectMapperConfiguration {
|
||||
|
||||
@Bean
|
||||
EndpointObjectMapper endpointObjectMapper() {
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.addSerializer(String.class, new ReverseStringSerializer());
|
||||
ObjectMapper objectMapper = org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.json()
|
||||
.modules(module)
|
||||
.build();
|
||||
return () -> objectMapper;
|
||||
}
|
||||
|
||||
static class ReverseStringSerializer extends StdScalarSerializer<Object> {
|
||||
|
||||
ReverseStringSerializer() {
|
||||
super(String.class, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty(SerializerProvider prov, Object value) {
|
||||
return ((String) value).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
serialize(value, gen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider,
|
||||
TypeSerializer typeSer) throws IOException {
|
||||
serialize(value, gen);
|
||||
}
|
||||
|
||||
private void serialize(Object value, JsonGenerator gen) throws IOException {
|
||||
StringBuilder builder = new StringBuilder((String) value);
|
||||
gen.writeString(builder.reverse().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -14,11 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
package org.springframework.boot.webmvc.actuate.autoconfigure.endpoint.web;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.integrationtest.AbstractHealthEndpointAdditionalPathIntegrationTests;
|
||||
import org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
Loading…
Reference in New Issue