Commit a4b0be08 authored by Phillip Webb's avatar Phillip Webb

Polish

parent 220f8cdc
......@@ -59,11 +59,11 @@ public final class EndpointRequest {
}
/**
* Returns a matcher that includes all {@link Endpoint actuator endpoints}. It also includes
* the links endpoint which is present at the base path of the actuator endpoints. The
* {@link EndpointServerWebExchangeMatcher#excluding(Class...) excluding} method can
* be used to further remove specific endpoints if required. For example:
* <pre class="code">
* Returns a matcher that includes all {@link Endpoint actuator endpoints}. It also
* includes the links endpoint which is present at the base path of the actuator
* endpoints. The {@link EndpointServerWebExchangeMatcher#excluding(Class...)
* excluding} method can be used to further remove specific endpoints if required. For
* example: <pre class="code">
* EndpointRequest.toAnyEndpoint().excluding(ShutdownEndpoint.class)
* </pre>
* @return the configured {@link ServerWebExchangeMatcher}
......@@ -97,11 +97,13 @@ public final class EndpointRequest {
}
/**
* Returns a matcher that matches only on the links endpoint. It can be used when security configuration
* for the links endpoint is different from the other {@link Endpoint actuator endpoints}. The
* {@link EndpointServerWebExchangeMatcher#excludingLinks() excludingLinks} method can be used in combination with this
* to remove the links endpoint from {@link EndpointRequest#toAnyEndpoint() toAnyEndpoint}.
* For example: <pre class="code">
* Returns a matcher that matches only on the links endpoint. It can be used when
* security configuration for the links endpoint is different from the other
* {@link Endpoint actuator endpoints}. The
* {@link EndpointServerWebExchangeMatcher#excludingLinks() excludingLinks} method can
* be used in combination with this to remove the links endpoint from
* {@link EndpointRequest#toAnyEndpoint() toAnyEndpoint}. For example:
* <pre class="code">
* EndpointRequest.toLinks()
* </pre>
* @return the configured {@link ServerWebExchangeMatcher}
......@@ -121,20 +123,24 @@ public final class EndpointRequest {
private final List<Object> excludes;
private ServerWebExchangeMatcher delegate;
private final boolean includeLinks;
private boolean includeLinks;
private ServerWebExchangeMatcher delegate;
private EndpointServerWebExchangeMatcher(boolean includeLinks) {
this(Collections.emptyList(), Collections.emptyList(), includeLinks);
}
private EndpointServerWebExchangeMatcher(Class<?>[] endpoints, boolean includeLinks) {
this(Arrays.asList((Object[]) endpoints), Collections.emptyList(), includeLinks);
private EndpointServerWebExchangeMatcher(Class<?>[] endpoints,
boolean includeLinks) {
this(Arrays.asList((Object[]) endpoints), Collections.emptyList(),
includeLinks);
}
private EndpointServerWebExchangeMatcher(String[] endpoints, boolean includeLinks) {
this(Arrays.asList((Object[]) endpoints), Collections.emptyList(), includeLinks);
private EndpointServerWebExchangeMatcher(String[] endpoints,
boolean includeLinks) {
this(Arrays.asList((Object[]) endpoints), Collections.emptyList(),
includeLinks);
}
private EndpointServerWebExchangeMatcher(List<Object> includes,
......@@ -148,17 +154,20 @@ public final class EndpointRequest {
public EndpointServerWebExchangeMatcher excluding(Class<?>... endpoints) {
List<Object> excludes = new ArrayList<>(this.excludes);
excludes.addAll(Arrays.asList((Object[]) endpoints));
return new EndpointServerWebExchangeMatcher(this.includes, excludes, this.includeLinks);
return new EndpointServerWebExchangeMatcher(this.includes, excludes,
this.includeLinks);
}
public EndpointServerWebExchangeMatcher excluding(String... endpoints) {
List<Object> excludes = new ArrayList<>(this.excludes);
excludes.addAll(Arrays.asList((Object[]) endpoints));
return new EndpointServerWebExchangeMatcher(this.includes, excludes, this.includeLinks);
return new EndpointServerWebExchangeMatcher(this.includes, excludes,
this.includeLinks);
}
public EndpointServerWebExchangeMatcher excludingLinks() {
return new EndpointServerWebExchangeMatcher(this.includes, this.excludes, false);
return new EndpointServerWebExchangeMatcher(this.includes, this.excludes,
false);
}
@Override
......@@ -185,8 +194,10 @@ public final class EndpointRequest {
streamPaths(this.includes, pathMappedEndpoints).forEach(paths::add);
streamPaths(this.excludes, pathMappedEndpoints).forEach(paths::remove);
List<ServerWebExchangeMatcher> delegateMatchers = getDelegateMatchers(paths);
if (this.includeLinks && StringUtils.hasText(pathMappedEndpoints.getBasePath())) {
delegateMatchers.add(new PathPatternParserServerWebExchangeMatcher(pathMappedEndpoints.getBasePath()));
if (this.includeLinks
&& StringUtils.hasText(pathMappedEndpoints.getBasePath())) {
delegateMatchers.add(new PathPatternParserServerWebExchangeMatcher(
pathMappedEndpoints.getBasePath()));
}
return new OrServerWebExchangeMatcher(delegateMatchers);
}
......@@ -241,15 +252,17 @@ public final class EndpointRequest {
}
@Override
protected void initialized(Supplier<WebEndpointProperties> propertiesSupplier) {
WebEndpointProperties webEndpointProperties = propertiesSupplier.get();
if (StringUtils.hasText(webEndpointProperties.getBasePath())) {
this.delegate = new PathPatternParserServerWebExchangeMatcher(
webEndpointProperties.getBasePath());
protected void initialized(Supplier<WebEndpointProperties> properties) {
this.delegate = createDelegate(properties.get());
}
else {
this.delegate = EMPTY_MATCHER;
private ServerWebExchangeMatcher createDelegate(
WebEndpointProperties properties) {
if (StringUtils.hasText(properties.getBasePath())) {
return new PathPatternParserServerWebExchangeMatcher(
properties.getBasePath());
}
return EMPTY_MATCHER;
}
@Override
......
......@@ -57,10 +57,11 @@ public final class EndpointRequest {
}
/**
* Returns a matcher that includes all {@link Endpoint actuator endpoints}. It also includes
* the links endpoint which is present at the base path of the actuator endpoints. The
* {@link EndpointRequestMatcher#excluding(Class...) excluding} method can be used to
* further remove specific endpoints if required. For example: <pre class="code">
* Returns a matcher that includes all {@link Endpoint actuator endpoints}. It also
* includes the links endpoint which is present at the base path of the actuator
* endpoints. The {@link EndpointRequestMatcher#excluding(Class...) excluding} method
* can be used to further remove specific endpoints if required. For example:
* <pre class="code">
* EndpointRequest.toAnyEndpoint().excluding(ShutdownEndpoint.class)
* </pre>
* @return the configured {@link RequestMatcher}
......@@ -94,11 +95,13 @@ public final class EndpointRequest {
}
/**
* Returns a matcher that matches only on the links endpoint. It can be used when security configuration
* for the links endpoint is different from the other {@link Endpoint actuator endpoints}. The
* {@link EndpointRequestMatcher#excludingLinks() excludingLinks} method can be used in combination with this
* to remove the links endpoint from {@link EndpointRequest#toAnyEndpoint() toAnyEndpoint}.
* For example: <pre class="code">
* Returns a matcher that matches only on the links endpoint. It can be used when
* security configuration for the links endpoint is different from the other
* {@link Endpoint actuator endpoints}. The
* {@link EndpointRequestMatcher#excludingLinks() excludingLinks} method can be used
* in combination with this to remove the links endpoint from
* {@link EndpointRequest#toAnyEndpoint() toAnyEndpoint}. For example:
* <pre class="code">
* EndpointRequest.toLinks()
* </pre>
* @return the configured {@link RequestMatcher}
......@@ -126,14 +129,17 @@ public final class EndpointRequest {
}
private EndpointRequestMatcher(Class<?>[] endpoints, boolean includeLinks) {
this(Arrays.asList((Object[]) endpoints), Collections.emptyList(), includeLinks);
this(Arrays.asList((Object[]) endpoints), Collections.emptyList(),
includeLinks);
}
private EndpointRequestMatcher(String[] endpoints, boolean includeLinks) {
this(Arrays.asList((Object[]) endpoints), Collections.emptyList(), includeLinks);
this(Arrays.asList((Object[]) endpoints), Collections.emptyList(),
includeLinks);
}
private EndpointRequestMatcher(List<Object> includes, List<Object> excludes, boolean includeLinks) {
private EndpointRequestMatcher(List<Object> includes, List<Object> excludes,
boolean includeLinks) {
super(PathMappedEndpoints.class);
this.includes = includes;
this.excludes = excludes;
......@@ -179,8 +185,10 @@ public final class EndpointRequest {
streamPaths(this.includes, pathMappedEndpoints).forEach(paths::add);
streamPaths(this.excludes, pathMappedEndpoints).forEach(paths::remove);
List<RequestMatcher> delegateMatchers = getDelegateMatchers(paths);
if (this.includeLinks && StringUtils.hasText(pathMappedEndpoints.getBasePath())) {
delegateMatchers.add(new AntPathRequestMatcher(pathMappedEndpoints.getBasePath()));
if (this.includeLinks
&& StringUtils.hasText(pathMappedEndpoints.getBasePath())) {
delegateMatchers.add(
new AntPathRequestMatcher(pathMappedEndpoints.getBasePath()));
}
return new OrRequestMatcher(delegateMatchers);
}
......@@ -234,20 +242,23 @@ public final class EndpointRequest {
}
@Override
protected void initialized(Supplier<WebEndpointProperties> propertiesSupplier) {
WebEndpointProperties webEndpointProperties = propertiesSupplier.get();
if (StringUtils.hasText(webEndpointProperties.getBasePath())) {
this.delegate = new AntPathRequestMatcher(webEndpointProperties.getBasePath());
protected void initialized(Supplier<WebEndpointProperties> properties) {
this.delegate = createDelegate(properties.get());
}
else {
this.delegate = EMPTY_MATCHER;
private RequestMatcher createDelegate(WebEndpointProperties properties) {
if (StringUtils.hasText(properties.getBasePath())) {
return new AntPathRequestMatcher(properties.getBasePath());
}
return EMPTY_MATCHER;
}
@Override
protected boolean matches(HttpServletRequest request, Supplier<WebEndpointProperties> context) {
protected boolean matches(HttpServletRequest request,
Supplier<WebEndpointProperties> context) {
return this.delegate.matches(request);
}
}
}
......@@ -78,14 +78,16 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
public ExpectedException thrown = ExpectedException.none();
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class,
.withConfiguration(AutoConfigurations.of(
ReactiveSecurityAutoConfiguration.class,
ReactiveUserDetailsServiceAutoConfiguration.class,
WebFluxAutoConfiguration.class, JacksonAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
WebClientCustomizerConfig.class, WebClientAutoConfiguration.class,
ManagementContextAutoConfiguration.class, EndpointAutoConfiguration.class,
WebEndpointAutoConfiguration.class, HealthEndpointAutoConfiguration.class,
ManagementContextAutoConfiguration.class,
EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class,
HealthEndpointAutoConfiguration.class,
ReactiveCloudFoundryActuatorAutoConfiguration.class));
@After
......@@ -96,47 +98,54 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
@Test
public void cloudFoundryPlatformActive() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(
context);
EndpointMapping endpointMapping = (EndpointMapping) ReflectionTestUtils
.getField(handlerMapping, "endpointMapping");
assertThat(endpointMapping.getPath()).isEqualTo("/cloudfoundryapplication");
assertThat(endpointMapping.getPath())
.isEqualTo("/cloudfoundryapplication");
CorsConfiguration corsConfiguration = (CorsConfiguration) ReflectionTestUtils
.getField(handlerMapping, "corsConfiguration");
assertThat(corsConfiguration.getAllowedOrigins()).contains("*");
assertThat(corsConfiguration.getAllowedMethods()).containsAll(
Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name()));
assertThat(corsConfiguration.getAllowedHeaders()).containsAll(
Arrays.asList("Authorization", "X-Cf-App-Instance", "Content-Type"));
assertThat(corsConfiguration.getAllowedHeaders())
.containsAll(Arrays.asList("Authorization",
"X-Cf-App-Instance", "Content-Type"));
});
}
@Test
public void cloudfoundryapplicationProducesActuatorMediaType() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
WebTestClient webTestClient = WebTestClient.bindToApplicationContext(context)
.build();
webTestClient.get().uri("/cloudfoundryapplication").header("Content-Type",
ActuatorMediaType.V2_JSON + ";charset=UTF-8");
.run((context) -> {
WebTestClient webTestClient = WebTestClient
.bindToApplicationContext(context).build();
webTestClient.get().uri("/cloudfoundryapplication").header(
"Content-Type", ActuatorMediaType.V2_JSON + ";charset=UTF-8");
});
}
@Test
public void cloudFoundryPlatformActiveSetsApplicationId() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(
context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping,
"securityInterceptor");
String applicationId = (String) ReflectionTestUtils.getField(interceptor,
"applicationId");
String applicationId = (String) ReflectionTestUtils
.getField(interceptor, "applicationId");
assertThat(applicationId).isEqualTo("my-app-id");
});
}
......@@ -144,30 +153,32 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
@Test
public void cloudFoundryPlatformActiveSetsCloudControllerUrl() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(
context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping,
"securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
Object interceptorSecurityService = ReflectionTestUtils
.getField(interceptor, "cloudFoundrySecurityService");
String cloudControllerUrl = (String) ReflectionTestUtils
.getField(interceptorSecurityService, "cloudControllerUrl");
assertThat(cloudControllerUrl).isEqualTo("http://my-cloud-controller.com");
assertThat(cloudControllerUrl)
.isEqualTo("http://my-cloud-controller.com");
});
}
@Test
public void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id")
.run(context -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = context.getBean(
"cloudFoundryWebFluxEndpointHandlerMapping",
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id").run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = context
.getBean("cloudFoundryWebFluxEndpointHandlerMapping",
CloudFoundryWebFluxEndpointHandlerMapping.class);
Object securityInterceptor = ReflectionTestUtils.getField(handlerMapping,
"securityInterceptor");
Object securityInterceptor = ReflectionTestUtils
.getField(handlerMapping, "securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils
.getField(securityInterceptor, "cloudFoundrySecurityService");
assertThat(interceptorSecurityService).isNull();
......@@ -178,23 +189,25 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
@SuppressWarnings("unchecked")
public void cloudFoundryPathsIgnoredBySpringSecurity() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
WebFilterChainProxy chainProxy = context.getBean(WebFilterChainProxy.class);
.run((context) -> {
WebFilterChainProxy chainProxy = context
.getBean(WebFilterChainProxy.class);
List<SecurityWebFilterChain> filters = (List<SecurityWebFilterChain>) ReflectionTestUtils
.getField(chainProxy, "filters");
Boolean cfRequestMatches = filters.get(0).matches(MockServerWebExchange.from(
MockServerHttpRequest.get("/cloudfoundryapplication/my-path").build()))
Boolean cfRequestMatches = filters.get(0)
.matches(MockServerWebExchange.from(MockServerHttpRequest
.get("/cloudfoundryapplication/my-path").build()))
.block();
Boolean otherRequestMatches = filters.get(0)
.matches(MockServerWebExchange
.from(MockServerHttpRequest.get("/some-other-path").build()))
.matches(MockServerWebExchange.from(MockServerHttpRequest
.get("/some-other-path").build()))
.block();
assertThat(cfRequestMatches).isTrue();
assertThat(otherRequestMatches).isFalse();
otherRequestMatches = filters.get(1)
.matches(MockServerWebExchange
otherRequestMatches = filters.get(1).matches(MockServerWebExchange
.from(MockServerHttpRequest.get("/some-other-path").build()))
.block();
assertThat(otherRequestMatches).isTrue();
......@@ -204,29 +217,34 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
@Test
public void cloudFoundryPlatformInactive() {
this.contextRunner
.run(context -> assertThat(
this.contextRunner.run((context) -> assertThat(
context.containsBean("cloudFoundryWebFluxEndpointHandlerMapping"))
.isFalse());
}
@Test
public void cloudFoundryManagementEndpointsDisabled() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION=---", "management.cloudfoundry.enabled:false")
.run(context -> assertThat(context.containsBean("cloudFoundryWebFluxEndpointHandlerMapping"))
this.contextRunner
.withPropertyValues("VCAP_APPLICATION=---",
"management.cloudfoundry.enabled:false")
.run((context) -> assertThat(
context.containsBean("cloudFoundryWebFluxEndpointHandlerMapping"))
.isFalse());
}
@Test
public void allEndpointsAvailableUnderCloudFoundryWithoutEnablingWebIncludes() {
this.contextRunner.withUserConfiguration(TestConfiguration.class)
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping.getEndpoints();
List<String> endpointIds = endpoints.stream().map(ExposableEndpoint::getId)
.collect(Collectors.toList());
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(
context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping
.getEndpoints();
List<String> endpointIds = endpoints.stream()
.map(ExposableEndpoint::getId).collect(Collectors.toList());
assertThat(endpointIds).contains("test");
});
}
......@@ -234,72 +252,94 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
@Test
public void endpointPathCustomizationIsNotApplied() {
this.contextRunner.withUserConfiguration(TestConfiguration.class)
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping.getEndpoints();
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(
context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping
.getEndpoints();
ExposableWebEndpoint endpoint = endpoints.stream()
.filter((candidate) -> "test".equals(candidate.getId())).findFirst()
.get();
.filter((candidate) -> "test".equals(candidate.getId()))
.findFirst().get();
assertThat(endpoint.getOperations()).hasSize(1);
WebOperation operation = endpoint.getOperations().iterator().next();
assertThat(operation.getRequestPredicate().getPath()).isEqualTo("test");
assertThat(operation.getRequestPredicate().getPath())
.isEqualTo("test");
});
}
@Test
public void healthEndpointInvokerShouldBeCloudFoundryWebExtension() {
this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
this.contextRunner
.withConfiguration(
AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
Collection<ExposableWebEndpoint> endpoints = getHandlerMapping(context).getEndpoints();
.run((context) -> {
Collection<ExposableWebEndpoint> endpoints = getHandlerMapping(
context).getEndpoints();
ExposableWebEndpoint endpoint = endpoints.iterator().next();
WebOperation webOperation = endpoint.getOperations().iterator().next();
Object invoker = ReflectionTestUtils.getField(webOperation, "invoker");
WebOperation webOperation = endpoint.getOperations().iterator()
.next();
Object invoker = ReflectionTestUtils.getField(webOperation,
"invoker");
assertThat(ReflectionTestUtils.getField(invoker, "target"))
.isInstanceOf(CloudFoundryReactiveHealthEndpointWebExtension.class);
.isInstanceOf(
CloudFoundryReactiveHealthEndpointWebExtension.class);
});
}
@Test
public void skipSslValidation() {
this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
this.contextRunner
.withConfiguration(
AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com",
"management.cloudfoundry.skip-ssl-validation:true")
.run(context -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(
context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping,
"securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
Object interceptorSecurityService = ReflectionTestUtils
.getField(interceptor, "cloudFoundrySecurityService");
WebClient webClient = (WebClient) ReflectionTestUtils
.getField(interceptorSecurityService, "webClient");
webClient.get().uri("https://self-signed.badssl.com/").exchange().block();
webClient.get().uri("https://self-signed.badssl.com/").exchange()
.block();
});
}
@Test
public void sslValidationNotSkippedByDefault() {
this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
this.contextRunner
.withConfiguration(
AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(
context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping,
"securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
Object interceptorSecurityService = ReflectionTestUtils
.getField(interceptor, "cloudFoundrySecurityService");
WebClient webClient = (WebClient) ReflectionTestUtils
.getField(interceptorSecurityService, "webClient");
this.thrown.expectCause(instanceOf(SSLException.class));
webClient.get().uri("https://self-signed.badssl.com/").exchange().block();
webClient.get().uri("https://self-signed.badssl.com/").exchange()
.block();
});
}
private CloudFoundryWebFluxEndpointHandlerMapping getHandlerMapping(ApplicationContext context) {
private CloudFoundryWebFluxEndpointHandlerMapping getHandlerMapping(
ApplicationContext context) {
return context.getBean("cloudFoundryWebFluxEndpointHandlerMapping",
CloudFoundryWebFluxEndpointHandlerMapping.class);
}
......
......@@ -81,46 +81,54 @@ public class CloudFoundryActuatorAutoConfigurationTests {
@Test
public void cloudFoundryPlatformActive() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
.run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(
context);
EndpointMapping endpointMapping = (EndpointMapping) ReflectionTestUtils
.getField(handlerMapping, "endpointMapping");
assertThat(endpointMapping.getPath()).isEqualTo("/cloudfoundryapplication");
assertThat(endpointMapping.getPath())
.isEqualTo("/cloudfoundryapplication");
CorsConfiguration corsConfiguration = (CorsConfiguration) ReflectionTestUtils
.getField(handlerMapping, "corsConfiguration");
assertThat(corsConfiguration.getAllowedOrigins()).contains("*");
assertThat(corsConfiguration.getAllowedMethods()).containsAll(
Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name()));
assertThat(corsConfiguration.getAllowedHeaders()).containsAll(
Arrays.asList("Authorization", "X-Cf-App-Instance", "Content-Type"));
assertThat(corsConfiguration.getAllowedHeaders())
.containsAll(Arrays.asList("Authorization",
"X-Cf-App-Instance", "Content-Type"));
});
}
@Test
public void cloudfoundryapplicationProducesActuatorMediaType() throws Exception {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
.run((context) -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
mockMvc.perform(get("/cloudfoundryapplication")).andExpect(header()
.string("Content-Type", ActuatorMediaType.V2_JSON + ";charset=UTF-8"));
mockMvc.perform(get("/cloudfoundryapplication"))
.andExpect(header().string("Content-Type",
ActuatorMediaType.V2_JSON + ";charset=UTF-8"));
});
}
@Test
public void cloudFoundryPlatformActiveSetsApplicationId() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
.run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(
context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping,
"securityInterceptor");
String applicationId = (String) ReflectionTestUtils.getField(interceptor,
"applicationId");
String applicationId = (String) ReflectionTestUtils
.getField(interceptor, "applicationId");
assertThat(applicationId).isEqualTo("my-app-id");
});
}
......@@ -128,31 +136,37 @@ public class CloudFoundryActuatorAutoConfigurationTests {
@Test
public void cloudFoundryPlatformActiveSetsCloudControllerUrl() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
.run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(
context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping,
"securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
Object interceptorSecurityService = ReflectionTestUtils
.getField(interceptor, "cloudFoundrySecurityService");
String cloudControllerUrl = (String) ReflectionTestUtils
.getField(interceptorSecurityService, "cloudControllerUrl");
assertThat(cloudControllerUrl).isEqualTo("http://my-cloud-controller.com");
assertThat(cloudControllerUrl)
.isEqualTo("http://my-cloud-controller.com");
});
}
@Test
public void skipSslValidation() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com", "management.cloudfoundry.skip-ssl-validation:true")
.run(context -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com",
"management.cloudfoundry.skip-ssl-validation:true")
.run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(
context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping,
"securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
Object interceptorSecurityService = ReflectionTestUtils
.getField(interceptor, "cloudFoundrySecurityService");
RestTemplate restTemplate = (RestTemplate) ReflectionTestUtils
.getField(interceptorSecurityService, "restTemplate");
assertThat(restTemplate.getRequestFactory())
......@@ -162,12 +176,12 @@ public class CloudFoundryActuatorAutoConfigurationTests {
@Test
public void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id")
.run(context -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
Object securityInterceptor = ReflectionTestUtils.getField(handlerMapping,
"securityInterceptor");
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id").run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(
context);
Object securityInterceptor = ReflectionTestUtils
.getField(handlerMapping, "securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils
.getField(securityInterceptor, "cloudFoundrySecurityService");
assertThat(interceptorSecurityService).isNull();
......@@ -176,11 +190,12 @@ public class CloudFoundryActuatorAutoConfigurationTests {
@Test
public void cloudFoundryPathsIgnoredBySpringSecurity() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id")
.run(context -> {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id").run((context) -> {
FilterChainProxy securityFilterChain = (FilterChainProxy) context
.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN);
SecurityFilterChain chain = securityFilterChain.getFilterChains().get(0);
SecurityFilterChain chain = securityFilterChain.getFilterChains()
.get(0);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath("/cloudfoundryapplication/my-path");
assertThat(chain.getFilters()).isEmpty();
......@@ -193,73 +208,86 @@ public class CloudFoundryActuatorAutoConfigurationTests {
@Test
public void cloudFoundryPlatformInactive() {
this.contextRunner.withPropertyValues()
.run(context -> assertThat(
context.containsBean("cloudFoundryWebEndpointServletHandlerMapping"))
.run((context) -> assertThat(context
.containsBean("cloudFoundryWebEndpointServletHandlerMapping"))
.isFalse());
}
@Test
public void cloudFoundryManagementEndpointsDisabled() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION=---", "management.cloudfoundry.enabled:false")
.run(context -> assertThat(context.containsBean("cloudFoundryEndpointHandlerMapping"))
this.contextRunner
.withPropertyValues("VCAP_APPLICATION=---",
"management.cloudfoundry.enabled:false")
.run((context) -> assertThat(
context.containsBean("cloudFoundryEndpointHandlerMapping"))
.isFalse());
}
@Test
public void allEndpointsAvailableUnderCloudFoundryWithoutExposeAllOnWeb() {
this.contextRunner
.withUserConfiguration(TestConfiguration.class)
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
this.contextRunner.withUserConfiguration(TestConfiguration.class)
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.run(context -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping.getEndpoints();
.run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(
context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping
.getEndpoints();
assertThat(endpoints.stream()
.filter((candidate) -> "test".equals(candidate.getId())).findFirst())
.isNotEmpty();
.filter((candidate) -> "test".equals(candidate.getId()))
.findFirst()).isNotEmpty();
});
}
@Test
public void endpointPathCustomizationIsNotApplied() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com",
"management.endpoints.web.path-mapping.test=custom")
.withUserConfiguration(TestConfiguration.class)
.run(context -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping.getEndpoints();
.withUserConfiguration(TestConfiguration.class).run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(
context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping
.getEndpoints();
ExposableWebEndpoint endpoint = endpoints.stream()
.filter((candidate) -> "test".equals(candidate.getId())).findFirst()
.get();
.filter((candidate) -> "test".equals(candidate.getId()))
.findFirst().get();
Collection<WebOperation> operations = endpoint.getOperations();
assertThat(operations).hasSize(1);
assertThat(operations.iterator().next().getRequestPredicate().getPath())
assertThat(
operations.iterator().next().getRequestPredicate().getPath())
.isEqualTo("test");
});
}
@Test
public void healthEndpointInvokerShouldBeCloudFoundryWebExtension() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
.run(context -> {
.withConfiguration(
AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
.run((context) -> {
Collection<ExposableWebEndpoint> endpoints = context
.getBean("cloudFoundryWebEndpointServletHandlerMapping",
CloudFoundryWebEndpointServletHandlerMapping.class)
.getEndpoints();
ExposableWebEndpoint endpoint = endpoints.iterator().next();
WebOperation webOperation = endpoint.getOperations().iterator().next();
Object invoker = ReflectionTestUtils.getField(webOperation, "invoker");
WebOperation webOperation = endpoint.getOperations().iterator()
.next();
Object invoker = ReflectionTestUtils.getField(webOperation,
"invoker");
assertThat(ReflectionTestUtils.getField(invoker, "target"))
.isInstanceOf(CloudFoundryHealthEndpointWebExtension.class);
});
}
private CloudFoundryWebEndpointServletHandlerMapping getHandlerMapping(ApplicationContext context) {
private CloudFoundryWebEndpointServletHandlerMapping getHandlerMapping(
ApplicationContext context) {
return context.getBean("cloudFoundryWebEndpointServletHandlerMapping",
CloudFoundryWebEndpointServletHandlerMapping.class);
}
......
......@@ -150,7 +150,8 @@ public class EndpointRequestTests {
@Test
public void excludeLinksShouldNotMatchBasePath() {
ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks();
ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint()
.excludingLinks();
assertMatcher(matcher).doesNotMatch("/actuator");
assertMatcher(matcher).matches("/actuator/foo");
assertMatcher(matcher).matches("/actuator/bar");
......@@ -158,7 +159,8 @@ public class EndpointRequestTests {
@Test
public void excludeLinksShouldNotMatchBasePathIfEmptyAndExcluded() {
ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks();
ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint()
.excludingLinks();
RequestMatcherAssert assertMatcher = assertMatcher(matcher, "");
assertMatcher.doesNotMatch("/");
assertMatcher.matches("/foo");
......@@ -176,7 +178,8 @@ public class EndpointRequestTests {
return assertMatcher(matcher, mockPathMappedEndpoints("/actuator"));
}
private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher, String basePath) {
private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher,
String basePath) {
return assertMatcher(matcher, mockPathMappedEndpoints(basePath));
}
......@@ -200,7 +203,8 @@ public class EndpointRequestTests {
context.registerBean(WebEndpointProperties.class);
if (pathMappedEndpoints != null) {
context.registerBean(PathMappedEndpoints.class, () -> pathMappedEndpoints);
WebEndpointProperties properties = context.getBean(WebEndpointProperties.class);
WebEndpointProperties properties = context
.getBean(WebEndpointProperties.class);
if (!properties.getBasePath().equals(pathMappedEndpoints.getBasePath())) {
properties.setBasePath(pathMappedEndpoints.getBasePath());
}
......
......@@ -125,8 +125,8 @@ public class EndpointRequestTests {
@Test
public void excludeByClassShouldNotMatchLinksIfExcluded() {
RequestMatcher matcher = EndpointRequest.toAnyEndpoint()
.excludingLinks().excluding(FooEndpoint.class);
RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks()
.excluding(FooEndpoint.class);
assertMatcher(matcher).doesNotMatch("/actuator/foo");
assertMatcher(matcher).doesNotMatch("/actuator");
}
......@@ -141,8 +141,8 @@ public class EndpointRequestTests {
@Test
public void excludeByIdShouldNotMatchLinksIfExcluded() {
RequestMatcher matcher = EndpointRequest.toAnyEndpoint()
.excludingLinks().excluding("foo");
RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks()
.excluding("foo");
assertMatcher(matcher).doesNotMatch("/actuator/foo");
assertMatcher(matcher).doesNotMatch("/actuator");
}
......@@ -199,7 +199,8 @@ public class EndpointRequestTests {
context.registerBean(WebEndpointProperties.class);
if (pathMappedEndpoints != null) {
context.registerBean(PathMappedEndpoints.class, () -> pathMappedEndpoints);
WebEndpointProperties properties = context.getBean(WebEndpointProperties.class);
WebEndpointProperties properties = context
.getBean(WebEndpointProperties.class);
if (!properties.getBasePath().equals(pathMappedEndpoints.getBasePath())) {
properties.setBasePath(pathMappedEndpoints.getBasePath());
}
......
......@@ -95,7 +95,8 @@ public class RabbitAutoConfiguration {
@Bean
public CachingConnectionFactory rabbitConnectionFactory(
RabbitProperties properties,
ObjectProvider<ConnectionNameStrategy> connectionNameStrategy) throws Exception {
ObjectProvider<ConnectionNameStrategy> connectionNameStrategy)
throws Exception {
PropertyMapper map = PropertyMapper.get();
CachingConnectionFactory factory = new CachingConnectionFactory(
getRabbitConnectionFactoryBean(properties).getObject());
......
......@@ -91,9 +91,8 @@ class DataSourceInitializedPublisher implements BeanPostProcessor {
if (this.properties == null) {
return true; // better safe than sorry
}
Supplier<String> defaultDdlAuto = () ->
EmbeddedDatabaseConnection.isEmbedded(dataSource) ? "create-drop"
: "none";
Supplier<String> defaultDdlAuto = () -> EmbeddedDatabaseConnection
.isEmbedded(dataSource) ? "create-drop" : "none";
Map<String, Object> hibernate = this.properties
.getHibernateProperties(new HibernateSettings().ddlAuto(defaultDdlAuto));
if (hibernate.containsKey("hibernate.hbm2ddl.auto")) {
......
......@@ -168,7 +168,8 @@ public class RabbitAutoConfigurationTests {
DirectFieldAccessor dfa = new DirectFieldAccessor(connectionFactory);
Address[] addresses = (Address[]) dfa.getPropertyValue("addresses");
assertThat(addresses).hasSize(1);
com.rabbitmq.client.ConnectionFactory rcf = mock(com.rabbitmq.client.ConnectionFactory.class);
com.rabbitmq.client.ConnectionFactory rcf = mock(
com.rabbitmq.client.ConnectionFactory.class);
given(rcf.newConnection(isNull(), eq(addresses), anyString()))
.willReturn(mock(Connection.class));
dfa.setPropertyValue("rabbitConnectionFactory", rcf);
......@@ -787,7 +788,7 @@ public class RabbitAutoConfigurationTests {
@Bean
public ConnectionNameStrategy myConnectionNameStrategy() {
return c -> "test#" + this.counter.getAndIncrement();
return (connectionFactory) -> "test#" + this.counter.getAndIncrement();
}
}
......
......@@ -68,8 +68,8 @@ public class CustomHibernateJpaAutoConfigurationTests {
+ "org.hibernate.cfg.naming.ImprovedNamingStrategyDelegator")
.run((context) -> {
JpaProperties bean = context.getBean(JpaProperties.class);
Map<String, Object> hibernateProperties = bean.getHibernateProperties(
new HibernateSettings());
Map<String, Object> hibernateProperties = bean
.getHibernateProperties(new HibernateSettings());
assertThat(hibernateProperties.get("hibernate.ejb.naming_strategy"))
.isNull();
});
......
......@@ -29,7 +29,10 @@ import javax.sql.DataSource;
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.cfg.AvailableSettings;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
......@@ -57,6 +60,14 @@ public class JpaPropertiesTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withUserConfiguration(TestConfiguration.class);
@Mock
private Supplier<String> ddlAutoSupplier;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void noCustomNamingStrategy() {
this.contextRunner.run(assertJpaProperties((properties) -> {
......@@ -80,8 +91,7 @@ public class JpaPropertiesTests {
"spring.jpa.hibernate.naming.physical-strategy:com.example.Physical")
.run(assertJpaProperties((properties) -> {
Map<String, Object> hibernateProperties = properties
.getHibernateProperties(
new HibernateSettings());
.getHibernateProperties(new HibernateSettings());
assertThat(hibernateProperties).contains(
entry("hibernate.implicit_naming_strategy",
"com.example.Implicit"),
......@@ -97,9 +107,8 @@ public class JpaPropertiesTests {
this.contextRunner.run(assertJpaProperties((properties) -> {
ImplicitNamingStrategy implicitStrategy = mock(ImplicitNamingStrategy.class);
PhysicalNamingStrategy physicalStrategy = mock(PhysicalNamingStrategy.class);
Map<String, Object> hibernateProperties = properties
.getHibernateProperties(new HibernateSettings()
.implicitNamingStrategy(implicitStrategy)
Map<String, Object> hibernateProperties = properties.getHibernateProperties(
new HibernateSettings().implicitNamingStrategy(implicitStrategy)
.physicalNamingStrategy(physicalStrategy));
assertThat(hibernateProperties).contains(
entry("hibernate.implicit_naming_strategy", implicitStrategy),
......@@ -120,8 +129,7 @@ public class JpaPropertiesTests {
PhysicalNamingStrategy physicalStrategy = mock(
PhysicalNamingStrategy.class);
Map<String, Object> hibernateProperties = properties
.getHibernateProperties(
new HibernateSettings()
.getHibernateProperties(new HibernateSettings()
.implicitNamingStrategy(implicitStrategy)
.physicalNamingStrategy(physicalStrategy));
assertThat(hibernateProperties).contains(
......@@ -154,8 +162,7 @@ public class JpaPropertiesTests {
effectivePhysicalStrategy);
};
Map<String, Object> hibernateProperties = properties
.getHibernateProperties(
new HibernateSettings()
.getHibernateProperties(new HibernateSettings()
.implicitNamingStrategy(implicitStrategy)
.physicalNamingStrategy(physicalStrategy)
.hibernatePropertiesCustomizers(
......@@ -177,8 +184,7 @@ public class JpaPropertiesTests {
"spring.jpa.properties.hibernate.physical_naming_strategy:com.example.Physical")
.run(assertJpaProperties((properties) -> {
Map<String, Object> hibernateProperties = properties
.getHibernateProperties(
new HibernateSettings());
.getHibernateProperties(new HibernateSettings());
// You can override them as we don't provide any default
assertThat(hibernateProperties).contains(
entry("hibernate.implicit_naming_strategy",
......@@ -207,8 +213,7 @@ public class JpaPropertiesTests {
"spring.jpa.hibernate.use-new-id-generator-mappings:false")
.run(assertJpaProperties((properties) -> {
Map<String, Object> hibernateProperties = properties
.getHibernateProperties(
new HibernateSettings());
.getHibernateProperties(new HibernateSettings());
assertThat(hibernateProperties).containsEntry(
AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "false");
}));
......@@ -251,8 +256,7 @@ public class JpaPropertiesTests {
@Test
public void defaultDdlAutoIsNotInvokedIfPropertyIsSet() {
this.contextRunner
.withPropertyValues("spring.jpa.hibernate.ddl-auto=validate")
this.contextRunner.withPropertyValues("spring.jpa.hibernate.ddl-auto=validate")
.run(assertDefaultDdlAutoNotInvoked("validate"));
}
......@@ -266,13 +270,11 @@ public class JpaPropertiesTests {
private ContextConsumer<AssertableApplicationContext> assertDefaultDdlAutoNotInvoked(
String expectedDdlAuto) {
return assertJpaProperties((properties) -> {
Supplier<String> ddlAutoSupplier = mock(Supplier.class);
Map<String, Object> hibernateProperties = properties
.getHibernateProperties(new HibernateSettings()
.ddlAuto(ddlAutoSupplier));
assertThat(hibernateProperties).containsEntry(
"hibernate.hbm2ddl.auto", expectedDdlAuto);
verify(ddlAutoSupplier, never()).get();
Map<String, Object> hibernateProperties = properties.getHibernateProperties(
new HibernateSettings().ddlAuto(this.ddlAutoSupplier));
assertThat(hibernateProperties).containsEntry("hibernate.hbm2ddl.auto",
expectedDdlAuto);
verify(this.ddlAutoSupplier, never()).get();
});
}
......
......@@ -48,11 +48,11 @@ public class ResourcePropertiesBindingTests {
"spring.resources.static-locations[3]=classpath:/four",
"spring.resources.static-locations[4]=classpath:/five/",
"spring.resources.static-locations[5]=classpath:/six")
.run(assertResourceProperties((properties) ->
assertThat(properties.getStaticLocations()).contains(
"classpath:/one/", "classpath:/two/", "classpath:/three/",
"classpath:/four/", "classpath:/five/",
"classpath:/six/")));
.run(assertResourceProperties(
(properties) -> assertThat(properties.getStaticLocations())
.contains("classpath:/one/", "classpath:/two/",
"classpath:/three/", "classpath:/four/",
"classpath:/five/", "classpath:/six/")));
}
private ContextConsumer<AssertableApplicationContext> assertResourceProperties(
......
......@@ -90,8 +90,10 @@ public class ReactiveWebServerFactoryAutoConfigurationTests {
@Test
public void defaultWebServerIsTomcat() {
// Tomcat should be chosen over Netty if the Tomcat library is present.
this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class).run(
(context) -> assertThat(context.getBean(ReactiveWebServerFactory.class))
this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class)
.withPropertyValues("server.port=0")
.run((context) -> assertThat(
context.getBean(ReactiveWebServerFactory.class))
.isInstanceOf(TomcatReactiveWebServerFactory.class));
}
......
......@@ -812,12 +812,12 @@ public class WebMvcAutoConfigurationTests {
@Test
public void customConfigurerAppliedAfterAutoConfig() {
this.contextRunner
.withUserConfiguration(CustomConfigurer.class)
this.contextRunner.withUserConfiguration(CustomConfigurer.class)
.run((context) -> {
ContentNegotiationManager manager = context.getBean(ContentNegotiationManager.class);
assertThat(manager.getStrategies()).anyMatch(strategy ->
WebMvcAutoConfiguration.OptionalPathExtensionContentNegotiationStrategy.class
ContentNegotiationManager manager = context
.getBean(ContentNegotiationManager.class);
assertThat(manager.getStrategies()).anyMatch(
strategy -> WebMvcAutoConfiguration.OptionalPathExtensionContentNegotiationStrategy.class
.isAssignableFrom(strategy.getClass()));
});
}
......@@ -1106,6 +1106,7 @@ public class WebMvcAutoConfigurationTests {
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true);
}
}
}
......@@ -67,8 +67,10 @@ public class WelcomePageHandlerMappingTests {
public void isOrderedAtLowPriority() {
this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
.run((context) -> {
WelcomePageHandlerMapping handler = context.getBean(WelcomePageHandlerMapping.class);
assertThat(handler.getOrder()).isEqualTo(Ordered.LOWEST_PRECEDENCE - 1);
WelcomePageHandlerMapping handler = context
.getBean(WelcomePageHandlerMapping.class);
assertThat(handler.getOrder())
.isEqualTo(Ordered.LOWEST_PRECEDENCE - 1);
});
}
......
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 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.
......
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 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.
......
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 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.
......
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 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.
......
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 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.
......
......@@ -371,10 +371,11 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = compile(StaticAccessor.class);
assertThat(metadata)
.has(Metadata.withGroup("specific").fromSource(StaticAccessor.class));
assertThat(metadata).has(Metadata.withProperty("specific.counter",
Integer.class).fromSource(StaticAccessor.class).withDefaultValue(42));
assertThat(metadata).doesNotHave(Metadata.withProperty("specific.name",
String.class).fromSource(StaticAccessor.class));
assertThat(metadata).has(Metadata.withProperty("specific.counter", Integer.class)
.fromSource(StaticAccessor.class).withDefaultValue(42));
assertThat(metadata)
.doesNotHave(Metadata.withProperty("specific.name", String.class)
.fromSource(StaticAccessor.class));
assertThat(metadata.getItems()).hasSize(2);
}
......
......@@ -46,7 +46,6 @@ import org.springframework.core.env.Environment;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* A container object which Binds objects from one or more
......@@ -309,7 +308,7 @@ public class Binder {
private ConfigurationProperty findProperty(ConfigurationPropertyName name,
Context context) {
if (!StringUtils.hasText(name.toString())) {
if (name.isEmpty()) {
return null;
}
return context.streamSources()
......
......@@ -23,6 +23,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import org.springframework.beans.BeanUtils;
......@@ -126,22 +127,20 @@ class JavaBeanBinder implements BeanBinder {
}
private void addMethod(Method method) {
String name = method.getName();
int parameterCount = method.getParameterCount();
if (name.startsWith("get") && parameterCount == 0 && name.length() > 3) {
name = Introspector.decapitalize(name.substring(3));
this.properties.computeIfAbsent(name, this::getBeanProperty)
.addGetter(method);
}
else if (name.startsWith("is") && parameterCount == 0 && name.length() > 2) {
name = Introspector.decapitalize(name.substring(2));
this.properties.computeIfAbsent(name, this::getBeanProperty)
.addGetter(method);
}
else if (name.startsWith("set") && parameterCount == 1 && name.length() > 3) {
name = Introspector.decapitalize(name.substring(3));
this.properties.computeIfAbsent(name, this::getBeanProperty)
.addSetter(method);
addMethodIfPossible(method, "get", 0, BeanProperty::addGetter);
addMethodIfPossible(method, "is", 0, BeanProperty::addGetter);
addMethodIfPossible(method, "set", 1, BeanProperty::addSetter);
}
private void addMethodIfPossible(Method method, String prefix, int parameterCount,
BiConsumer<BeanProperty, Method> consumer) {
if (method.getParameterCount() == parameterCount
&& method.getName().startsWith(prefix)
&& method.getName().length() > prefix.length()) {
String propertyName = Introspector
.decapitalize(method.getName().substring(prefix.length()));
consumer.accept(this.properties.computeIfAbsent(propertyName,
this::getBeanProperty), method);
}
}
......
......@@ -24,13 +24,28 @@ import org.springframework.boot.context.properties.source.ConfigurationPropertyN
import org.springframework.core.convert.ConverterNotFoundException;
/**
* {@link BindHandler} that can be used to ignore top-level {@link ConverterNotFoundException}s.
* {@link BindHandler} that can be used to ignore top-level
* {@link ConverterNotFoundException}s.
*
* @author Madhura Bhave
* @since 2.0.0
*/
public class IgnoreTopLevelConverterNotFoundBindHandler extends AbstractBindHandler {
/**
* Create a new {@link IgnoreTopLevelConverterNotFoundBindHandler} instance.
*/
public IgnoreTopLevelConverterNotFoundBindHandler() {
}
/**
* Create a new {@link IgnoreTopLevelConverterNotFoundBindHandler} instance with a
* specific parent.
* @param parent the parent handler
*/
public IgnoreTopLevelConverterNotFoundBindHandler(BindHandler parent) {
}
@Override
public Object onFailure(ConfigurationPropertyName name, Bindable<?> target,
BindContext context, Exception error) throws Exception {
......@@ -41,5 +56,3 @@ public class IgnoreTopLevelConverterNotFoundBindHandler extends AbstractBindHand
}
}
......@@ -23,7 +23,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.validation.Validation;
......@@ -306,14 +305,13 @@ public class BinderTests {
}
@Test
@SuppressWarnings("unchecked")
public void bindWithEmptyPrefixShouldIgnorePropertiesWithEmptyName() {
Map<String, Object> source = new HashMap<>();
source.put("value", "hello");
source.put("", "bar");
Iterable<ConfigurationPropertySource> propertySources = ConfigurationPropertySources.from(
new MapPropertySource("test", source));
this.sources.addAll((Set) propertySources);
Iterable<ConfigurationPropertySource> propertySources = ConfigurationPropertySources
.from(new MapPropertySource("test", source));
propertySources.forEach(this.sources::add);
Bindable<JavaBean> target = Bindable.of(JavaBean.class);
JavaBean result = this.binder.bind("", target).get();
assertThat(result.getValue()).isEqualTo("hello");
......
......@@ -70,7 +70,8 @@ public class IgnoreTopLevelConverterNotFoundBindHandlerTests {
@Test
public void bindWhenTopLevelContextAndExceptionIgnorableShouldNotFail() {
this.binder.bind("example", Bindable.of(Example.class), new IgnoreTopLevelConverterNotFoundBindHandler());
this.binder.bind("example", Bindable.of(Example.class),
new IgnoreTopLevelConverterNotFoundBindHandler());
}
@Test
......@@ -79,7 +80,8 @@ public class IgnoreTopLevelConverterNotFoundBindHandlerTests {
source.put("example.foo", "1");
this.sources.add(source);
this.thrown.expectCause(instanceOf(IllegalStateException.class));
this.binder.bind("example", Bindable.of(Example.class), new IgnoreTopLevelConverterNotFoundBindHandler());
this.binder.bind("example", Bindable.of(Example.class),
new IgnoreTopLevelConverterNotFoundBindHandler());
}
@Test
......@@ -89,7 +91,8 @@ public class IgnoreTopLevelConverterNotFoundBindHandlerTests {
this.sources.add(source);
this.thrown.expect(BindException.class);
this.thrown.expectCause(instanceOf(ConverterNotFoundException.class));
this.binder.bind("example", Bindable.of(Example.class), new IgnoreTopLevelConverterNotFoundBindHandler());
this.binder.bind("example", Bindable.of(Example.class),
new IgnoreTopLevelConverterNotFoundBindHandler());
}
public static class Example {
......
......@@ -86,8 +86,7 @@ public class SampleActuatorCustomSecurityApplicationTests {
ResponseEntity<Object> entity = restTemplate().getForEntity("/actuator",
Object.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
entity = adminRestTemplate().getForEntity("/actuator",
Object.class);
entity = adminRestTemplate().getForEntity("/actuator", Object.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
}
......@@ -137,8 +136,8 @@ public class SampleActuatorCustomSecurityApplicationTests {
@Test
public void actuatorExcludedFromEndpointRequestMatcher() {
ResponseEntity<Object> entity = userRestTemplate().getForEntity("/actuator/mappings",
Object.class);
ResponseEntity<Object> entity = userRestTemplate()
.getForEntity("/actuator/mappings", Object.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
}
......
......@@ -95,8 +95,7 @@ public class SampleSecureWebFluxCustomSecurityTests {
@Test
public void actuatorLinksIsSecure() {
this.webClient.get().uri("/actuator").accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isUnauthorized();
.exchange().expectStatus().isUnauthorized();
this.webClient.get().uri("/actuator").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "basic " + getBasicAuthForAdmin()).exchange()
.expectStatus().isOk();
......@@ -118,7 +117,9 @@ public class SampleSecureWebFluxCustomSecurityTests {
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http.authorizeExchange().matchers(EndpointRequest.to("health", "info"))
.permitAll().matchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class))
.permitAll()
.matchers(EndpointRequest.toAnyEndpoint()
.excluding(MappingsEndpoint.class))
.hasRole("ACTUATOR")
.matchers(PathRequest.toStaticResources().atCommonLocations())
.permitAll().pathMatchers("/login").permitAll().anyExchange()
......
......@@ -44,7 +44,6 @@ public abstract class AbstractEmbeddedServletContainerIntegrationTests {
@Override
public void delete() {
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment