Merge branch '2.7.x' into 3.0.x

This commit is contained in:
Phillip Webb
2023-02-21 23:15:40 -08:00
1890 changed files with 27173 additions and 21952 deletions

View File

@@ -48,7 +48,7 @@ public abstract class OnEndpointElementCondition extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
AnnotationAttributes annotationAttributes = AnnotationAttributes
.fromMap(metadata.getAnnotationAttributes(this.annotationType.getName()));
.fromMap(metadata.getAnnotationAttributes(this.annotationType.getName()));
String endpointName = annotationAttributes.getString("value");
ConditionOutcome outcome = getEndpointOutcome(context, endpointName);
if (outcome != null) {
@@ -63,7 +63,7 @@ public abstract class OnEndpointElementCondition extends SpringBootCondition {
if (environment.containsProperty(enabledProperty)) {
boolean match = environment.getProperty(enabledProperty, Boolean.class, true);
return new ConditionOutcome(match, ConditionMessage.forCondition(this.annotationType)
.because(this.prefix + endpointName + ".enabled is " + match));
.because(this.prefix + endpointName + ".enabled is " + match));
}
return null;
}
@@ -79,9 +79,9 @@ public abstract class OnEndpointElementCondition extends SpringBootCondition {
*/
protected ConditionOutcome getDefaultOutcome(ConditionContext context, AnnotationAttributes annotationAttributes) {
boolean match = Boolean
.parseBoolean(context.getEnvironment().getProperty(this.prefix + "defaults.enabled", "true"));
.parseBoolean(context.getEnvironment().getProperty(this.prefix + "defaults.enabled", "true"));
return new ConditionOutcome(match, ConditionMessage.forCondition(this.annotationType)
.because(this.prefix + "defaults.enabled is considered " + match));
.because(this.prefix + "defaults.enabled is considered " + match));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -36,7 +36,7 @@ class AvailabilityProbesHealthEndpointGroupsPostProcessor implements HealthEndpo
AvailabilityProbesHealthEndpointGroupsPostProcessor(Environment environment) {
this.addAdditionalPaths = "true"
.equalsIgnoreCase(environment.getProperty("management.endpoint.health.probes.add-additional-paths"));
.equalsIgnoreCase(environment.getProperty("management.endpoint.health.probes.add-additional-paths"));
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -73,8 +73,11 @@ public class CloudFoundryWebEndpointDiscoverer extends WebEndpointDiscoverer {
}
private boolean isHealthEndpointExtension(Class<?> extensionBeanType) {
return MergedAnnotations.from(extensionBeanType).get(EndpointWebExtension.class)
.getValue("endpoint", Class.class).map(HealthEndpoint.class::isAssignableFrom).orElse(false);
return MergedAnnotations.from(extensionBeanType)
.get(EndpointWebExtension.class)
.getValue("endpoint", Class.class)
.map(HealthEndpoint.class::isAssignableFrom)
.orElse(false);
}
private boolean isCloudFoundryHealthEndpointExtension(Class<?> extensionBeanType) {
@@ -85,8 +88,8 @@ public class CloudFoundryWebEndpointDiscoverer extends WebEndpointDiscoverer {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.reflection().registerType(CloudFoundryEndpointFilter.class,
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
hints.reflection()
.registerType(CloudFoundryEndpointFilter.class, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -80,12 +80,12 @@ class CloudFoundrySecurityInterceptor {
try {
Token token = getToken(exchange.getRequest());
return this.tokenValidator.validate(token)
.then(this.cloudFoundrySecurityService.getAccessLevel(token.toString(), this.applicationId))
.filter((accessLevel) -> accessLevel.isAccessAllowed(id))
.switchIfEmpty(
Mono.error(new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied")))
.doOnSuccess((accessLevel) -> exchange.getAttributes().put("cloudFoundryAccessLevel", accessLevel))
.then();
.then(this.cloudFoundrySecurityService.getAccessLevel(token.toString(), this.applicationId))
.filter((accessLevel) -> accessLevel.isAccessAllowed(id))
.switchIfEmpty(
Mono.error(new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied")))
.doOnSuccess((accessLevel) -> exchange.getAttributes().put("cloudFoundryAccessLevel", accessLevel))
.then();
}
catch (CloudFoundryAuthorizationException ex) {
return Mono.error(ex);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -91,26 +91,26 @@ class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointH
public Publisher<ResponseEntity<Object>> links(ServerWebExchange exchange) {
ServerHttpRequest request = exchange.getRequest();
return CloudFoundryWebFluxEndpointHandlerMapping.this.securityInterceptor.preHandle(exchange, "")
.map((securityResponse) -> {
if (!securityResponse.getStatus().equals(HttpStatus.OK)) {
return new ResponseEntity<>(securityResponse.getStatus());
}
AccessLevel accessLevel = exchange.getAttribute(AccessLevel.REQUEST_ATTRIBUTE);
Map<String, Link> links = CloudFoundryWebFluxEndpointHandlerMapping.this.linksResolver
.resolveLinks(request.getURI().toString());
return new ResponseEntity<>(
Collections.singletonMap("_links", getAccessibleLinks(accessLevel, links)),
HttpStatus.OK);
});
.map((securityResponse) -> {
if (!securityResponse.getStatus().equals(HttpStatus.OK)) {
return new ResponseEntity<>(securityResponse.getStatus());
}
AccessLevel accessLevel = exchange.getAttribute(AccessLevel.REQUEST_ATTRIBUTE);
Map<String, Link> links = CloudFoundryWebFluxEndpointHandlerMapping.this.linksResolver
.resolveLinks(request.getURI().toString());
return new ResponseEntity<>(
Collections.singletonMap("_links", getAccessibleLinks(accessLevel, links)), HttpStatus.OK);
});
}
private Map<String, Link> getAccessibleLinks(AccessLevel accessLevel, Map<String, Link> links) {
if (accessLevel == null) {
return new LinkedHashMap<>();
}
return links.entrySet().stream()
.filter((entry) -> entry.getKey().equals("self") || accessLevel.isAccessAllowed(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return links.entrySet()
.stream()
.filter((entry) -> entry.getKey().equals("self") || accessLevel.isAccessAllowed(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
@Override
@@ -141,7 +141,7 @@ class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointH
@Override
public Mono<ResponseEntity<Object>> handle(ServerWebExchange exchange, Map<String, String> body) {
return this.securityInterceptor.preHandle(exchange, this.endpointId.toLowerCaseString())
.flatMap((securityResponse) -> flatMapResponse(exchange, body, securityResponse));
.flatMap((securityResponse) -> flatMapResponse(exchange, body, securityResponse));
}
private Mono<ResponseEntity<Object>> flatMapResponse(ServerWebExchange exchange, Map<String, String> body,

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -96,9 +96,9 @@ public class ReactiveCloudFoundryActuatorAutoConfiguration {
public CloudFoundryInfoEndpointWebExtension cloudFoundryInfoEndpointWebExtension(GitProperties properties,
ObjectProvider<InfoContributor> infoContributors) {
List<InfoContributor> contributors = infoContributors.orderedStream()
.map((infoContributor) -> (infoContributor instanceof GitInfoContributor)
? new GitInfoContributor(properties, InfoPropertiesInfoContributor.Mode.FULL) : infoContributor)
.toList();
.map((infoContributor) -> (infoContributor instanceof GitInfoContributor)
? new GitInfoContributor(properties, InfoPropertiesInfoContributor.Mode.FULL) : infoContributor)
.toList();
return new CloudFoundryInfoEndpointWebExtension(new InfoEndpoint(contributors));
}
@@ -143,8 +143,8 @@ public class ReactiveCloudFoundryActuatorAutoConfiguration {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL);
corsConfiguration.setAllowedMethods(Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name()));
corsConfiguration.setAllowedHeaders(
Arrays.asList(HttpHeaders.AUTHORIZATION, "X-Cf-App-Instance", HttpHeaders.CONTENT_TYPE));
corsConfiguration
.setAllowedHeaders(Arrays.asList(HttpHeaders.AUTHORIZATION, "X-Cf-App-Instance", HttpHeaders.CONTENT_TYPE));
return corsConfiguration;
}
@@ -171,7 +171,7 @@ public class ReactiveCloudFoundryActuatorAutoConfiguration {
private WebFilterChainProxy postProcess(WebFilterChainProxy existing) {
ServerWebExchangeMatcher cloudFoundryRequestMatcher = ServerWebExchangeMatchers
.pathMatchers("/cloudfoundryapplication/**");
.pathMatchers("/cloudfoundryapplication/**");
WebFilter noOpFilter = (exchange, chain) -> chain.filter(exchange);
MatcherSecurityWebFilterChain ignoredRequestFilterChain = new MatcherSecurityWebFilterChain(
cloudFoundryRequestMatcher, Collections.singletonList(noOpFilter));

View File

@@ -72,8 +72,9 @@ class ReactiveCloudFoundrySecurityService {
}
private Http11SslContextSpec createSslContextSpec() {
return Http11SslContextSpec.forClient().configure(
(builder) -> builder.sslProvider(SslProvider.JDK).trustManager(InsecureTrustManagerFactory.INSTANCE));
return Http11SslContextSpec.forClient()
.configure((builder) -> builder.sslProvider(SslProvider.JDK)
.trustManager(InsecureTrustManagerFactory.INSTANCE));
}
/**
@@ -85,8 +86,13 @@ class ReactiveCloudFoundrySecurityService {
*/
Mono<AccessLevel> getAccessLevel(String token, String applicationId) throws CloudFoundryAuthorizationException {
String uri = getPermissionsUri(applicationId);
return this.webClient.get().uri(uri).header("Authorization", "bearer " + token).retrieve().bodyToMono(Map.class)
.map(this::getAccessLevel).onErrorMap(this::mapError);
return this.webClient.get()
.uri(uri)
.header("Authorization", "bearer " + token)
.retrieve()
.bodyToMono(Map.class)
.map(this::getAccessLevel)
.onErrorMap(this::mapError);
}
private Throwable mapError(Throwable throwable) {
@@ -123,8 +129,10 @@ class ReactiveCloudFoundrySecurityService {
private Mono<? extends Map<String, String>> fetchTokenKeys(String url) {
RequestHeadersSpec<?> uri = this.webClient.get().uri(url + "/token_keys");
return uri.retrieve().bodyToMono(STRING_OBJECT_MAP).map(this::extractTokenKeys).onErrorMap(
((ex) -> new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, ex.getMessage())));
return uri.retrieve()
.bodyToMono(STRING_OBJECT_MAP)
.map(this::extractTokenKeys)
.onErrorMap(((ex) -> new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, ex.getMessage())));
}
private Map<String, String> extractTokenKeys(Map<String, Object> response) {
@@ -141,10 +149,14 @@ class ReactiveCloudFoundrySecurityService {
* @return the UAA url Mono
*/
Mono<String> getUaaUrl() {
this.uaaUrl = this.webClient.get().uri(this.cloudControllerUrl + "/info").retrieve().bodyToMono(Map.class)
.map((response) -> (String) response.get("token_endpoint")).cache()
.onErrorMap((ex) -> new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,
"Unable to fetch token keys from UAA."));
this.uaaUrl = this.webClient.get()
.uri(this.cloudControllerUrl + "/info")
.retrieve()
.bodyToMono(Map.class)
.map((response) -> (String) response.get("token_endpoint"))
.cache()
.onErrorMap((ex) -> new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,
"Unable to fetch token keys from UAA."));
return this.uaaUrl;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2023 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.
@@ -51,8 +51,10 @@ class ReactiveTokenValidator {
}
Mono<Void> validate(Token token) {
return validateAlgorithm(token).then(validateKeyIdAndSignature(token)).then(validateExpiry(token))
.then(validateIssuer(token)).then(validateAudience(token));
return validateAlgorithm(token).then(validateKeyIdAndSignature(token))
.then(validateExpiry(token))
.then(validateIssuer(token))
.then(validateAudience(token));
}
private Mono<Void> validateAlgorithm(Token token) {
@@ -70,9 +72,9 @@ class ReactiveTokenValidator {
private Mono<Void> validateKeyIdAndSignature(Token token) {
return getTokenKey(token).filter((tokenKey) -> hasValidSignature(token, tokenKey))
.switchIfEmpty(Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE,
"RSA Signature did not match content")))
.then();
.switchIfEmpty(Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE,
"RSA Signature did not match content")))
.then();
}
private Mono<String> getTokenKey(Token token) {
@@ -81,10 +83,12 @@ class ReactiveTokenValidator {
if (cached != null) {
return Mono.just(cached);
}
return this.securityService.fetchTokenKeys().doOnSuccess(this::cacheTokenKeys)
.filter((tokenKeys) -> tokenKeys.containsKey(keyId)).map((tokenKeys) -> tokenKeys.get(keyId))
.switchIfEmpty(Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_KEY_ID,
"Key Id present in token header does not match")));
return this.securityService.fetchTokenKeys()
.doOnSuccess(this::cacheTokenKeys)
.filter((tokenKeys) -> tokenKeys.containsKey(keyId))
.map((tokenKeys) -> tokenKeys.get(keyId))
.switchIfEmpty(Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_KEY_ID,
"Key Id present in token header does not match")));
}
private void cacheTokenKeys(Map<String, String> tokenKeys) {
@@ -122,11 +126,12 @@ class ReactiveTokenValidator {
}
private Mono<Void> validateIssuer(Token token) {
return this.securityService.getUaaUrl().map((uaaUrl) -> String.format("%s/oauth/token", uaaUrl))
.filter((issuerUri) -> issuerUri.equals(token.getIssuer()))
.switchIfEmpty(Mono.error(
new CloudFoundryAuthorizationException(Reason.INVALID_ISSUER, "Token issuer does not match")))
.then();
return this.securityService.getUaaUrl()
.map((uaaUrl) -> String.format("%s/oauth/token", uaaUrl))
.filter((issuerUri) -> issuerUri.equals(token.getIssuer()))
.switchIfEmpty(Mono
.error(new CloudFoundryAuthorizationException(Reason.INVALID_ISSUER, "Token issuer does not match")))
.then();
}
private Mono<Void> validateAudience(Token token) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -100,9 +100,9 @@ public class CloudFoundryActuatorAutoConfiguration {
public CloudFoundryInfoEndpointWebExtension cloudFoundryInfoEndpointWebExtension(GitProperties properties,
ObjectProvider<InfoContributor> infoContributors) {
List<InfoContributor> contributors = infoContributors.orderedStream()
.map((infoContributor) -> (infoContributor instanceof GitInfoContributor)
? new GitInfoContributor(properties, InfoPropertiesInfoContributor.Mode.FULL) : infoContributor)
.toList();
.map((infoContributor) -> (infoContributor instanceof GitInfoContributor)
? new GitInfoContributor(properties, InfoPropertiesInfoContributor.Mode.FULL) : infoContributor)
.toList();
return new CloudFoundryInfoEndpointWebExtension(new InfoEndpoint(contributors));
}
@@ -147,8 +147,8 @@ public class CloudFoundryActuatorAutoConfiguration {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL);
corsConfiguration.setAllowedMethods(Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name()));
corsConfiguration.setAllowedHeaders(
Arrays.asList(HttpHeaders.AUTHORIZATION, "X-Cf-App-Instance", HttpHeaders.CONTENT_TYPE));
corsConfiguration
.setAllowedHeaders(Arrays.asList(HttpHeaders.AUTHORIZATION, "X-Cf-App-Instance", HttpHeaders.CONTENT_TYPE));
return corsConfiguration;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -94,7 +94,7 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpoin
@Reflective
public Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
SecurityResponse securityResponse = CloudFoundryWebEndpointServletHandlerMapping.this.securityInterceptor
.preHandle(request, null);
.preHandle(request, null);
if (!securityResponse.getStatus().equals(HttpStatus.OK)) {
sendFailureResponse(response, securityResponse);
}
@@ -104,10 +104,11 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpoin
return Collections.singletonMap("_links", filteredLinks);
}
Map<String, Link> links = CloudFoundryWebEndpointServletHandlerMapping.this.linksResolver
.resolveLinks(request.getRequestURL().toString());
filteredLinks = links.entrySet().stream()
.filter((e) -> e.getKey().equals("self") || accessLevel.isAccessAllowed(e.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
.resolveLinks(request.getRequestURL().toString());
filteredLinks = links.entrySet()
.stream()
.filter((e) -> e.getKey().equals("self") || accessLevel.isAccessAllowed(e.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return Collections.singletonMap("_links", filteredLinks);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -68,7 +68,7 @@ class OnAvailableEndpointCondition extends SpringBootCondition {
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
MergedAnnotation<ConditionalOnAvailableEndpoint> conditionAnnotation = metadata.getAnnotations()
.get(ConditionalOnAvailableEndpoint.class);
.get(ConditionalOnAvailableEndpoint.class);
Class<?> target = getTarget(context, metadata, conditionAnnotation);
MergedAnnotation<Endpoint> endpointAnnotation = getEndpointAnnotation(target);
return getMatchOutcome(environment, conditionAnnotation, endpointAnnotation);
@@ -134,8 +134,8 @@ class OnAvailableEndpointCondition extends SpringBootCondition {
}
Boolean userDefinedDefault = isEnabledByDefault(environment);
if (userDefinedDefault != null) {
return new ConditionOutcome(userDefinedDefault, message.because(
"no property " + key + " found so using user defined default from " + ENABLED_BY_DEFAULT_KEY));
return new ConditionOutcome(userDefinedDefault, message
.because("no property " + key + " found so using user defined default from " + ENABLED_BY_DEFAULT_KEY));
}
boolean endpointDefault = endpointAnnotation.getBoolean("enableByDefault");
return new ConditionOutcome(endpointDefault,

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -45,9 +45,10 @@ public class JacksonEndpointAutoConfiguration {
@ConditionalOnClass({ ObjectMapper.class, Jackson2ObjectMapperBuilder.class })
public EndpointObjectMapper endpointObjectMapper() {
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json()
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS)
.serializationInclusion(Include.NON_NULL).build();
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS)
.serializationInclusion(Include.NON_NULL)
.build();
return () -> objectMapper;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -89,7 +89,7 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory {
}
StringBuilder builder = new StringBuilder();
this.properties.getStaticNames()
.forEach((name, value) -> builder.append(",").append(name).append("=").append(value));
.forEach((name, value) -> builder.append(",").append(name).append("=").append(value));
return builder.toString();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -101,7 +101,9 @@ class JerseyWebEndpointManagementContextConfiguration {
WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups healthEndpointGroups) {
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
ExposableWebEndpoint health = webEndpoints.stream()
.filter((endpoint) -> endpoint.getEndpointId().equals(HEALTH_ENDPOINT_ID)).findFirst().get();
.filter((endpoint) -> endpoint.getEndpointId().equals(HEALTH_ENDPOINT_ID))
.findFirst()
.get();
return new JerseyAdditionalHealthEndpointPathsManagementResourcesRegistrar(health, healthEndpointGroups);
}
@@ -195,8 +197,10 @@ class JerseyWebEndpointManagementContextConfiguration {
JerseyHealthEndpointAdditionalPathResourceFactory resourceFactory = new JerseyHealthEndpointAdditionalPathResourceFactory(
WebServerNamespace.MANAGEMENT, this.groups);
Collection<Resource> endpointResources = resourceFactory
.createEndpointResources(mapping, Collections.singletonList(this.endpoint), null, null, false)
.stream().filter(Objects::nonNull).toList();
.createEndpointResources(mapping, Collections.singletonList(this.endpoint), null, null, false)
.stream()
.filter(Objects::nonNull)
.toList();
register(endpointResources, config);
}

View File

@@ -118,7 +118,9 @@ public class WebFluxEndpointManagementContextConfiguration {
WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) {
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
ExposableWebEndpoint health = webEndpoints.stream()
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID)).findFirst().get();
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID))
.findFirst()
.get();
return new AdditionalHealthEndpointPathsWebFluxHandlerMapping(new EndpointMapping(""), health,
groups.getAllWithAdditionalPath(WebServerNamespace.MANAGEMENT));
}
@@ -149,7 +151,7 @@ public class WebFluxEndpointManagementContextConfiguration {
static class ServerCodecConfigurerEndpointObjectMapperBeanPostProcessor implements BeanPostProcessor {
private static final List<MediaType> MEDIA_TYPES = Collections
.unmodifiableList(Arrays.asList(MediaType.APPLICATION_JSON, new MediaType("application", "*+json")));
.unmodifiableList(Arrays.asList(MediaType.APPLICATION_JSON, new MediaType("application", "*+json")));
private final Supplier<EndpointObjectMapper> endpointObjectMapper;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -113,7 +113,9 @@ public class WebMvcEndpointManagementContextConfiguration {
WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) {
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
ExposableWebEndpoint health = webEndpoints.stream()
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID)).findFirst().get();
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID))
.findFirst()
.get();
return new AdditionalHealthEndpointPathsWebMvcHandlerMapping(health,
groups.getAllWithAdditionalPath(WebServerNamespace.MANAGEMENT));
}
@@ -144,7 +146,7 @@ public class WebMvcEndpointManagementContextConfiguration {
static class EndpointObjectMapperWebMvcConfigurer implements WebMvcConfigurer {
private static final List<MediaType> MEDIA_TYPES = Collections
.unmodifiableList(Arrays.asList(MediaType.APPLICATION_JSON, new MediaType("application", "*+json")));
.unmodifiableList(Arrays.asList(MediaType.APPLICATION_JSON, new MediaType("application", "*+json")));
private final EndpointObjectMapper endpointObjectMapper;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -93,7 +93,7 @@ public abstract class AbstractCompositeHealthContributorConfiguration<C, I exten
}
catch (Exception ex) {
throw new IllegalStateException("Unable to create health indicator %s for bean type %s"
.formatted(this.indicatorType, this.beanType), ex);
.formatted(this.indicatorType, this.beanType), ex);
}
}

View File

@@ -120,7 +120,7 @@ class HealthEndpointConfiguration {
private Object applyPostProcessors(HealthEndpointGroups bean) {
for (HealthEndpointGroupsPostProcessor postProcessor : this.postProcessors.orderedStream()
.toArray(HealthEndpointGroupsPostProcessor[]::new)) {
.toArray(HealthEndpointGroupsPostProcessor[]::new)) {
bean = postProcessor.postProcessHealthEndpointGroups(bean);
}
return bean;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -68,7 +68,9 @@ class HealthEndpointReactiveWebExtensionConfiguration {
WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) {
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
ExposableWebEndpoint health = webEndpoints.stream()
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID)).findFirst().get();
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID))
.findFirst()
.get();
return new AdditionalHealthEndpointPathsWebFluxHandlerMapping(new EndpointMapping(""), health,
groups.getAllWithAdditionalPath(WebServerNamespace.SERVER));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -78,8 +78,10 @@ class HealthEndpointWebExtensionConfiguration {
private static ExposableWebEndpoint getHealthEndpoint(WebEndpointsSupplier webEndpointsSupplier) {
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
return webEndpoints.stream().filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID))
.findFirst().get();
return webEndpoints.stream()
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID))
.findFirst()
.get();
}
@ConditionalOnBean(DispatcherServlet.class)
@@ -160,8 +162,10 @@ class HealthEndpointWebExtensionConfiguration {
JerseyHealthEndpointAdditionalPathResourceFactory resourceFactory = new JerseyHealthEndpointAdditionalPathResourceFactory(
WebServerNamespace.SERVER, this.groups);
Collection<Resource> endpointResources = resourceFactory
.createEndpointResources(mapping, Collections.singletonList(this.endpoint), null, null, false)
.stream().filter(Objects::nonNull).toList();
.createEndpointResources(mapping, Collections.singletonList(this.endpoint), null, null, false)
.stream()
.filter(Objects::nonNull)
.toList();
register(endpointResources, config);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -39,7 +39,7 @@ class OnEnabledInfoContributorCondition extends OnEndpointElementCondition {
InfoContributorFallback fallback = annotationAttributes.getEnum("fallback");
if (fallback == InfoContributorFallback.DISABLE) {
return new ConditionOutcome(false, ConditionMessage.forCondition(ConditionalOnEnabledInfoContributor.class)
.because("management.info." + annotationAttributes.getString("value") + ".enabled is not true"));
.because("management.info." + annotationAttributes.getString("value") + ".enabled is not true"));
}
return super.getDefaultOutcome(context, annotationAttributes);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -86,9 +86,10 @@ public class DataSourceHealthContributorAutoConfiguration implements Initializin
public HealthContributor dbHealthContributor(Map<String, DataSource> dataSources,
DataSourceHealthIndicatorProperties dataSourceHealthIndicatorProperties) {
if (dataSourceHealthIndicatorProperties.isIgnoreRoutingDataSources()) {
Map<String, DataSource> filteredDatasources = dataSources.entrySet().stream()
.filter((e) -> !(e.getValue() instanceof AbstractRoutingDataSource))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Map<String, DataSource> filteredDatasources = dataSources.entrySet()
.stream()
.filter((e) -> !(e.getValue() instanceof AbstractRoutingDataSource))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return createContributor(filteredDatasources);
}
return createContributor(dataSources);
@@ -127,9 +128,11 @@ public class DataSourceHealthContributorAutoConfiguration implements Initializin
RoutingDataSourceHealthContributor(AbstractRoutingDataSource routingDataSource,
Function<DataSource, HealthContributor> contributorFunction) {
Map<String, DataSource> routedDataSources = routingDataSource.getResolvedDataSources().entrySet().stream()
.collect(Collectors.toMap((e) -> Objects.toString(e.getKey(), UNNAMED_DATASOURCE_KEY),
Map.Entry::getValue));
Map<String, DataSource> routedDataSources = routingDataSource.getResolvedDataSources()
.entrySet()
.stream()
.collect(Collectors.toMap((e) -> Objects.toString(e.getKey(), UNNAMED_DATASOURCE_KEY),
Map.Entry::getValue));
this.delegate = CompositeHealthContributor.fromMap(routedDataSources, contributorFunction);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -59,8 +59,8 @@ public class LoggersEndpointAutoConfiguration {
ConditionMessage.Builder message = ConditionMessage.forCondition("Logging System");
String loggingSystem = System.getProperty(LoggingSystem.SYSTEM_PROPERTY);
if (LoggingSystem.NONE.equals(loggingSystem)) {
return ConditionOutcome.noMatch(
message.because("system property " + LoggingSystem.SYSTEM_PROPERTY + " is set to none"));
return ConditionOutcome
.noMatch(message.because("system property " + LoggingSystem.SYSTEM_PROPERTY + " is set to none"));
}
return ConditionOutcome.match(message.because("enabled"));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -60,14 +60,14 @@ public class Log4J2MetricsAutoConfiguration {
try {
if (Class.forName("org.apache.logging.log4j.core.LoggerContext").isInstance(loggerContext)) {
return ConditionOutcome
.match("LoggerContext was an instance of org.apache.logging.log4j.core.LoggerContext");
.match("LoggerContext was an instance of org.apache.logging.log4j.core.LoggerContext");
}
}
catch (Throwable ex) {
// Continue with no match
}
return ConditionOutcome
.noMatch("Logger context was not an instance of org.apache.logging.log4j.core.LoggerContext");
.noMatch("Logger context was not an instance of org.apache.logging.log4j.core.LoggerContext");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -108,8 +108,8 @@ class MeterRegistryPostProcessor implements BeanPostProcessor, SmartInitializing
private void applyCustomizers(MeterRegistry meterRegistry) {
List<MeterRegistryCustomizer<?>> customizers = this.customizers.orderedStream().toList();
LambdaSafe.callbacks(MeterRegistryCustomizer.class, customizers, meterRegistry)
.withLogger(MeterRegistryPostProcessor.class)
.invoke((customizer) -> customizer.customize(meterRegistry));
.withLogger(MeterRegistryPostProcessor.class)
.invoke((customizer) -> customizer.customize(meterRegistry));
}
private void applyFilters(MeterRegistry meterRegistry) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -42,7 +42,7 @@ public class PropertiesAutoTimer implements AutoTimer {
@Override
public void apply(Builder builder) {
builder.publishPercentileHistogram(this.properties.isPercentilesHistogram())
.publishPercentiles(this.properties.getPercentiles());
.publishPercentiles(this.properties.getPercentiles());
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -84,24 +84,29 @@ public class PropertiesMeterFilter implements MeterFilter {
public DistributionStatisticConfig configure(Meter.Id id, DistributionStatisticConfig config) {
Distribution distribution = this.properties.getDistribution();
return DistributionStatisticConfig.builder()
.percentilesHistogram(lookupWithFallbackToAll(distribution.getPercentilesHistogram(), id, null))
.percentiles(lookupWithFallbackToAll(distribution.getPercentiles(), id, null))
.serviceLevelObjectives(
convertServiceLevelObjectives(id.getType(), lookup(distribution.getSlo(), id, null)))
.minimumExpectedValue(
convertMeterValue(id.getType(), lookup(distribution.getMinimumExpectedValue(), id, null)))
.maximumExpectedValue(
convertMeterValue(id.getType(), lookup(distribution.getMaximumExpectedValue(), id, null)))
.expiry(lookupWithFallbackToAll(distribution.getExpiry(), id, null))
.bufferLength(lookupWithFallbackToAll(distribution.getBufferLength(), id, null)).build().merge(config);
.percentilesHistogram(lookupWithFallbackToAll(distribution.getPercentilesHistogram(), id, null))
.percentiles(lookupWithFallbackToAll(distribution.getPercentiles(), id, null))
.serviceLevelObjectives(
convertServiceLevelObjectives(id.getType(), lookup(distribution.getSlo(), id, null)))
.minimumExpectedValue(
convertMeterValue(id.getType(), lookup(distribution.getMinimumExpectedValue(), id, null)))
.maximumExpectedValue(
convertMeterValue(id.getType(), lookup(distribution.getMaximumExpectedValue(), id, null)))
.expiry(lookupWithFallbackToAll(distribution.getExpiry(), id, null))
.bufferLength(lookupWithFallbackToAll(distribution.getBufferLength(), id, null))
.build()
.merge(config);
}
private double[] convertServiceLevelObjectives(Meter.Type meterType, ServiceLevelObjectiveBoundary[] slo) {
if (slo == null) {
return null;
}
double[] converted = Arrays.stream(slo).map((candidate) -> candidate.getValue(meterType))
.filter(Objects::nonNull).mapToDouble(Double::doubleValue).toArray();
double[] converted = Arrays.stream(slo)
.map((candidate) -> candidate.getValue(meterType))
.filter(Objects::nonNull)
.mapToDouble(Double::doubleValue)
.toArray();
return (converted.length != 0) ? converted : null;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -68,7 +68,7 @@ class CacheMetricsRegistrarConfiguration {
private void bindCacheManagerToRegistry(String beanName, CacheManager cacheManager) {
cacheManager.getCacheNames()
.forEach((cacheName) -> bindCacheToRegistry(beanName, cacheManager.getCache(cacheName)));
.forEach((cacheName) -> bindCacheToRegistry(beanName, cacheManager.getCache(cacheName)));
}
private void bindCacheToRegistry(String beanName, Cache cache) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -40,7 +40,7 @@ class OnMetricsExportEnabledCondition extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
AnnotationAttributes annotationAttributes = AnnotationAttributes
.fromMap(metadata.getAnnotationAttributes(ConditionalOnEnabledMetricsExport.class.getName()));
.fromMap(metadata.getAnnotationAttributes(ConditionalOnEnabledMetricsExport.class.getName()));
String endpointName = annotationAttributes.getString("value");
ConditionOutcome outcome = getProductOutcome(context, endpointName);
if (outcome != null) {
@@ -55,7 +55,7 @@ class OnMetricsExportEnabledCondition extends SpringBootCondition {
if (environment.containsProperty(enabledProperty)) {
boolean match = environment.getProperty(enabledProperty, Boolean.class, true);
return new ConditionOutcome(match, ConditionMessage.forCondition(ConditionalOnEnabledMetricsExport.class)
.because(enabledProperty + " is " + match));
.because(enabledProperty + " is " + match));
}
return null;
}
@@ -70,7 +70,7 @@ class OnMetricsExportEnabledCondition extends SpringBootCondition {
private ConditionOutcome getDefaultOutcome(ConditionContext context) {
boolean match = Boolean.parseBoolean(context.getEnvironment().getProperty(DEFAULT_PROPERTY_NAME, "true"));
return new ConditionOutcome(match, ConditionMessage.forCondition(ConditionalOnEnabledMetricsExport.class)
.because(DEFAULT_PROPERTY_NAME + " is considered " + match));
.because(DEFAULT_PROPERTY_NAME + " is considered " + match));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -64,9 +64,11 @@ public class AppOpticsMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public AppOpticsMeterRegistry appOpticsMeterRegistry(AppOpticsConfig config, Clock clock) {
return AppOpticsMeterRegistry.builder(config).clock(clock).httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
return AppOpticsMeterRegistry.builder(config)
.clock(clock)
.httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -64,9 +64,11 @@ public class DatadogMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public DatadogMeterRegistry datadogMeterRegistry(DatadogConfig datadogConfig, Clock clock) {
return DatadogMeterRegistry.builder(datadogConfig).clock(clock).httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
return DatadogMeterRegistry.builder(datadogConfig)
.clock(clock)
.httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -64,9 +64,11 @@ public class DynatraceMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public DynatraceMeterRegistry dynatraceMeterRegistry(DynatraceConfig dynatraceConfig, Clock clock) {
return DynatraceMeterRegistry.builder(dynatraceConfig).clock(clock).httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
return DynatraceMeterRegistry.builder(dynatraceConfig)
.clock(clock)
.httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -73,9 +73,11 @@ public class ElasticMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public ElasticMeterRegistry elasticMeterRegistry(ElasticConfig elasticConfig, Clock clock) {
return ElasticMeterRegistry.builder(elasticConfig).clock(clock).httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
return ElasticMeterRegistry.builder(elasticConfig)
.clock(clock)
.httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -64,9 +64,11 @@ public class HumioMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public HumioMeterRegistry humioMeterRegistry(HumioConfig humioConfig, Clock clock) {
return HumioMeterRegistry.builder(humioConfig).clock(clock).httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
return HumioMeterRegistry.builder(humioConfig)
.clock(clock)
.httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -64,9 +64,11 @@ public class InfluxMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public InfluxMeterRegistry influxMeterRegistry(InfluxConfig influxConfig, Clock clock) {
return InfluxMeterRegistry.builder(influxConfig).clock(clock).httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
return InfluxMeterRegistry.builder(influxConfig)
.clock(clock)
.httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -64,9 +64,11 @@ public class KairosMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public KairosMeterRegistry kairosMeterRegistry(KairosConfig kairosConfig, Clock clock) {
return KairosMeterRegistry.builder(kairosConfig).clock(clock).httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
return KairosMeterRegistry.builder(kairosConfig)
.clock(clock)
.httpClient(
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
.build();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -81,8 +81,10 @@ public class NewRelicMetricsExportAutoConfiguration {
@ConditionalOnMissingBean
public NewRelicMeterRegistry newRelicMeterRegistry(NewRelicConfig newRelicConfig, Clock clock,
NewRelicClientProvider newRelicClientProvider) {
return NewRelicMeterRegistry.builder(newRelicConfig).clock(clock).clientProvider(newRelicClientProvider)
.build();
return NewRelicMeterRegistry.builder(newRelicConfig)
.clock(clock)
.clientProvider(newRelicClientProvider)
.build();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -95,7 +95,7 @@ public class DataSourcePoolMetricsAutoConfiguration {
Collection<DataSourcePoolMetadataProvider> metadataProviders, MeterRegistry registry) {
String dataSourceName = getDataSourceName(beanName);
new DataSourcePoolMetrics(dataSource, metadataProviders, dataSourceName, Collections.emptyList())
.bindTo(registry);
.bindTo(registry);
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -98,8 +98,8 @@ public class MongoMetricsAutoConfiguration {
MongoClientSettingsBuilderCustomizer mongoMetricsConnectionPoolListenerClientSettingsBuilderCustomizer(
MongoMetricsConnectionPoolListener mongoMetricsConnectionPoolListener) {
return (clientSettingsBuilder) -> clientSettingsBuilder
.applyToConnectionPoolSettings((connectionPoolSettingsBuilder) -> connectionPoolSettingsBuilder
.addConnectionPoolListener(mongoMetricsConnectionPoolListener));
.applyToConnectionPoolSettings((connectionPoolSettingsBuilder) -> connectionPoolSettingsBuilder
.addConnectionPoolListener(mongoMetricsConnectionPoolListener));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -78,7 +78,8 @@ public class HibernateMetricsAutoConfiguration implements SmartInitializingSingl
String entityManagerFactoryName = getEntityManagerFactoryName(beanName);
try {
new HibernateMetrics(entityManagerFactory.unwrap(SessionFactory.class), entityManagerFactoryName,
Collections.emptyList()).bindTo(registry);
Collections.emptyList())
.bindTo(registry);
}
catch (PersistenceException ex) {
// Continue

View File

@@ -93,7 +93,8 @@ class ObservationRegistryConfigurer {
@SuppressWarnings("unchecked")
private void customize(ObservationRegistry registry) {
LambdaSafe.callbacks(ObservationRegistryCustomizer.class, asOrderedList(this.customizers), registry)
.withLogger(ObservationRegistryConfigurer.class).invoke((customizer) -> customizer.customize(registry));
.withLogger(ObservationRegistryConfigurer.class)
.invoke((customizer) -> customizer.customize(registry));
}
private <T> List<T> asOrderedList(ObjectProvider<T> provider) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -74,7 +74,7 @@ public class HttpClientObservationsAutoConfiguration {
String name = (observationName != null) ? observationName : metricName;
MeterFilter denyFilter = new OnlyOnceLoggingDenyMeterFilter(
() -> "Reached the maximum number of URI tags for '%s'. Are you using 'uriVariables'?"
.formatted(name));
.formatted(name));
return MeterFilter.maximumAllowableTags(name, "uri", clientProperties.getMaxUriTags(), denyFilter);
}

View File

@@ -246,8 +246,10 @@ public final class EndpointRequest {
}
private String toString(List<Object> endpoints, String emptyValue) {
return (!endpoints.isEmpty()) ? endpoints.stream().map(this::getEndpointId).map(Object::toString)
.collect(Collectors.joining(", ", "[", "]")) : emptyValue;
return (!endpoints.isEmpty()) ? endpoints.stream()
.map(this::getEndpointId)
.map(Object::toString)
.collect(Collectors.joining(", ", "[", "]")) : emptyValue;
}
private EndpointId getEndpointId(Object source) {

View File

@@ -250,8 +250,9 @@ public final class EndpointRequest {
private List<RequestMatcher> getDelegateMatchers(RequestMatcherFactory requestMatcherFactory,
RequestMatcherProvider matcherProvider, Set<String> paths) {
return paths.stream().map((path) -> requestMatcherFactory.antPath(matcherProvider, path, "/**"))
.collect(Collectors.toCollection(ArrayList::new));
return paths.stream()
.map((path) -> requestMatcherFactory.antPath(matcherProvider, path, "/**"))
.collect(Collectors.toCollection(ArrayList::new));
}
@Override
@@ -261,8 +262,10 @@ public final class EndpointRequest {
}
private String toString(List<Object> endpoints, String emptyValue) {
return (!endpoints.isEmpty()) ? endpoints.stream().map(this::getEndpointId).map(Object::toString)
.collect(Collectors.joining(", ", "[", "]")) : emptyValue;
return (!endpoints.isEmpty()) ? endpoints.stream()
.map(this::getEndpointId)
.map(Object::toString)
.collect(Collectors.joining(", ", "[", "]")) : emptyValue;
}
private EndpointId getEndpointId(Object source) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -62,8 +62,8 @@ public class StartupEndpointAutoConfiguration {
ConditionMessage.Builder message = ConditionMessage.forCondition("ApplicationStartup");
ApplicationStartup applicationStartup = context.getBeanFactory().getApplicationStartup();
if (applicationStartup instanceof BufferingApplicationStartup) {
return ConditionOutcome.match(
message.because("configured applicationStartup is of type BufferingApplicationStartup."));
return ConditionOutcome
.match(message.because("configured applicationStartup is of type BufferingApplicationStartup."));
}
return ConditionOutcome.noMatch(message.because("configured applicationStartup is of type "
+ applicationStartup.getClass() + ", expected BufferingApplicationStartup."));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -101,9 +101,13 @@ public class BraveAutoConfiguration {
List<TracingCustomizer> tracingCustomizers, CurrentTraceContext currentTraceContext,
Factory propagationFactory, Sampler sampler) {
String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME);
Builder builder = Tracing.newBuilder().currentTraceContext(currentTraceContext).traceId128Bit(true)
.supportsJoin(false).propagationFactory(propagationFactory).sampler(sampler)
.localServiceName(applicationName);
Builder builder = Tracing.newBuilder()
.currentTraceContext(currentTraceContext)
.traceId128Bit(true)
.supportsJoin(false)
.propagationFactory(propagationFactory)
.sampler(sampler)
.localServiceName(applicationName);
spanHandlers.forEach(builder::addSpanHandler);
for (TracingCustomizer tracingCustomizer : tracingCustomizers) {
tracingCustomizer.customize(builder);
@@ -234,7 +238,8 @@ public class BraveAutoConfiguration {
List<String> correlationFields = this.tracingProperties.getBaggage().getCorrelation().getFields();
for (String field : correlationFields) {
builder.add(CorrelationScopeConfig.SingleCorrelationField.newBuilder(BaggageField.create(field))
.flushOnUpdate().build());
.flushOnUpdate()
.build());
}
};
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -88,8 +88,10 @@ public class OpenTelemetryAutoConfiguration {
@Bean
@ConditionalOnMissingBean
OpenTelemetry openTelemetry(SdkTracerProvider sdkTracerProvider, ContextPropagators contextPropagators) {
return OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider).setPropagators(contextPropagators)
.build();
return OpenTelemetrySdk.builder()
.setTracerProvider(sdkTracerProvider)
.setPropagators(contextPropagators)
.build();
}
@Bean
@@ -97,8 +99,9 @@ public class OpenTelemetryAutoConfiguration {
SdkTracerProvider otelSdkTracerProvider(Environment environment, ObjectProvider<SpanProcessor> spanProcessors,
Sampler sampler) {
String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME);
SdkTracerProviderBuilder builder = SdkTracerProvider.builder().setSampler(sampler)
.setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName)));
SdkTracerProviderBuilder builder = SdkTracerProvider.builder()
.setSampler(sampler)
.setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName)));
spanProcessors.orderedStream().forEach(builder::addSpanProcessor);
return builder.build();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -79,7 +79,8 @@ class ZipkinConfigurations {
ZipkinRestTemplateSender restTemplateSender(ZipkinProperties properties,
ObjectProvider<ZipkinRestTemplateBuilderCustomizer> customizers) {
RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder()
.setConnectTimeout(properties.getConnectTimeout()).setReadTimeout(properties.getReadTimeout());
.setConnectTimeout(properties.getConnectTimeout())
.setReadTimeout(properties.getReadTimeout());
restTemplateBuilder = applyCustomizers(restTemplateBuilder, customizers);
return new ZipkinRestTemplateSender(properties.getEndpoint(), restTemplateBuilder.build());
}
@@ -87,7 +88,7 @@ class ZipkinConfigurations {
private RestTemplateBuilder applyCustomizers(RestTemplateBuilder restTemplateBuilder,
ObjectProvider<ZipkinRestTemplateBuilderCustomizer> customizers) {
Iterable<ZipkinRestTemplateBuilderCustomizer> orderedCustomizers = () -> customizers.orderedStream()
.iterator();
.iterator();
RestTemplateBuilder currentBuilder = restTemplateBuilder;
for (ZipkinRestTemplateBuilderCustomizer customizer : orderedCustomizers) {
currentBuilder = customizer.customize(currentBuilder);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -74,8 +74,12 @@ class ZipkinWebClientSender extends HttpSender {
}
private Mono<ResponseEntity<Void>> sendRequest() {
return this.webClient.post().uri(this.endpoint).headers(this::addDefaultHeaders).bodyValue(getBody())
.retrieve().toBodilessEntity();
return this.webClient.post()
.uri(this.endpoint)
.headers(this::addDefaultHeaders)
.bodyValue(getBody())
.retrieve()
.toBodilessEntity();
}
private void addDefaultHeaders(HttpHeaders headers) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -59,12 +59,12 @@ public final class ManagementContextFactory {
public ConfigurableApplicationContext createManagementContext(ApplicationContext parentContext) {
Environment parentEnvironment = parentContext.getEnvironment();
ConfigurableEnvironment childEnvironment = ApplicationContextFactory.DEFAULT
.createEnvironment(this.webApplicationType);
.createEnvironment(this.webApplicationType);
if (parentEnvironment instanceof ConfigurableEnvironment) {
childEnvironment.setConversionService(((ConfigurableEnvironment) parentEnvironment).getConversionService());
}
ConfigurableApplicationContext managementContext = ApplicationContextFactory.DEFAULT
.create(this.webApplicationType);
.create(this.webApplicationType);
managementContext.setEnvironment(childEnvironment);
managementContext.setParent(parentContext);
return managementContext;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -121,7 +121,7 @@ class ChildManagementContextInitializer
protected final ConfigurableApplicationContext createManagementContext() {
ConfigurableApplicationContext managementContext = this.managementContextFactory
.createManagementContext(this.parentContext);
.createManagementContext(this.parentContext);
managementContext.setId(this.parentContext.getId() + ":management");
if (managementContext instanceof ConfigurableWebServerApplicationContext webServerApplicationContext) {
webServerApplicationContext.setServerNamespace("management");
@@ -162,9 +162,10 @@ class ChildManagementContextInitializer
public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) {
GenerationContext managementGenerationContext = generationContext.withName("Management");
ClassName generatedInitializerClassName = new ApplicationContextAotGenerator()
.processAheadOfTime(this.managementContext, managementGenerationContext);
GeneratedMethod postProcessorMethod = beanRegistrationCode.getMethods().add("addManagementInitializer",
(method) -> method.addJavadoc("Use AOT management context initialization")
.processAheadOfTime(this.managementContext, managementGenerationContext);
GeneratedMethod postProcessorMethod = beanRegistrationCode.getMethods()
.add("addManagementInitializer",
(method) -> method.addJavadoc("Use AOT management context initialization")
.addModifiers(Modifier.PRIVATE, Modifier.STATIC)
.addParameter(RegisteredBean.class, "registeredBean")
.addParameter(ChildManagementContextInitializer.class, "instance")

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -55,7 +55,8 @@ class ManagementContextConfigurationImportSelector implements DeferredImportSele
@Override
public String[] selectImports(AnnotationMetadata metadata) {
ManagementContextType contextType = (ManagementContextType) metadata
.getAnnotationAttributes(EnableManagementContext.class.getName()).get("value");
.getAnnotationAttributes(EnableManagementContext.class.getName())
.get("value");
// Find all management context configuration classes, filtering duplicates
List<ManagementConfiguration> configurations = getConfigurations();
OrderComparator.sort(configurations);
@@ -118,7 +119,7 @@ class ManagementContextConfigurationImportSelector implements DeferredImportSele
private ManagementContextType readContextType(AnnotationMetadata annotationMetadata) {
Map<String, Object> annotationAttributes = annotationMetadata
.getAnnotationAttributes(ManagementContextConfiguration.class.getName());
.getAnnotationAttributes(ManagementContextConfiguration.class.getName());
return (annotationAttributes != null) ? (ManagementContextType) annotationAttributes.get("value")
: ManagementContextType.ANY;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -62,7 +62,7 @@ public abstract class ManagementWebServerFactoryCustomizer<T extends Configurabl
@Override
public final void customize(T factory) {
ManagementServerProperties managementServerProperties = BeanFactoryUtils
.beanOfTypeIncludingAncestors(this.beanFactory, ManagementServerProperties.class);
.beanOfTypeIncludingAncestors(this.beanFactory, ManagementServerProperties.class);
// Customize as per the parent context first (so e.g. the access logs go to
// the same place)
customizeSameAsParentContext(factory);
@@ -89,7 +89,7 @@ public abstract class ManagementWebServerFactoryCustomizer<T extends Configurabl
@SuppressWarnings("unchecked")
private void invokeCustomizers(T factory, List<WebServerFactoryCustomizer<?>> customizers) {
LambdaSafe.callbacks(WebServerFactoryCustomizer.class, customizers, factory)
.invoke((customizer) -> customizer.customize(factory));
.invoke((customizer) -> customizer.customize(factory));
}
protected void customize(T factory, ManagementServerProperties managementServerProperties,

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2023 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.
@@ -49,10 +49,10 @@ class OnManagementPortCondition extends SpringBootCondition {
ManagementPortType actualType = ManagementPortType.get(context.getEnvironment());
if (actualType == requiredType) {
return ConditionOutcome
.match(message.because("actual port type (" + actualType + ") matched required type"));
.match(message.because("actual port type (" + actualType + ") matched required type"));
}
return ConditionOutcome.noMatch(message
.because("actual port type (" + actualType + ") did not match required type (" + requiredType + ")"));
.because("actual port type (" + actualType + ") did not match required type (" + requiredType + ")"));
}
private boolean isWebApplicationContext(ConditionContext context) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -111,8 +111,8 @@ class ServletManagementChildContextConfiguration {
@Bean
@ConditionalOnBean(name = "securityFilterChainRegistration", search = SearchStrategy.ANCESTORS)
DelegatingFilterProxyRegistrationBean securityFilterChainRegistration(HierarchicalBeanFactory beanFactory) {
return beanFactory.getParentBeanFactory().getBean("securityFilterChainRegistration",
DelegatingFilterProxyRegistrationBean.class);
return beanFactory.getParentBeanFactory()
.getBean("securityFilterChainRegistration", DelegatingFilterProxyRegistrationBean.class);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2023 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.
@@ -34,8 +34,8 @@ import static org.assertj.core.api.Assertions.assertThat;
class RabbitHealthContributorAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class,
RabbitHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class,
RabbitHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
@Test
void runShouldCreateIndicator() {
@@ -45,7 +45,7 @@ class RabbitHealthContributorAutoConfigurationTests {
@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withPropertyValues("management.health.rabbit.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(RabbitHealthIndicator.class));
.run((context) -> assertThat(context).doesNotHaveBean(RabbitHealthIndicator.class));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -47,7 +47,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class AuditAutoConfigurationTests {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(AuditAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(AuditAutoConfiguration.class));
@Test
void autoConfigurationIsDisabledByDefault() {
@@ -66,34 +66,34 @@ class AuditAutoConfigurationTests {
@Test
void ownAuthenticationAuditListener() {
this.contextRunner.withUserConfiguration(CustomAuditEventRepositoryConfiguration.class)
.withUserConfiguration(CustomAuthenticationAuditListenerConfiguration.class)
.run((context) -> assertThat(context.getBean(AbstractAuthenticationAuditListener.class))
.isInstanceOf(TestAuthenticationAuditListener.class));
.withUserConfiguration(CustomAuthenticationAuditListenerConfiguration.class)
.run((context) -> assertThat(context.getBean(AbstractAuthenticationAuditListener.class))
.isInstanceOf(TestAuthenticationAuditListener.class));
}
@Test
void ownAuthorizationAuditListener() {
this.contextRunner.withUserConfiguration(CustomAuditEventRepositoryConfiguration.class)
.withUserConfiguration(CustomAuthorizationAuditListenerConfiguration.class)
.run((context) -> assertThat(context.getBean(AbstractAuthorizationAuditListener.class))
.isInstanceOf(TestAuthorizationAuditListener.class));
.withUserConfiguration(CustomAuthorizationAuditListenerConfiguration.class)
.run((context) -> assertThat(context.getBean(AbstractAuthorizationAuditListener.class))
.isInstanceOf(TestAuthorizationAuditListener.class));
}
@Test
void ownAuditListener() {
this.contextRunner.withUserConfiguration(CustomAuditEventRepositoryConfiguration.class)
.withUserConfiguration(CustomAuditListenerConfiguration.class)
.run((context) -> assertThat(context.getBean(AbstractAuditListener.class))
.isInstanceOf(TestAuditListener.class));
.withUserConfiguration(CustomAuditListenerConfiguration.class)
.run((context) -> assertThat(context.getBean(AbstractAuditListener.class))
.isInstanceOf(TestAuditListener.class));
}
@Test
void backsOffWhenDisabled() {
this.contextRunner.withUserConfiguration(CustomAuditEventRepositoryConfiguration.class)
.withPropertyValues("management.auditevents.enabled=false")
.run((context) -> assertThat(context).doesNotHaveBean(AuditListener.class)
.doesNotHaveBean(AuthenticationAuditListener.class)
.doesNotHaveBean(AuthorizationAuditListener.class));
.withPropertyValues("management.auditevents.enabled=false")
.run((context) -> assertThat(context).doesNotHaveBean(AuditListener.class)
.doesNotHaveBean(AuthenticationAuditListener.class)
.doesNotHaveBean(AuthorizationAuditListener.class));
}
@Configuration(proxyBeanMethods = false)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2023 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.
@@ -42,14 +42,14 @@ class AuditEventsEndpointAutoConfigurationTests {
@Test
void runWhenRepositoryBeanAvailableShouldHaveEndpointBean() {
this.contextRunner.withUserConfiguration(CustomAuditEventRepositoryConfiguration.class)
.withPropertyValues("management.endpoints.web.exposure.include=auditevents")
.run((context) -> assertThat(context).hasSingleBean(AuditEventsEndpoint.class));
.withPropertyValues("management.endpoints.web.exposure.include=auditevents")
.run((context) -> assertThat(context).hasSingleBean(AuditEventsEndpoint.class));
}
@Test
void endpointBacksOffWhenRepositoryNotAvailable() {
this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=auditevents")
.run((context) -> assertThat(context).doesNotHaveBean(AuditEventsEndpoint.class));
.run((context) -> assertThat(context).doesNotHaveBean(AuditEventsEndpoint.class));
}
@Test
@@ -60,9 +60,9 @@ class AuditEventsEndpointAutoConfigurationTests {
@Test
void runWhenEnabledPropertyIsFalseShouldNotHaveEndpoint() {
this.contextRunner.withUserConfiguration(CustomAuditEventRepositoryConfiguration.class)
.withPropertyValues("management.endpoint.auditevents.enabled:false")
.withPropertyValues("management.endpoints.web.exposure.include=*")
.run((context) -> assertThat(context).doesNotHaveBean(AuditEventsEndpoint.class));
.withPropertyValues("management.endpoint.auditevents.enabled:false")
.withPropertyValues("management.endpoints.web.exposure.include=*")
.run((context) -> assertThat(context).doesNotHaveBean(AuditEventsEndpoint.class));
}
@Configuration(proxyBeanMethods = false)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2023 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.
@@ -35,30 +35,30 @@ import static org.assertj.core.api.Assertions.assertThat;
class AvailabilityHealthContributorAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ApplicationAvailabilityAutoConfiguration.class,
AvailabilityHealthContributorAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(ApplicationAvailabilityAutoConfiguration.class,
AvailabilityHealthContributorAutoConfiguration.class));
@Test
void probesWhenNotKubernetesAddsNoBeans() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.doesNotHaveBean(LivenessStateHealthIndicator.class)
.doesNotHaveBean(ReadinessStateHealthIndicator.class));
.doesNotHaveBean(LivenessStateHealthIndicator.class)
.doesNotHaveBean(ReadinessStateHealthIndicator.class));
}
@Test
void livenessIndicatorWhenPropertyEnabledAddsBeans() {
this.contextRunner.withPropertyValues("management.health.livenessState.enabled=true")
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.hasSingleBean(LivenessStateHealthIndicator.class)
.doesNotHaveBean(ReadinessStateHealthIndicator.class));
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.hasSingleBean(LivenessStateHealthIndicator.class)
.doesNotHaveBean(ReadinessStateHealthIndicator.class));
}
@Test
void readinessIndicatorWhenPropertyEnabledAddsBeans() {
this.contextRunner.withPropertyValues("management.health.readinessState.enabled=true")
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.hasSingleBean(ReadinessStateHealthIndicator.class)
.doesNotHaveBean(LivenessStateHealthIndicator.class));
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.hasSingleBean(ReadinessStateHealthIndicator.class)
.doesNotHaveBean(LivenessStateHealthIndicator.class));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -35,44 +35,48 @@ import static org.assertj.core.api.Assertions.assertThat;
class AvailabilityProbesAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ApplicationAvailabilityAutoConfiguration.class,
AvailabilityHealthContributorAutoConfiguration.class, AvailabilityProbesAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(ApplicationAvailabilityAutoConfiguration.class,
AvailabilityHealthContributorAutoConfiguration.class, AvailabilityProbesAutoConfiguration.class));
@Test
void probesWhenNotKubernetesAddsNoBeans() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.doesNotHaveBean(LivenessStateHealthIndicator.class)
.doesNotHaveBean(ReadinessStateHealthIndicator.class)
.doesNotHaveBean(AvailabilityProbesHealthEndpointGroupsPostProcessor.class));
.doesNotHaveBean(LivenessStateHealthIndicator.class)
.doesNotHaveBean(ReadinessStateHealthIndicator.class)
.doesNotHaveBean(AvailabilityProbesHealthEndpointGroupsPostProcessor.class));
}
@Test
void probesWhenKubernetesAddsBeans() {
this.contextRunner.withPropertyValues("spring.main.cloud-platform=kubernetes")
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.hasSingleBean(LivenessStateHealthIndicator.class).hasBean("livenessStateHealthIndicator")
.hasSingleBean(ReadinessStateHealthIndicator.class).hasBean("readinessStateHealthIndicator")
.hasSingleBean(AvailabilityProbesHealthEndpointGroupsPostProcessor.class));
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.hasSingleBean(LivenessStateHealthIndicator.class)
.hasBean("livenessStateHealthIndicator")
.hasSingleBean(ReadinessStateHealthIndicator.class)
.hasBean("readinessStateHealthIndicator")
.hasSingleBean(AvailabilityProbesHealthEndpointGroupsPostProcessor.class));
}
@Test
void probesWhenPropertyEnabledAddsBeans() {
this.contextRunner.withPropertyValues("management.endpoint.health.probes.enabled=true")
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.hasSingleBean(LivenessStateHealthIndicator.class).hasBean("livenessStateHealthIndicator")
.hasSingleBean(ReadinessStateHealthIndicator.class).hasBean("readinessStateHealthIndicator")
.hasSingleBean(AvailabilityProbesHealthEndpointGroupsPostProcessor.class));
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.hasSingleBean(LivenessStateHealthIndicator.class)
.hasBean("livenessStateHealthIndicator")
.hasSingleBean(ReadinessStateHealthIndicator.class)
.hasBean("readinessStateHealthIndicator")
.hasSingleBean(AvailabilityProbesHealthEndpointGroupsPostProcessor.class));
}
@Test
void probesWhenKubernetesAndPropertyDisabledAddsNotBeans() {
this.contextRunner
.withPropertyValues("spring.main.cloud-platform=kubernetes",
"management.endpoint.health.probes.enabled=false")
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.doesNotHaveBean(LivenessStateHealthIndicator.class)
.doesNotHaveBean(ReadinessStateHealthIndicator.class)
.doesNotHaveBean(AvailabilityProbesHealthEndpointGroupsPostProcessor.class));
.withPropertyValues("spring.main.cloud-platform=kubernetes",
"management.endpoint.health.probes.enabled=false")
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.doesNotHaveBean(LivenessStateHealthIndicator.class)
.doesNotHaveBean(ReadinessStateHealthIndicator.class)
.doesNotHaveBean(AvailabilityProbesHealthEndpointGroupsPostProcessor.class));
}
}

View File

@@ -49,7 +49,7 @@ class AvailabilityProbesHealthEndpointGroupsPostProcessorTests {
names.add("liveness");
given(groups.getNames()).willReturn(names);
assertThat(this.postProcessor.postProcessHealthEndpointGroups(groups))
.isInstanceOf(AvailabilityProbesHealthEndpointGroups.class);
.isInstanceOf(AvailabilityProbesHealthEndpointGroups.class);
}
@Test
@@ -60,7 +60,7 @@ class AvailabilityProbesHealthEndpointGroupsPostProcessorTests {
names.add("readiness");
given(groups.getNames()).willReturn(names);
assertThat(this.postProcessor.postProcessHealthEndpointGroups(groups))
.isInstanceOf(AvailabilityProbesHealthEndpointGroups.class);
.isInstanceOf(AvailabilityProbesHealthEndpointGroups.class);
}
@Test
@@ -72,7 +72,7 @@ class AvailabilityProbesHealthEndpointGroupsPostProcessorTests {
names.add("boot");
given(groups.getNames()).willReturn(names);
assertThat(this.postProcessor.postProcessHealthEndpointGroups(groups))
.isInstanceOf(AvailabilityProbesHealthEndpointGroups.class);
.isInstanceOf(AvailabilityProbesHealthEndpointGroups.class);
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -52,7 +52,7 @@ class AvailabilityProbesHealthEndpointGroupsTests {
@Test
void createWhenGroupsIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() -> new AvailabilityProbesHealthEndpointGroups(null, false))
.withMessage("Groups must not be null");
.withMessage("Groups must not be null");
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2023 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.
@@ -32,12 +32,12 @@ import static org.assertj.core.api.Assertions.assertThat;
class BeansEndpointAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(BeansEndpointAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(BeansEndpointAutoConfiguration.class));
@Test
void runShouldHaveEndpointBean() {
this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=beans")
.run((context) -> assertThat(context).hasSingleBean(BeansEndpoint.class));
.run((context) -> assertThat(context).hasSingleBean(BeansEndpoint.class));
}
@Test
@@ -48,8 +48,8 @@ class BeansEndpointAutoConfigurationTests {
@Test
void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointBean() {
this.contextRunner.withPropertyValues("management.endpoint.beans.enabled:false")
.withPropertyValues("management.endpoints.web.exposure.include=*")
.run((context) -> assertThat(context).doesNotHaveBean(BeansEndpoint.class));
.withPropertyValues("management.endpoints.web.exposure.include=*")
.run((context) -> assertThat(context).doesNotHaveBean(BeansEndpoint.class));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -36,42 +36,42 @@ import static org.mockito.Mockito.mock;
class CachesEndpointAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(CachesEndpointAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(CachesEndpointAutoConfiguration.class));
@Test
void runShouldHaveEndpointBean() {
this.contextRunner.withBean(CacheManager.class, () -> mock(CacheManager.class))
.withPropertyValues("management.endpoints.web.exposure.include=caches")
.run((context) -> assertThat(context).hasSingleBean(CachesEndpoint.class));
.withPropertyValues("management.endpoints.web.exposure.include=caches")
.run((context) -> assertThat(context).hasSingleBean(CachesEndpoint.class));
}
@Test
void runWithoutCacheManagerShouldHaveEndpointBean() {
this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=caches")
.run((context) -> assertThat(context).hasSingleBean(CachesEndpoint.class));
.run((context) -> assertThat(context).hasSingleBean(CachesEndpoint.class));
}
@Test
void runWhenNotExposedShouldNotHaveEndpointBean() {
this.contextRunner.withBean(CacheManager.class, () -> mock(CacheManager.class))
.run((context) -> assertThat(context).doesNotHaveBean(CachesEndpoint.class));
.run((context) -> assertThat(context).doesNotHaveBean(CachesEndpoint.class));
}
@Test
void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointBean() {
this.contextRunner.withPropertyValues("management.endpoint.caches.enabled:false")
.withPropertyValues("management.endpoints.web.exposure.include=*")
.withBean(CacheManager.class, () -> mock(CacheManager.class))
.run((context) -> assertThat(context).doesNotHaveBean(CachesEndpoint.class));
.withPropertyValues("management.endpoints.web.exposure.include=*")
.withBean(CacheManager.class, () -> mock(CacheManager.class))
.run((context) -> assertThat(context).doesNotHaveBean(CachesEndpoint.class));
}
@Test
void runWhenOnlyExposedOverJmxShouldHaveEndpointBeanWithoutWebExtension() {
this.contextRunner.withBean(CacheManager.class, () -> mock(CacheManager.class))
.withPropertyValues("management.endpoints.web.exposure.include=info", "spring.jmx.enabled=true",
"management.endpoints.jmx.exposure.include=caches")
.run((context) -> assertThat(context).hasSingleBean(CachesEndpoint.class)
.doesNotHaveBean(CachesEndpointWebExtension.class));
.withPropertyValues("management.endpoints.web.exposure.include=info", "spring.jmx.enabled=true",
"management.endpoints.jmx.exposure.include=caches")
.run((context) -> assertThat(context).hasSingleBean(CachesEndpoint.class)
.doesNotHaveBean(CachesEndpointWebExtension.class));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -38,35 +38,35 @@ import static org.mockito.Mockito.mock;
class CassandraHealthContributorAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(CassandraHealthContributorAutoConfiguration.class,
HealthContributorAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(CassandraHealthContributorAutoConfiguration.class,
HealthContributorAutoConfiguration.class));
@Test
void runWithoutCqlSessionOrCassandraOperationsShouldNotCreateIndicator() {
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean("cassandraHealthContributor")
.doesNotHaveBean(CassandraDriverHealthIndicator.class));
.doesNotHaveBean(CassandraDriverHealthIndicator.class));
}
@Test
void runWithCqlSessionOnlyShouldCreateDriverIndicator() {
this.contextRunner.withBean(CqlSession.class, () -> mock(CqlSession.class))
.run((context) -> assertThat(context).hasSingleBean(CassandraDriverHealthIndicator.class));
.run((context) -> assertThat(context).hasSingleBean(CassandraDriverHealthIndicator.class));
}
@Test
void runWithCqlSessionAndSpringDataAbsentShouldCreateDriverIndicator() {
this.contextRunner.withBean(CqlSession.class, () -> mock(CqlSession.class))
.withClassLoader(new FilteredClassLoader("org.springframework.data"))
.run((context) -> assertThat(context).hasSingleBean(CassandraDriverHealthIndicator.class));
.withClassLoader(new FilteredClassLoader("org.springframework.data"))
.run((context) -> assertThat(context).hasSingleBean(CassandraDriverHealthIndicator.class));
}
@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withBean(CqlSession.class, () -> mock(CqlSession.class))
.withBean(CassandraOperations.class, () -> mock(CassandraOperations.class))
.withPropertyValues("management.health.cassandra.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean("cassandraHealthContributor")
.doesNotHaveBean(CassandraDriverHealthIndicator.class));
.withBean(CassandraOperations.class, () -> mock(CassandraOperations.class))
.withPropertyValues("management.health.cassandra.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean("cassandraHealthContributor")
.doesNotHaveBean(CassandraDriverHealthIndicator.class));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -40,45 +40,46 @@ import static org.mockito.Mockito.mock;
class CassandraReactiveHealthContributorAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(CassandraReactiveHealthContributorAutoConfiguration.class,
CassandraHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(CassandraReactiveHealthContributorAutoConfiguration.class,
CassandraHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
@Test
void runWithoutCqlSessionOrReactiveCassandraOperationsShouldNotCreateIndicator() {
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean("cassandraHealthContributor")
.doesNotHaveBean(CassandraDriverReactiveHealthIndicator.class));
.doesNotHaveBean(CassandraDriverReactiveHealthIndicator.class));
}
@Test
void runWithCqlSessionOnlyShouldCreateDriverIndicator() {
this.contextRunner.withBean(CqlSession.class, () -> mock(CqlSession.class)).run((context) -> assertThat(context)
.hasBean("cassandraHealthContributor").hasSingleBean(CassandraDriverReactiveHealthIndicator.class));
this.contextRunner.withBean(CqlSession.class, () -> mock(CqlSession.class))
.run((context) -> assertThat(context).hasBean("cassandraHealthContributor")
.hasSingleBean(CassandraDriverReactiveHealthIndicator.class));
}
@Test
void runWithCqlSessionAndReactiveCassandraOperationsShouldCreateDriverIndicator() {
this.contextRunner.withBean(CqlSession.class, () -> mock(CqlSession.class))
.withBean(ReactiveCassandraOperations.class, () -> mock(ReactiveCassandraOperations.class))
.withBean(CassandraOperations.class, () -> mock(CassandraOperations.class))
.run((context) -> assertThat(context).hasBean("cassandraHealthContributor")
.hasSingleBean(CassandraDriverReactiveHealthIndicator.class)
.doesNotHaveBean(CassandraDriverHealthIndicator.class));
.withBean(ReactiveCassandraOperations.class, () -> mock(ReactiveCassandraOperations.class))
.withBean(CassandraOperations.class, () -> mock(CassandraOperations.class))
.run((context) -> assertThat(context).hasBean("cassandraHealthContributor")
.hasSingleBean(CassandraDriverReactiveHealthIndicator.class)
.doesNotHaveBean(CassandraDriverHealthIndicator.class));
}
@Test
void runWithCqlSessionAndSpringDataAbsentShouldCreateDriverIndicator() {
this.contextRunner.withBean(CqlSession.class, () -> mock(CqlSession.class))
.withClassLoader(new FilteredClassLoader("org.springframework.data"))
.run((context) -> assertThat(context).hasBean("cassandraHealthContributor")
.hasSingleBean(CassandraDriverReactiveHealthIndicator.class));
.withClassLoader(new FilteredClassLoader("org.springframework.data"))
.run((context) -> assertThat(context).hasBean("cassandraHealthContributor")
.hasSingleBean(CassandraDriverReactiveHealthIndicator.class));
}
@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withBean(CqlSession.class, () -> mock(CqlSession.class))
.withBean(ReactiveCassandraOperations.class, () -> mock(ReactiveCassandraOperations.class))
.withPropertyValues("management.health.cassandra.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean("cassandraHealthContributor"));
.withBean(ReactiveCassandraOperations.class, () -> mock(ReactiveCassandraOperations.class))
.withPropertyValues("management.health.cassandra.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean("cassandraHealthContributor"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2023 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.
@@ -58,7 +58,7 @@ class CloudFoundryAuthorizationExceptionTests {
@Test
void statusCodeForUnsupportedSignatureAlgorithmReasonShouldBe401() {
assertThat(createException(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM).getStatusCode())
.isEqualTo(HttpStatus.UNAUTHORIZED);
.isEqualTo(HttpStatus.UNAUTHORIZED);
}
@Test
@@ -74,7 +74,7 @@ class CloudFoundryAuthorizationExceptionTests {
@Test
void statusCodeForServiceUnavailableReasonShouldBe503() {
assertThat(createException(Reason.SERVICE_UNAVAILABLE).getStatusCode())
.isEqualTo(HttpStatus.SERVICE_UNAVAILABLE);
.isEqualTo(HttpStatus.SERVICE_UNAVAILABLE);
}
private CloudFoundryAuthorizationException createException(Reason reason) {

View File

@@ -67,8 +67,8 @@ class CloudFoundryWebEndpointDiscovererTests {
if (endpoint.getEndpointId().equals(EndpointId.of("health"))) {
WebOperation operation = findMainReadOperation(endpoint);
assertThat(operation
.invoke(new InvocationContext(mock(SecurityContext.class), Collections.emptyMap())))
.isEqualTo("cf");
.invoke(new InvocationContext(mock(SecurityContext.class), Collections.emptyMap())))
.isEqualTo("cf");
}
}
});
@@ -78,8 +78,9 @@ class CloudFoundryWebEndpointDiscovererTests {
void shouldRegisterHints() {
RuntimeHints runtimeHints = new RuntimeHints();
new CloudFoundryWebEndpointDiscovererRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader());
assertThat(RuntimeHintsPredicates.reflection().onType(CloudFoundryEndpointFilter.class)
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints);
assertThat(RuntimeHintsPredicates.reflection()
.onType(CloudFoundryEndpointFilter.class)
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints);
}
private WebOperation findMainReadOperation(ExposableWebEndpoint endpoint) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2023 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.
@@ -36,7 +36,7 @@ class TokenTests {
@Test
void invalidJwtShouldThrowException() {
assertThatExceptionOfType(CloudFoundryAuthorizationException.class).isThrownBy(() -> new Token("invalid-token"))
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
}
@Test
@@ -44,9 +44,9 @@ class TokenTests {
String header = "{\"alg\": \"RS256\", \"kid\": \"key-id\", \"typ\": \"JWT\"}";
String claims = "invalid-claims";
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(() -> new Token(Base64.getEncoder().encodeToString(header.getBytes()) + "."
+ Base64.getEncoder().encodeToString(claims.getBytes())))
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
.isThrownBy(() -> new Token(Base64.getEncoder().encodeToString(header.getBytes()) + "."
+ Base64.getEncoder().encodeToString(claims.getBytes())))
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
}
@Test
@@ -54,9 +54,9 @@ class TokenTests {
String header = "invalid-header";
String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\"}";
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(() -> new Token(Base64.getEncoder().encodeToString(header.getBytes()) + "."
+ Base64.getEncoder().encodeToString(claims.getBytes())))
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
.isThrownBy(() -> new Token(Base64.getEncoder().encodeToString(header.getBytes()) + "."
+ Base64.getEncoder().encodeToString(claims.getBytes())))
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
}
@Test
@@ -64,7 +64,7 @@ class TokenTests {
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwu"
+ "Y29tIiwiZXhwIjoxNDI2NDIwODAwLCJhd2Vzb21lIjp0cnVlfQ.";
assertThatExceptionOfType(CloudFoundryAuthorizationException.class).isThrownBy(() -> new Token(token))
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
}
@Test
@@ -89,7 +89,7 @@ class TokenTests {
String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\"}";
Token token = createToken(header, claims);
assertThatExceptionOfType(CloudFoundryAuthorizationException.class).isThrownBy(token::getSignatureAlgorithm)
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
}
@Test
@@ -98,7 +98,7 @@ class TokenTests {
String claims = "{\"exp\": 2147483647}";
Token token = createToken(header, claims);
assertThatExceptionOfType(CloudFoundryAuthorizationException.class).isThrownBy(token::getIssuer)
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
}
@Test
@@ -107,7 +107,7 @@ class TokenTests {
String claims = "{\"exp\": 2147483647}";
Token token = createToken(header, claims);
assertThatExceptionOfType(CloudFoundryAuthorizationException.class).isThrownBy(token::getKeyId)
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
}
@Test
@@ -116,7 +116,7 @@ class TokenTests {
String claims = "{\"iss\": \"http://localhost:8080/uaa/oauth/token\"}";
Token token = createToken(header, claims);
assertThatExceptionOfType(CloudFoundryAuthorizationException.class).isThrownBy(token::getExpiry)
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
}
private Token createToken(String header, String claims) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -50,23 +50,23 @@ import static org.assertj.core.api.Assertions.assertThat;
class CloudFoundryReactiveHealthEndpointWebExtensionTests {
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner()
.withPropertyValues("VCAP_APPLICATION={}")
.withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class,
ReactiveUserDetailsServiceAutoConfiguration.class, WebFluxAutoConfiguration.class,
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
ReactiveCloudFoundryActuatorAutoConfigurationTests.WebClientCustomizerConfig.class,
WebClientAutoConfiguration.class, ManagementContextAutoConfiguration.class,
EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class,
HealthContributorAutoConfiguration.class, HealthEndpointAutoConfiguration.class,
ReactiveCloudFoundryActuatorAutoConfiguration.class))
.withUserConfiguration(TestHealthIndicator.class);
.withPropertyValues("VCAP_APPLICATION={}")
.withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class,
ReactiveUserDetailsServiceAutoConfiguration.class, WebFluxAutoConfiguration.class,
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
ReactiveCloudFoundryActuatorAutoConfigurationTests.WebClientCustomizerConfig.class,
WebClientAutoConfiguration.class, ManagementContextAutoConfiguration.class,
EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class,
HealthContributorAutoConfiguration.class, HealthEndpointAutoConfiguration.class,
ReactiveCloudFoundryActuatorAutoConfiguration.class))
.withUserConfiguration(TestHealthIndicator.class);
@Test
void healthComponentsAlwaysPresent() {
this.contextRunner.run((context) -> {
CloudFoundryReactiveHealthEndpointWebExtension extension = context
.getBean(CloudFoundryReactiveHealthEndpointWebExtension.class);
.getBean(CloudFoundryReactiveHealthEndpointWebExtension.class);
HealthComponent body = extension.health(ApiVersion.V3).block(Duration.ofSeconds(30)).getBody();
HealthComponent health = ((CompositeHealth) body).getComponents().entrySet().iterator().next().getValue();
assertThat(((Health) health).getDetails()).containsEntry("spring", "boot");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -39,7 +39,7 @@ class CloudFoundryWebFluxEndpointHandlerMappingTests {
new CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints().registerHints(runtimeHints,
getClass().getClassLoader());
assertThat(RuntimeHintsPredicates.reflection().onMethod(CloudFoundryLinksHandler.class, "links"))
.accepts(runtimeHints);
.accepts(runtimeHints);
assertThat(RuntimeHintsPredicates.reflection().onType(Link.class)).accepts(runtimeHints);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -78,50 +78,87 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner(
AnnotationConfigReactiveWebServerApplicationContext::new)
.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class,
HttpHandlerAutoConfiguration.class, ReactiveWebServerFactoryAutoConfiguration.class))
.withUserConfiguration(TestEndpointConfiguration.class).withPropertyValues("server.port=0");
.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class, HttpHandlerAutoConfiguration.class,
ReactiveWebServerFactoryAutoConfiguration.class))
.withUserConfiguration(TestEndpointConfiguration.class)
.withPropertyValues("server.port=0");
@Test
void operationWithSecurityInterceptorForbidden() {
given(tokenValidator.validate(any())).willReturn(Mono.empty());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
this.contextRunner.run(withWebTestClient((client) -> client.get().uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON).header("Authorization", "bearer " + mockAccessToken()).exchange()
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN)));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange()
.expectStatus()
.isEqualTo(HttpStatus.FORBIDDEN)));
}
@Test
void operationWithSecurityInterceptorSuccess() {
given(tokenValidator.validate(any())).willReturn(Mono.empty());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
this.contextRunner.run(withWebTestClient((client) -> client.get().uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON).header("Authorization", "bearer " + mockAccessToken()).exchange()
.expectStatus().isEqualTo(HttpStatus.OK)));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange()
.expectStatus()
.isEqualTo(HttpStatus.OK)));
}
@Test
void responseToOptionsRequestIncludesCorsHeaders() {
this.contextRunner.run(withWebTestClient((client) -> client.options().uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON).header("Access-Control-Request-Method", "POST")
.header("Origin", "https://example.com").exchange().expectStatus().isOk().expectHeader()
.valueEquals("Access-Control-Allow-Origin", "https://example.com").expectHeader()
.valueEquals("Access-Control-Allow-Methods", "GET,POST")));
this.contextRunner.run(withWebTestClient((client) -> client.options()
.uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON)
.header("Access-Control-Request-Method", "POST")
.header("Origin", "https://example.com")
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.valueEquals("Access-Control-Allow-Origin", "https://example.com")
.expectHeader()
.valueEquals("Access-Control-Allow-Methods", "GET,POST")));
}
@Test
void linksToOtherEndpointsWithFullAccess() {
given(tokenValidator.validate(any())).willReturn(Mono.empty());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
this.contextRunner
.run(withWebTestClient((client) -> client.get().uri("/cfApplication").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken()).exchange().expectStatus().isOk()
.expectBody().jsonPath("_links.length()").isEqualTo(5).jsonPath("_links.self.href").isNotEmpty()
.jsonPath("_links.self.templated").isEqualTo(false).jsonPath("_links.info.href").isNotEmpty()
.jsonPath("_links.info.templated").isEqualTo(false).jsonPath("_links.env.href").isNotEmpty()
.jsonPath("_links.env.templated").isEqualTo(false).jsonPath("_links.test.href").isNotEmpty()
.jsonPath("_links.test.templated").isEqualTo(false).jsonPath("_links.test-part.href")
.isNotEmpty().jsonPath("_links.test-part.templated").isEqualTo(true)));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange()
.expectStatus()
.isOk()
.expectBody()
.jsonPath("_links.length()")
.isEqualTo(5)
.jsonPath("_links.self.href")
.isNotEmpty()
.jsonPath("_links.self.templated")
.isEqualTo(false)
.jsonPath("_links.info.href")
.isNotEmpty()
.jsonPath("_links.info.templated")
.isEqualTo(false)
.jsonPath("_links.env.href")
.isNotEmpty()
.jsonPath("_links.env.templated")
.isEqualTo(false)
.jsonPath("_links.test.href")
.isNotEmpty()
.jsonPath("_links.test.templated")
.isEqualTo(false)
.jsonPath("_links.test-part.href")
.isNotEmpty()
.jsonPath("_links.test-part.templated")
.isEqualTo(true)));
}
@Test
@@ -129,31 +166,55 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
"invalid-token");
willThrow(exception).given(tokenValidator).validate(any());
this.contextRunner.run(withWebTestClient((client) -> client.get().uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON).header("Authorization", "bearer " + mockAccessToken()).exchange()
.expectStatus().isUnauthorized()));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange()
.expectStatus()
.isUnauthorized()));
}
@Test
void linksToOtherEndpointsWithRestrictedAccess() {
given(tokenValidator.validate(any())).willReturn(Mono.empty());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
this.contextRunner
.run(withWebTestClient((client) -> client.get().uri("/cfApplication").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken()).exchange().expectStatus().isOk()
.expectBody().jsonPath("_links.length()").isEqualTo(2).jsonPath("_links.self.href").isNotEmpty()
.jsonPath("_links.self.templated").isEqualTo(false).jsonPath("_links.info.href").isNotEmpty()
.jsonPath("_links.info.templated").isEqualTo(false).jsonPath("_links.env").doesNotExist()
.jsonPath("_links.test").doesNotExist().jsonPath("_links.test-part").doesNotExist()));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange()
.expectStatus()
.isOk()
.expectBody()
.jsonPath("_links.length()")
.isEqualTo(2)
.jsonPath("_links.self.href")
.isNotEmpty()
.jsonPath("_links.self.templated")
.isEqualTo(false)
.jsonPath("_links.info.href")
.isNotEmpty()
.jsonPath("_links.info.templated")
.isEqualTo(false)
.jsonPath("_links.env")
.doesNotExist()
.jsonPath("_links.test")
.doesNotExist()
.jsonPath("_links.test-part")
.doesNotExist()));
}
private ContextConsumer<AssertableReactiveWebApplicationContext> withWebTestClient(
Consumer<WebTestClient> clientConsumer) {
return (context) -> {
int port = ((AnnotationConfigReactiveWebServerApplicationContext) context.getSourceApplicationContext())
.getWebServer().getPort();
clientConsumer.accept(WebTestClient.bindToServer().baseUrl("http://localhost:" + port)
.responseTimeout(Duration.ofMinutes(5)).build());
.getWebServer()
.getPort();
clientConsumer.accept(WebTestClient.bindToServer()
.baseUrl("http://localhost:" + port)
.responseTimeout(Duration.ofMinutes(5))
.build());
};
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -84,15 +84,15 @@ class ReactiveCloudFoundryActuatorAutoConfigurationTests {
private static final String V3_JSON = ApiVersion.V3.getProducedMimeType().toString();
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner()
.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,
HealthContributorAutoConfiguration.class, HealthEndpointAutoConfiguration.class,
InfoContributorAutoConfiguration.class, InfoEndpointAutoConfiguration.class,
ProjectInfoAutoConfiguration.class, ReactiveCloudFoundryActuatorAutoConfiguration.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,
HealthContributorAutoConfiguration.class, HealthEndpointAutoConfiguration.class,
InfoContributorAutoConfiguration.class, InfoEndpointAutoConfiguration.class,
ProjectInfoAutoConfiguration.class, ReactiveCloudFoundryActuatorAutoConfiguration.class));
@AfterEach
void close() {
@@ -101,149 +101,161 @@ class ReactiveCloudFoundryActuatorAutoConfigurationTests {
@Test
void cloudFoundryPlatformActive() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com").run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
EndpointMapping endpointMapping = (EndpointMapping) ReflectionTestUtils.getField(handlerMapping,
"endpointMapping");
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"));
});
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
EndpointMapping endpointMapping = (EndpointMapping) ReflectionTestUtils.getField(handlerMapping,
"endpointMapping");
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"));
});
}
@Test
void cloudfoundryapplicationProducesActuatorMediaType() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com").run((context) -> {
WebTestClient webTestClient = WebTestClient.bindToApplicationContext(context).build();
webTestClient.get().uri("/cloudfoundryapplication").header("Content-Type",
V2_JSON + ";charset=UTF-8");
});
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
WebTestClient webTestClient = WebTestClient.bindToApplicationContext(context).build();
webTestClient.get().uri("/cloudfoundryapplication").header("Content-Type", V2_JSON + ";charset=UTF-8");
});
}
@Test
void cloudFoundryPlatformActiveSetsApplicationId() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com").run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
String applicationId = (String) ReflectionTestUtils.getField(interceptor, "applicationId");
assertThat(applicationId).isEqualTo("my-app-id");
});
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
String applicationId = (String) ReflectionTestUtils.getField(interceptor, "applicationId");
assertThat(applicationId).isEqualTo("my-app-id");
});
}
@Test
void cloudFoundryPlatformActiveSetsCloudControllerUrl() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com").run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
String cloudControllerUrl = (String) ReflectionTestUtils.getField(interceptorSecurityService,
"cloudControllerUrl");
assertThat(cloudControllerUrl).isEqualTo("https://my-cloud-controller.com");
});
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
String cloudControllerUrl = (String) ReflectionTestUtils.getField(interceptorSecurityService,
"cloudControllerUrl");
assertThat(cloudControllerUrl).isEqualTo("https://my-cloud-controller.com");
});
}
@Test
void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent() {
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 interceptorSecurityService = ReflectionTestUtils.getField(securityInterceptor,
"cloudFoundrySecurityService");
assertThat(interceptorSecurityService).isNull();
});
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = context.getBean(
"cloudFoundryWebFluxEndpointHandlerMapping", CloudFoundryWebFluxEndpointHandlerMapping.class);
Object securityInterceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(securityInterceptor,
"cloudFoundrySecurityService");
assertThat(interceptorSecurityService).isNull();
});
}
@Test
@SuppressWarnings("unchecked")
void cloudFoundryPathsIgnoredBySpringSecurity() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com").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()))
.block(Duration.ofSeconds(30));
Boolean otherRequestMatches = filters.get(0)
.matches(MockServerWebExchange.from(MockServerHttpRequest.get("/some-other-path").build()))
.block(Duration.ofSeconds(30));
assertThat(cfRequestMatches).isTrue();
assertThat(otherRequestMatches).isFalse();
otherRequestMatches = filters.get(1)
.matches(MockServerWebExchange.from(MockServerHttpRequest.get("/some-other-path").build()))
.block(Duration.ofSeconds(30));
assertThat(otherRequestMatches).isTrue();
});
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.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()))
.block(Duration.ofSeconds(30));
Boolean otherRequestMatches = filters.get(0)
.matches(MockServerWebExchange.from(MockServerHttpRequest.get("/some-other-path").build()))
.block(Duration.ofSeconds(30));
assertThat(cfRequestMatches).isTrue();
assertThat(otherRequestMatches).isFalse();
otherRequestMatches = filters.get(1)
.matches(MockServerWebExchange.from(MockServerHttpRequest.get("/some-other-path").build()))
.block(Duration.ofSeconds(30));
assertThat(otherRequestMatches).isTrue();
});
}
@Test
void cloudFoundryPlatformInactive() {
this.contextRunner.run(
(context) -> assertThat(context.containsBean("cloudFoundryWebFluxEndpointHandlerMapping")).isFalse());
this.contextRunner
.run((context) -> assertThat(context.containsBean("cloudFoundryWebFluxEndpointHandlerMapping")).isFalse());
}
@Test
void cloudFoundryManagementEndpointsDisabled() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION=---", "management.cloudfoundry.enabled:false").run(
(context) -> assertThat(context.containsBean("cloudFoundryWebFluxEndpointHandlerMapping")).isFalse());
this.contextRunner.withPropertyValues("VCAP_APPLICATION=---", "management.cloudfoundry.enabled:false")
.run((context) -> assertThat(context.containsBean("cloudFoundryWebFluxEndpointHandlerMapping")).isFalse());
}
@Test
void allEndpointsAvailableUnderCloudFoundryWithoutEnablingWebIncludes() {
this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new).withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id", "vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping.getEndpoints();
List<EndpointId> endpointIds = endpoints.stream().map(ExposableWebEndpoint::getEndpointId).toList();
assertThat(endpointIds).contains(EndpointId.of("test"));
});
this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new)
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping.getEndpoints();
List<EndpointId> endpointIds = endpoints.stream().map(ExposableWebEndpoint::getEndpointId).toList();
assertThat(endpointIds).contains(EndpointId.of("test"));
});
}
@Test
void endpointPathCustomizationIsNotApplied() {
this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new).withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id", "vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping.getEndpoints();
ExposableWebEndpoint endpoint = endpoints.stream()
.filter((candidate) -> EndpointId.of("test").equals(candidate.getEndpointId())).findFirst()
.get();
assertThat(endpoint.getOperations()).hasSize(1);
WebOperation operation = endpoint.getOperations().iterator().next();
assertThat(operation.getRequestPredicate().getPath()).isEqualTo("test");
});
this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new)
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping.getEndpoints();
ExposableWebEndpoint endpoint = endpoints.stream()
.filter((candidate) -> EndpointId.of("test").equals(candidate.getEndpointId()))
.findFirst()
.get();
assertThat(endpoint.getOperations()).hasSize(1);
WebOperation operation = endpoint.getOperations().iterator().next();
assertThat(operation.getRequestPredicate().getPath()).isEqualTo("test");
});
}
@Test
void healthEndpointInvokerShouldBeCloudFoundryWebExtension() {
this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
Collection<ExposableWebEndpoint> endpoints = getHandlerMapping(context).getEndpoints();
ExposableWebEndpoint endpoint = endpoints.iterator().next();
assertThat(endpoint.getOperations()).hasSize(2);
WebOperation webOperation = findOperationWithRequestPath(endpoint, "health");
assertThat(webOperation).extracting("invoker").extracting("target")
.isInstanceOf(CloudFoundryReactiveHealthEndpointWebExtension.class);
});
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
Collection<ExposableWebEndpoint> endpoints = getHandlerMapping(context).getEndpoints();
ExposableWebEndpoint endpoint = endpoints.iterator().next();
assertThat(endpoint.getOperations()).hasSize(2);
WebOperation webOperation = findOperationWithRequestPath(endpoint, "health");
assertThat(webOperation).extracting("invoker")
.extracting("target")
.isInstanceOf(CloudFoundryReactiveHealthEndpointWebExtension.class);
});
}
@Test
@@ -251,7 +263,7 @@ class ReactiveCloudFoundryActuatorAutoConfigurationTests {
void gitFullDetailsAlwaysPresent() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---").run((context) -> {
CloudFoundryInfoEndpointWebExtension extension = context
.getBean(CloudFoundryInfoEndpointWebExtension.class);
.getBean(CloudFoundryInfoEndpointWebExtension.class);
Map<String, Object> git = (Map<String, Object>) extension.info().get("git");
Map<String, Object> commit = (Map<String, Object>) git.get("commit");
assertThat(commit).hasSize(4);
@@ -261,38 +273,42 @@ class ReactiveCloudFoundryActuatorAutoConfigurationTests {
@Test
void skipSslValidation() {
this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com",
"management.cloudfoundry.skip-ssl-validation:true")
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
WebClient webClient = (WebClient) ReflectionTestUtils.getField(interceptorSecurityService,
"webClient");
webClient.get().uri("https://self-signed.badssl.com/").retrieve().toBodilessEntity()
.block(Duration.ofSeconds(30));
});
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com",
"management.cloudfoundry.skip-ssl-validation:true")
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
WebClient webClient = (WebClient) ReflectionTestUtils.getField(interceptorSecurityService, "webClient");
webClient.get()
.uri("https://self-signed.badssl.com/")
.retrieve()
.toBodilessEntity()
.block(Duration.ofSeconds(30));
});
}
@Test
void sslValidationNotSkippedByDefault() {
this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
WebClient webClient = (WebClient) ReflectionTestUtils.getField(interceptorSecurityService,
"webClient");
assertThatExceptionOfType(RuntimeException.class)
.isThrownBy(() -> webClient.get().uri("https://self-signed.badssl.com/").retrieve()
.toBodilessEntity().block(Duration.ofSeconds(30)))
.withCauseInstanceOf(SSLException.class);
});
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
WebClient webClient = (WebClient) ReflectionTestUtils.getField(interceptorSecurityService, "webClient");
assertThatExceptionOfType(RuntimeException.class)
.isThrownBy(() -> webClient.get()
.uri("https://self-signed.badssl.com/")
.retrieve()
.toBodilessEntity()
.block(Duration.ofSeconds(30)))
.withCauseInstanceOf(SSLException.class);
});
}
private CloudFoundryWebFluxEndpointHandlerMapping getHandlerMapping(ApplicationContext context) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2023 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.
@@ -61,64 +61,68 @@ class ReactiveCloudFoundrySecurityInterceptorTests {
@Test
void preHandleWhenRequestIsPreFlightShouldBeOk() {
MockServerWebExchange request = MockServerWebExchange
.from(MockServerHttpRequest.options("/a").header(HttpHeaders.ORIGIN, "https://example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET").build());
MockServerWebExchange request = MockServerWebExchange.from(MockServerHttpRequest.options("/a")
.header(HttpHeaders.ORIGIN, "https://example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET")
.build());
StepVerifier.create(this.interceptor.preHandle(request, "/a"))
.consumeNextWith((response) -> assertThat(response.getStatus()).isEqualTo(HttpStatus.OK))
.verifyComplete();
.consumeNextWith((response) -> assertThat(response.getStatus()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
@Test
void preHandleWhenTokenIsMissingShouldReturnMissingAuthorization() {
MockServerWebExchange request = MockServerWebExchange.from(MockServerHttpRequest.get("/a").build());
StepVerifier.create(this.interceptor.preHandle(request, "/a")).consumeNextWith(
(response) -> assertThat(response.getStatus()).isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus()))
.verifyComplete();
StepVerifier.create(this.interceptor.preHandle(request, "/a"))
.consumeNextWith(
(response) -> assertThat(response.getStatus()).isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus()))
.verifyComplete();
}
@Test
void preHandleWhenTokenIsNotBearerShouldReturnMissingAuthorization() {
MockServerWebExchange request = MockServerWebExchange
.from(MockServerHttpRequest.get("/a").header(HttpHeaders.AUTHORIZATION, mockAccessToken()).build());
StepVerifier.create(this.interceptor.preHandle(request, "/a")).consumeNextWith(
(response) -> assertThat(response.getStatus()).isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus()))
.verifyComplete();
.from(MockServerHttpRequest.get("/a").header(HttpHeaders.AUTHORIZATION, mockAccessToken()).build());
StepVerifier.create(this.interceptor.preHandle(request, "/a"))
.consumeNextWith(
(response) -> assertThat(response.getStatus()).isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus()))
.verifyComplete();
}
@Test
void preHandleWhenApplicationIdIsNullShouldReturnError() {
this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator, this.securityService, null);
MockServerWebExchange request = MockServerWebExchange.from(MockServerHttpRequest.get("/a")
.header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken()).build());
.header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken())
.build());
StepVerifier.create(this.interceptor.preHandle(request, "/a"))
.consumeErrorWith((ex) -> assertThat(((CloudFoundryAuthorizationException) ex).getReason())
.isEqualTo(Reason.SERVICE_UNAVAILABLE))
.verify();
.consumeErrorWith((ex) -> assertThat(((CloudFoundryAuthorizationException) ex).getReason())
.isEqualTo(Reason.SERVICE_UNAVAILABLE))
.verify();
}
@Test
void preHandleWhenCloudFoundrySecurityServiceIsNullShouldReturnError() {
this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator, null, "my-app-id");
MockServerWebExchange request = MockServerWebExchange
.from(MockServerHttpRequest.get("/a").header(HttpHeaders.AUTHORIZATION, mockAccessToken()).build());
.from(MockServerHttpRequest.get("/a").header(HttpHeaders.AUTHORIZATION, mockAccessToken()).build());
StepVerifier.create(this.interceptor.preHandle(request, "/a"))
.consumeErrorWith((ex) -> assertThat(((CloudFoundryAuthorizationException) ex).getReason())
.isEqualTo(Reason.SERVICE_UNAVAILABLE))
.verify();
.consumeErrorWith((ex) -> assertThat(((CloudFoundryAuthorizationException) ex).getReason())
.isEqualTo(Reason.SERVICE_UNAVAILABLE))
.verify();
}
@Test
void preHandleWhenAccessIsNotAllowedShouldReturnAccessDenied() {
given(this.securityService.getAccessLevel(mockAccessToken(), "my-app-id"))
.willReturn(Mono.just(AccessLevel.RESTRICTED));
.willReturn(Mono.just(AccessLevel.RESTRICTED));
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
MockServerWebExchange request = MockServerWebExchange.from(MockServerHttpRequest.get("/a")
.header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken()).build());
.header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken())
.build());
StepVerifier.create(this.interceptor.preHandle(request, "/a"))
.consumeNextWith(
(response) -> assertThat(response.getStatus()).isEqualTo(Reason.ACCESS_DENIED.getStatus()))
.verifyComplete();
.consumeNextWith((response) -> assertThat(response.getStatus()).isEqualTo(Reason.ACCESS_DENIED.getStatus()))
.verifyComplete();
}
@Test
@@ -127,7 +131,8 @@ class ReactiveCloudFoundrySecurityInterceptorTests {
given(this.securityService.getAccessLevel(accessToken, "my-app-id")).willReturn(Mono.just(AccessLevel.FULL));
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/a")
.header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken()).build());
.header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken())
.build());
StepVerifier.create(this.interceptor.preHandle(exchange, "/a")).consumeNextWith((response) -> {
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK);
assertThat((AccessLevel) exchange.getAttribute("cloudFoundryAccessLevel")).isEqualTo(AccessLevel.FULL);
@@ -138,14 +143,15 @@ class ReactiveCloudFoundrySecurityInterceptorTests {
void preHandleSuccessfulWithRestrictedAccess() {
String accessToken = mockAccessToken();
given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
.willReturn(Mono.just(AccessLevel.RESTRICTED));
.willReturn(Mono.just(AccessLevel.RESTRICTED));
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/info")
.header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken()).build());
.header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken())
.build());
StepVerifier.create(this.interceptor.preHandle(exchange, "info")).consumeNextWith((response) -> {
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK);
assertThat((AccessLevel) exchange.getAttribute("cloudFoundryAccessLevel"))
.isEqualTo(AccessLevel.RESTRICTED);
.isEqualTo(AccessLevel.RESTRICTED);
}).verifyComplete();
}

View File

@@ -70,8 +70,9 @@ class ReactiveCloudFoundrySecurityServiceTests {
String responseBody = "{\"read_sensitive_data\": true,\"read_basic_data\": true}";
prepareResponse((response) -> response.setBody(responseBody).setHeader("Content-Type", "application/json"));
StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id"))
.consumeNextWith((accessLevel) -> assertThat(accessLevel).isEqualTo(AccessLevel.FULL)).expectComplete()
.verify();
.consumeNextWith((accessLevel) -> assertThat(accessLevel).isEqualTo(AccessLevel.FULL))
.expectComplete()
.verify();
expectRequest((request) -> {
assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token");
assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS);
@@ -83,8 +84,9 @@ class ReactiveCloudFoundrySecurityServiceTests {
String responseBody = "{\"read_sensitive_data\": false,\"read_basic_data\": true}";
prepareResponse((response) -> response.setBody(responseBody).setHeader("Content-Type", "application/json"));
StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id"))
.consumeNextWith((accessLevel) -> assertThat(accessLevel).isEqualTo(AccessLevel.RESTRICTED))
.expectComplete().verify();
.consumeNextWith((accessLevel) -> assertThat(accessLevel).isEqualTo(AccessLevel.RESTRICTED))
.expectComplete()
.verify();
expectRequest((request) -> {
assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token");
assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS);
@@ -95,11 +97,12 @@ class ReactiveCloudFoundrySecurityServiceTests {
void getAccessLevelWhenTokenIsNotValidShouldThrowException() throws Exception {
prepareResponse((response) -> response.setResponseCode(401));
StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id"))
.consumeErrorWith((throwable) -> {
assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) throwable).getReason())
.isEqualTo(Reason.INVALID_TOKEN);
}).verify();
.consumeErrorWith((throwable) -> {
assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) throwable).getReason())
.isEqualTo(Reason.INVALID_TOKEN);
})
.verify();
expectRequest((request) -> {
assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token");
assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS);
@@ -110,11 +113,12 @@ class ReactiveCloudFoundrySecurityServiceTests {
void getAccessLevelWhenForbiddenShouldThrowException() throws Exception {
prepareResponse((response) -> response.setResponseCode(403));
StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id"))
.consumeErrorWith((throwable) -> {
assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) throwable).getReason())
.isEqualTo(Reason.ACCESS_DENIED);
}).verify();
.consumeErrorWith((throwable) -> {
assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) throwable).getReason())
.isEqualTo(Reason.ACCESS_DENIED);
})
.verify();
expectRequest((request) -> {
assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token");
assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS);
@@ -125,11 +129,12 @@ class ReactiveCloudFoundrySecurityServiceTests {
void getAccessLevelWhenCloudControllerIsNotReachableThrowsException() throws Exception {
prepareResponse((response) -> response.setResponseCode(500));
StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id"))
.consumeErrorWith((throwable) -> {
assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) throwable).getReason())
.isEqualTo(Reason.SERVICE_UNAVAILABLE);
}).verify();
.consumeErrorWith((throwable) -> {
assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) throwable).getReason())
.isEqualTo(Reason.SERVICE_UNAVAILABLE);
})
.verify();
expectRequest((request) -> {
assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token");
assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS);
@@ -159,8 +164,9 @@ class ReactiveCloudFoundrySecurityServiceTests {
response.setHeader("Content-Type", "application/json");
});
StepVerifier.create(this.securityService.fetchTokenKeys())
.consumeNextWith((tokenKeys) -> assertThat(tokenKeys.get("test-key")).isEqualTo(tokenKeyValue))
.expectComplete().verify();
.consumeNextWith((tokenKeys) -> assertThat(tokenKeys.get("test-key")).isEqualTo(tokenKeyValue))
.expectComplete()
.verify();
expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-cloud-controller.com/info"));
expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-uaa.com/token_keys"));
}
@@ -177,7 +183,9 @@ class ReactiveCloudFoundrySecurityServiceTests {
response.setHeader("Content-Type", "application/json");
});
StepVerifier.create(this.securityService.fetchTokenKeys())
.consumeNextWith((tokenKeys) -> assertThat(tokenKeys).hasSize(0)).expectComplete().verify();
.consumeNextWith((tokenKeys) -> assertThat(tokenKeys).hasSize(0))
.expectComplete()
.verify();
expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-cloud-controller.com/info"));
expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-uaa.com/token_keys"));
}
@@ -190,10 +198,9 @@ class ReactiveCloudFoundrySecurityServiceTests {
});
prepareResponse((response) -> response.setResponseCode(500));
StepVerifier.create(this.securityService.fetchTokenKeys())
.consumeErrorWith(
(throwable) -> assertThat(((CloudFoundryAuthorizationException) throwable).getReason())
.isEqualTo(Reason.SERVICE_UNAVAILABLE))
.verify();
.consumeErrorWith((throwable) -> assertThat(((CloudFoundryAuthorizationException) throwable).getReason())
.isEqualTo(Reason.SERVICE_UNAVAILABLE))
.verify();
expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-cloud-controller.com/info"));
expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-uaa.com/token_keys"));
}
@@ -205,7 +212,9 @@ class ReactiveCloudFoundrySecurityServiceTests {
response.setHeader("Content-Type", "application/json");
});
StepVerifier.create(this.securityService.getUaaUrl())
.consumeNextWith((uaaUrl) -> assertThat(uaaUrl).isEqualTo(UAA_URL)).expectComplete().verify();
.consumeNextWith((uaaUrl) -> assertThat(uaaUrl).isEqualTo(UAA_URL))
.expectComplete()
.verify();
expectRequest((request) -> assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER + "/info"));
expectRequestCount(1);
}
@@ -216,7 +225,7 @@ class ReactiveCloudFoundrySecurityServiceTests {
StepVerifier.create(this.securityService.getUaaUrl()).consumeErrorWith((throwable) -> {
assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) throwable).getReason())
.isEqualTo(Reason.SERVICE_UNAVAILABLE);
.isEqualTo(Reason.SERVICE_UNAVAILABLE);
}).verify();
expectRequest((request) -> assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER + "/info"));
}

View File

@@ -105,11 +105,12 @@ class ReactiveTokenValidatorTests {
String header = "{\"alg\": \"RS256\", \"kid\": \"invalid-key\",\"typ\": \"JWT\"}";
String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
StepVerifier
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_KEY_ID);
}).verify();
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_KEY_ID);
})
.verify();
assertThat(this.tokenValidator).hasFieldOrPropertyWithValue("cachedTokenKeys", VALID_KEYS);
fetchTokenKeys.assertWasSubscribed();
}
@@ -123,8 +124,8 @@ class ReactiveTokenValidatorTests {
String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}";
String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
StepVerifier
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.verifyComplete();
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.verifyComplete();
assertThat(this.tokenValidator).hasFieldOrPropertyWithValue("cachedTokenKeys", VALID_KEYS);
fetchTokenKeys.assertWasSubscribed();
}
@@ -137,8 +138,8 @@ class ReactiveTokenValidatorTests {
String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}";
String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
StepVerifier
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.verifyComplete();
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.verifyComplete();
assertThat(this.tokenValidator).hasFieldOrPropertyWithValue("cachedTokenKeys", VALID_KEYS);
fetchTokenKeys.assertWasSubscribed();
}
@@ -151,11 +152,12 @@ class ReactiveTokenValidatorTests {
String header = "{\"alg\": \"RS256\", \"kid\": \"invalid-key\",\"typ\": \"JWT\"}";
String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
StepVerifier
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_KEY_ID);
}).verify();
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_KEY_ID);
})
.verify();
assertThat(this.tokenValidator).hasFieldOrPropertyWithValue("cachedTokenKeys", VALID_KEYS);
fetchTokenKeys.assertWasSubscribed();
}
@@ -168,8 +170,8 @@ class ReactiveTokenValidatorTests {
String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}";
String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
StepVerifier
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.verifyComplete();
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.verifyComplete();
fetchTokenKeys.assertWasNotSubscribed();
}
@@ -181,12 +183,12 @@ class ReactiveTokenValidatorTests {
String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
StepVerifier
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason())
.isEqualTo(Reason.INVALID_SIGNATURE);
}).verify();
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_SIGNATURE);
})
.verify();
}
@Test
@@ -196,12 +198,13 @@ class ReactiveTokenValidatorTests {
String header = "{ \"alg\": \"HS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
StepVerifier
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason())
.isEqualTo(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM);
}).verify();
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason())
.isEqualTo(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM);
})
.verify();
}
@Test
@@ -211,11 +214,12 @@ class ReactiveTokenValidatorTests {
String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}";
String claims = "{ \"jti\": \"0236399c350c47f3ae77e67a75e75e7d\", \"exp\": 1477509977, \"scope\": [\"actuator.read\"]}";
StepVerifier
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.TOKEN_EXPIRED);
}).verify();
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.TOKEN_EXPIRED);
})
.verify();
}
@Test
@@ -225,11 +229,12 @@ class ReactiveTokenValidatorTests {
String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\", \"scope\": [\"actuator.read\"]}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"foo.bar\"]}";
StepVerifier
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_ISSUER);
}).verify();
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_ISSUER);
})
.verify();
}
@Test
@@ -239,12 +244,12 @@ class ReactiveTokenValidatorTests {
String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"foo.bar\"]}";
StepVerifier
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason())
.isEqualTo(Reason.INVALID_AUDIENCE);
}).verify();
.create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.consumeErrorWith((ex) -> {
assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class);
assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_AUDIENCE);
})
.verify();
}
private String getSignedToken(byte[] header, byte[] claims) throws Exception {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -70,172 +70,183 @@ class CloudFoundryActuatorAutoConfigurationTests {
private static final String V3_JSON = ApiVersion.V3.getProducedMimeType().toString();
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(SecurityAutoConfiguration.class, WebMvcAutoConfiguration.class,
JacksonAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
RestTemplateAutoConfiguration.class, ManagementContextAutoConfiguration.class,
ServletManagementContextAutoConfiguration.class, EndpointAutoConfiguration.class,
WebEndpointAutoConfiguration.class, CloudFoundryActuatorAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(SecurityAutoConfiguration.class, WebMvcAutoConfiguration.class,
JacksonAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
RestTemplateAutoConfiguration.class, ManagementContextAutoConfiguration.class,
ServletManagementContextAutoConfiguration.class, EndpointAutoConfiguration.class,
WebEndpointAutoConfiguration.class, CloudFoundryActuatorAutoConfiguration.class));
@Test
void cloudFoundryPlatformActive() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com").run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
EndpointMapping endpointMapping = (EndpointMapping) ReflectionTestUtils.getField(handlerMapping,
"endpointMapping");
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"));
});
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
EndpointMapping endpointMapping = (EndpointMapping) ReflectionTestUtils.getField(handlerMapping,
"endpointMapping");
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"));
});
}
@Test
void cloudfoundryapplicationProducesActuatorMediaType() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com").run((context) -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
mockMvc.perform(get("/cloudfoundryapplication"))
.andExpect(header().string("Content-Type", V3_JSON));
});
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
mockMvc.perform(get("/cloudfoundryapplication")).andExpect(header().string("Content-Type", V3_JSON));
});
}
@Test
void cloudFoundryPlatformActiveSetsApplicationId() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com").run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
String applicationId = (String) ReflectionTestUtils.getField(interceptor, "applicationId");
assertThat(applicationId).isEqualTo("my-app-id");
});
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
String applicationId = (String) ReflectionTestUtils.getField(interceptor, "applicationId");
assertThat(applicationId).isEqualTo("my-app-id");
});
}
@Test
void cloudFoundryPlatformActiveSetsCloudControllerUrl() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com").run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
String cloudControllerUrl = (String) ReflectionTestUtils.getField(interceptorSecurityService,
"cloudControllerUrl");
assertThat(cloudControllerUrl).isEqualTo("https://my-cloud-controller.com");
});
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
"cloudFoundrySecurityService");
String cloudControllerUrl = (String) ReflectionTestUtils.getField(interceptorSecurityService,
"cloudControllerUrl");
assertThat(cloudControllerUrl).isEqualTo("https://my-cloud-controller.com");
});
}
@Test
void skipSslValidation() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://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");
RestTemplate restTemplate = (RestTemplate) ReflectionTestUtils.getField(interceptorSecurityService,
"restTemplate");
assertThat(restTemplate.getRequestFactory())
.isInstanceOf(SkipSslVerificationHttpRequestFactory.class);
});
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://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");
RestTemplate restTemplate = (RestTemplate) ReflectionTestUtils.getField(interceptorSecurityService,
"restTemplate");
assertThat(restTemplate.getRequestFactory()).isInstanceOf(SkipSslVerificationHttpRequestFactory.class);
});
}
@Test
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");
Object interceptorSecurityService = ReflectionTestUtils.getField(securityInterceptor,
"cloudFoundrySecurityService");
assertThat(interceptorSecurityService).isNull();
});
.run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
Object securityInterceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(securityInterceptor,
"cloudFoundrySecurityService");
assertThat(interceptorSecurityService).isNull();
});
}
@Test
void cloudFoundryPathsIgnoredBySpringSecurity() {
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);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath("/cloudfoundryapplication/my-path");
assertThat(chain.getFilters()).isEmpty();
assertThat(chain.matches(request)).isTrue();
request.setServletPath("/some-other-path");
assertThat(chain.matches(request)).isFalse();
});
.run((context) -> {
FilterChainProxy securityFilterChain = (FilterChainProxy) context
.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN);
SecurityFilterChain chain = securityFilterChain.getFilterChains().get(0);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath("/cloudfoundryapplication/my-path");
assertThat(chain.getFilters()).isEmpty();
assertThat(chain.matches(request)).isTrue();
request.setServletPath("/some-other-path");
assertThat(chain.matches(request)).isFalse();
});
}
@Test
void cloudFoundryPlatformInactive() {
this.contextRunner.withPropertyValues()
.run((context) -> assertThat(context.containsBean("cloudFoundryWebEndpointServletHandlerMapping"))
.isFalse());
.run((context) -> assertThat(context.containsBean("cloudFoundryWebEndpointServletHandlerMapping"))
.isFalse());
}
@Test
void cloudFoundryManagementEndpointsDisabled() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION=---", "management.cloudfoundry.enabled:false")
.run((context) -> assertThat(context.containsBean("cloudFoundryEndpointHandlerMapping")).isFalse());
.run((context) -> assertThat(context.containsBean("cloudFoundryEndpointHandlerMapping")).isFalse());
}
@Test
void allEndpointsAvailableUnderCloudFoundryWithoutExposeAllOnWeb() {
this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new).withPropertyValues("VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id", "vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping.getEndpoints();
assertThat(endpoints.stream()
.filter((candidate) -> EndpointId.of("test").equals(candidate.getEndpointId())).findFirst())
.isNotEmpty();
});
this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new)
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping.getEndpoints();
assertThat(endpoints.stream()
.filter((candidate) -> EndpointId.of("test").equals(candidate.getEndpointId()))
.findFirst()).isNotEmpty();
});
}
@Test
void endpointPathCustomizationIsNotApplied() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com",
"management.endpoints.web.path-mapping.test=custom")
.withBean(TestEndpoint.class, TestEndpoint::new).run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping.getEndpoints();
ExposableWebEndpoint endpoint = endpoints.stream()
.filter((candidate) -> EndpointId.of("test").equals(candidate.getEndpointId())).findFirst()
.get();
Collection<WebOperation> operations = endpoint.getOperations();
assertThat(operations).hasSize(1);
assertThat(operations.iterator().next().getRequestPredicate().getPath()).isEqualTo("test");
});
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com",
"management.endpoints.web.path-mapping.test=custom")
.withBean(TestEndpoint.class, TestEndpoint::new)
.run((context) -> {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping(context);
Collection<ExposableWebEndpoint> endpoints = handlerMapping.getEndpoints();
ExposableWebEndpoint endpoint = endpoints.stream()
.filter((candidate) -> EndpointId.of("test").equals(candidate.getEndpointId()))
.findFirst()
.get();
Collection<WebOperation> operations = endpoint.getOperations();
assertThat(operations).hasSize(1);
assertThat(operations.iterator().next().getRequestPredicate().getPath()).isEqualTo("test");
});
}
@Test
void healthEndpointInvokerShouldBeCloudFoundryWebExtension() {
this.contextRunner
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class,
HealthEndpointAutoConfiguration.class))
.run((context) -> {
Collection<ExposableWebEndpoint> endpoints = context
.getBean("cloudFoundryWebEndpointServletHandlerMapping",
CloudFoundryWebEndpointServletHandlerMapping.class)
.getEndpoints();
ExposableWebEndpoint endpoint = endpoints.iterator().next();
assertThat(endpoint.getOperations()).hasSize(2);
WebOperation webOperation = findOperationWithRequestPath(endpoint, "health");
assertThat(webOperation).extracting("invoker.target")
.isInstanceOf(CloudFoundryHealthEndpointWebExtension.class);
});
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class,
HealthEndpointAutoConfiguration.class))
.run((context) -> {
Collection<ExposableWebEndpoint> endpoints = context
.getBean("cloudFoundryWebEndpointServletHandlerMapping",
CloudFoundryWebEndpointServletHandlerMapping.class)
.getEndpoints();
ExposableWebEndpoint endpoint = endpoints.iterator().next();
assertThat(endpoint.getOperations()).hasSize(2);
WebOperation webOperation = findOperationWithRequestPath(endpoint, "health");
assertThat(webOperation).extracting("invoker.target")
.isInstanceOf(CloudFoundryHealthEndpointWebExtension.class);
});
}
private CloudFoundryWebEndpointServletHandlerMapping getHandlerMapping(ApplicationContext context) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -49,21 +49,21 @@ import static org.assertj.core.api.Assertions.assertThat;
class CloudFoundryHealthEndpointWebExtensionTests {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withPropertyValues("VCAP_APPLICATION={}")
.withConfiguration(AutoConfigurations.of(SecurityAutoConfiguration.class, WebMvcAutoConfiguration.class,
JacksonAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
RestTemplateAutoConfiguration.class, ManagementContextAutoConfiguration.class,
ServletManagementContextAutoConfiguration.class, EndpointAutoConfiguration.class,
WebEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class,
HealthEndpointAutoConfiguration.class, CloudFoundryActuatorAutoConfiguration.class))
.withUserConfiguration(TestHealthIndicator.class);
.withPropertyValues("VCAP_APPLICATION={}")
.withConfiguration(AutoConfigurations.of(SecurityAutoConfiguration.class, WebMvcAutoConfiguration.class,
JacksonAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
RestTemplateAutoConfiguration.class, ManagementContextAutoConfiguration.class,
ServletManagementContextAutoConfiguration.class, EndpointAutoConfiguration.class,
WebEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class,
HealthEndpointAutoConfiguration.class, CloudFoundryActuatorAutoConfiguration.class))
.withUserConfiguration(TestHealthIndicator.class);
@Test
void healthComponentsAlwaysPresent() {
this.contextRunner.run((context) -> {
CloudFoundryHealthEndpointWebExtension extension = context
.getBean(CloudFoundryHealthEndpointWebExtension.class);
.getBean(CloudFoundryHealthEndpointWebExtension.class);
HealthComponent body = extension.health(ApiVersion.V3).getBody();
HealthComponent health = ((CompositeHealth) body).getComponents().entrySet().iterator().next().getValue();
assertThat(((Health) health).getDetails()).containsEntry("spring", "boot");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2023 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.
@@ -48,22 +48,22 @@ import static org.assertj.core.api.Assertions.assertThat;
class CloudFoundryInfoEndpointWebExtensionTests {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withPropertyValues("VCAP_APPLICATION={}")
.withConfiguration(AutoConfigurations.of(SecurityAutoConfiguration.class, WebMvcAutoConfiguration.class,
JacksonAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
RestTemplateAutoConfiguration.class, ManagementContextAutoConfiguration.class,
ServletManagementContextAutoConfiguration.class, EndpointAutoConfiguration.class,
WebEndpointAutoConfiguration.class, ProjectInfoAutoConfiguration.class,
InfoContributorAutoConfiguration.class, InfoEndpointAutoConfiguration.class,
HealthEndpointAutoConfiguration.class, CloudFoundryActuatorAutoConfiguration.class));
.withPropertyValues("VCAP_APPLICATION={}")
.withConfiguration(AutoConfigurations.of(SecurityAutoConfiguration.class, WebMvcAutoConfiguration.class,
JacksonAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
RestTemplateAutoConfiguration.class, ManagementContextAutoConfiguration.class,
ServletManagementContextAutoConfiguration.class, EndpointAutoConfiguration.class,
WebEndpointAutoConfiguration.class, ProjectInfoAutoConfiguration.class,
InfoContributorAutoConfiguration.class, InfoEndpointAutoConfiguration.class,
HealthEndpointAutoConfiguration.class, CloudFoundryActuatorAutoConfiguration.class));
@Test
@SuppressWarnings("unchecked")
void gitFullDetailsAlwaysPresent() {
this.contextRunner.run((context) -> {
CloudFoundryInfoEndpointWebExtension extension = context
.getBean(CloudFoundryInfoEndpointWebExtension.class);
.getBean(CloudFoundryInfoEndpointWebExtension.class);
Map<String, Object> git = (Map<String, Object>) extension.info().get("git");
Map<String, Object> commit = (Map<String, Object>) git.get("commit");
assertThat(commit).hasSize(4);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -74,42 +74,79 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
void operationWithSecurityInterceptorForbidden() {
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
load(TestEndpointConfiguration.class,
(client) -> client.get().uri("/cfApplication/test").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken()).exchange().expectStatus()
.isEqualTo(HttpStatus.FORBIDDEN));
(client) -> client.get()
.uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange()
.expectStatus()
.isEqualTo(HttpStatus.FORBIDDEN));
}
@Test
void operationWithSecurityInterceptorSuccess() {
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
load(TestEndpointConfiguration.class,
(client) -> client.get().uri("/cfApplication/test").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken()).exchange().expectStatus()
.isEqualTo(HttpStatus.OK));
(client) -> client.get()
.uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange()
.expectStatus()
.isEqualTo(HttpStatus.OK));
}
@Test
void responseToOptionsRequestIncludesCorsHeaders() {
load(TestEndpointConfiguration.class,
(client) -> client.options().uri("/cfApplication/test").accept(MediaType.APPLICATION_JSON)
.header("Access-Control-Request-Method", "POST").header("Origin", "https://example.com")
.exchange().expectStatus().isOk().expectHeader()
.valueEquals("Access-Control-Allow-Origin", "https://example.com").expectHeader()
.valueEquals("Access-Control-Allow-Methods", "GET,POST"));
(client) -> client.options()
.uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON)
.header("Access-Control-Request-Method", "POST")
.header("Origin", "https://example.com")
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.valueEquals("Access-Control-Allow-Origin", "https://example.com")
.expectHeader()
.valueEquals("Access-Control-Allow-Methods", "GET,POST"));
}
@Test
void linksToOtherEndpointsWithFullAccess() {
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
load(TestEndpointConfiguration.class,
(client) -> client.get().uri("/cfApplication").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken()).exchange().expectStatus().isOk()
.expectBody().jsonPath("_links.length()").isEqualTo(5).jsonPath("_links.self.href").isNotEmpty()
.jsonPath("_links.self.templated").isEqualTo(false).jsonPath("_links.info.href").isNotEmpty()
.jsonPath("_links.info.templated").isEqualTo(false).jsonPath("_links.env.href").isNotEmpty()
.jsonPath("_links.env.templated").isEqualTo(false).jsonPath("_links.test.href").isNotEmpty()
.jsonPath("_links.test.templated").isEqualTo(false).jsonPath("_links.test-part.href")
.isNotEmpty().jsonPath("_links.test-part.templated").isEqualTo(true));
(client) -> client.get()
.uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange()
.expectStatus()
.isOk()
.expectBody()
.jsonPath("_links.length()")
.isEqualTo(5)
.jsonPath("_links.self.href")
.isNotEmpty()
.jsonPath("_links.self.templated")
.isEqualTo(false)
.jsonPath("_links.info.href")
.isNotEmpty()
.jsonPath("_links.info.templated")
.isEqualTo(false)
.jsonPath("_links.env.href")
.isNotEmpty()
.jsonPath("_links.env.templated")
.isEqualTo(false)
.jsonPath("_links.test.href")
.isNotEmpty()
.jsonPath("_links.test.templated")
.isEqualTo(false)
.jsonPath("_links.test-part.href")
.isNotEmpty()
.jsonPath("_links.test-part.templated")
.isEqualTo(true));
}
@Test
@@ -118,21 +155,43 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
"invalid-token");
willThrow(exception).given(tokenValidator).validate(any());
load(TestEndpointConfiguration.class,
(client) -> client.get().uri("/cfApplication").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken()).exchange().expectStatus()
.isUnauthorized());
(client) -> client.get()
.uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange()
.expectStatus()
.isUnauthorized());
}
@Test
void linksToOtherEndpointsWithRestrictedAccess() {
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
load(TestEndpointConfiguration.class,
(client) -> client.get().uri("/cfApplication").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken()).exchange().expectStatus().isOk()
.expectBody().jsonPath("_links.length()").isEqualTo(2).jsonPath("_links.self.href").isNotEmpty()
.jsonPath("_links.self.templated").isEqualTo(false).jsonPath("_links.info.href").isNotEmpty()
.jsonPath("_links.info.templated").isEqualTo(false).jsonPath("_links.env").doesNotExist()
.jsonPath("_links.test").doesNotExist().jsonPath("_links.test-part").doesNotExist());
(client) -> client.get()
.uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange()
.expectStatus()
.isOk()
.expectBody()
.jsonPath("_links.length()")
.isEqualTo(2)
.jsonPath("_links.self.href")
.isNotEmpty()
.jsonPath("_links.self.templated")
.isEqualTo(false)
.jsonPath("_links.info.href")
.isNotEmpty()
.jsonPath("_links.info.templated")
.isEqualTo(false)
.jsonPath("_links.env")
.doesNotExist()
.jsonPath("_links.test")
.doesNotExist()
.jsonPath("_links.test-part")
.doesNotExist());
}
private AnnotationConfigServletWebServerApplicationContext createApplicationContext(Class<?>... config) {
@@ -147,8 +206,11 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
BiConsumer<ApplicationContext, WebTestClient> consumer = (context, client) -> clientConsumer.accept(client);
try (AnnotationConfigServletWebServerApplicationContext context = createApplicationContext(configuration,
CloudFoundryMvcConfiguration.class)) {
consumer.accept(context, WebTestClient.bindToServer().baseUrl("http://localhost:" + getPort(context))
.responseTimeout(Duration.ofMinutes(5)).build());
consumer.accept(context,
WebTestClient.bindToServer()
.baseUrl("http://localhost:" + getPort(context))
.responseTimeout(Duration.ofMinutes(5))
.build());
}
}

View File

@@ -87,8 +87,8 @@ class CloudFoundrySecurityServiceTests {
void getAccessLevelWhenSpaceDeveloperShouldReturnFull() {
String responseBody = "{\"read_sensitive_data\": true,\"read_basic_data\": true}";
this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS))
.andExpect(header("Authorization", "bearer my-access-token"))
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
.andExpect(header("Authorization", "bearer my-access-token"))
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
AccessLevel accessLevel = this.securityService.getAccessLevel("my-access-token", "my-app-id");
this.server.verify();
assertThat(accessLevel).isEqualTo(AccessLevel.FULL);
@@ -98,8 +98,8 @@ class CloudFoundrySecurityServiceTests {
void getAccessLevelWhenNotSpaceDeveloperShouldReturnRestricted() {
String responseBody = "{\"read_sensitive_data\": false,\"read_basic_data\": true}";
this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS))
.andExpect(header("Authorization", "bearer my-access-token"))
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
.andExpect(header("Authorization", "bearer my-access-token"))
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
AccessLevel accessLevel = this.securityService.getAccessLevel("my-access-token", "my-app-id");
this.server.verify();
assertThat(accessLevel).isEqualTo(AccessLevel.RESTRICTED);
@@ -108,35 +108,37 @@ class CloudFoundrySecurityServiceTests {
@Test
void getAccessLevelWhenTokenIsNotValidShouldThrowException() {
this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS))
.andExpect(header("Authorization", "bearer my-access-token")).andRespond(withUnauthorizedRequest());
.andExpect(header("Authorization", "bearer my-access-token"))
.andRespond(withUnauthorizedRequest());
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(() -> this.securityService.getAccessLevel("my-access-token", "my-app-id"))
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
.isThrownBy(() -> this.securityService.getAccessLevel("my-access-token", "my-app-id"))
.satisfies(reasonRequirement(Reason.INVALID_TOKEN));
}
@Test
void getAccessLevelWhenForbiddenShouldThrowException() {
this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS))
.andExpect(header("Authorization", "bearer my-access-token"))
.andRespond(withStatus(HttpStatus.FORBIDDEN));
.andExpect(header("Authorization", "bearer my-access-token"))
.andRespond(withStatus(HttpStatus.FORBIDDEN));
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(() -> this.securityService.getAccessLevel("my-access-token", "my-app-id"))
.satisfies(reasonRequirement(Reason.ACCESS_DENIED));
.isThrownBy(() -> this.securityService.getAccessLevel("my-access-token", "my-app-id"))
.satisfies(reasonRequirement(Reason.ACCESS_DENIED));
}
@Test
void getAccessLevelWhenCloudControllerIsNotReachableThrowsException() {
this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS))
.andExpect(header("Authorization", "bearer my-access-token")).andRespond(withServerError());
.andExpect(header("Authorization", "bearer my-access-token"))
.andRespond(withServerError());
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(() -> this.securityService.getAccessLevel("my-access-token", "my-app-id"))
.satisfies(reasonRequirement(Reason.SERVICE_UNAVAILABLE));
.isThrownBy(() -> this.securityService.getAccessLevel("my-access-token", "my-app-id"))
.satisfies(reasonRequirement(Reason.SERVICE_UNAVAILABLE));
}
@Test
void fetchTokenKeysWhenSuccessfulShouldReturnListOfKeysFromUAA() {
this.server.expect(requestTo(CLOUD_CONTROLLER + "/info"))
.andRespond(withSuccess("{\"token_endpoint\":\"https://my-uaa.com\"}", MediaType.APPLICATION_JSON));
.andRespond(withSuccess("{\"token_endpoint\":\"https://my-uaa.com\"}", MediaType.APPLICATION_JSON));
String tokenKeyValue = """
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0m59l2u9iDnMbrXHfqkO
@@ -150,7 +152,7 @@ class CloudFoundrySecurityServiceTests {
String responseBody = "{\"keys\" : [ {\"kid\":\"test-key\",\"value\" : \"" + tokenKeyValue.replace("\n", "\\n")
+ "\"} ]}";
this.server.expect(requestTo(UAA_URL + "/token_keys"))
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
Map<String, String> tokenKeys = this.securityService.fetchTokenKeys();
this.server.verify();
assertThat(tokenKeys).containsEntry("test-key", tokenKeyValue);
@@ -159,10 +161,10 @@ class CloudFoundrySecurityServiceTests {
@Test
void fetchTokenKeysWhenNoKeysReturnedFromUAA() {
this.server.expect(requestTo(CLOUD_CONTROLLER + "/info"))
.andRespond(withSuccess("{\"token_endpoint\":\"" + UAA_URL + "\"}", MediaType.APPLICATION_JSON));
.andRespond(withSuccess("{\"token_endpoint\":\"" + UAA_URL + "\"}", MediaType.APPLICATION_JSON));
String responseBody = "{\"keys\": []}";
this.server.expect(requestTo(UAA_URL + "/token_keys"))
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
Map<String, String> tokenKeys = this.securityService.fetchTokenKeys();
this.server.verify();
assertThat(tokenKeys).isEmpty();
@@ -171,17 +173,17 @@ class CloudFoundrySecurityServiceTests {
@Test
void fetchTokenKeysWhenUnsuccessfulShouldThrowException() {
this.server.expect(requestTo(CLOUD_CONTROLLER + "/info"))
.andRespond(withSuccess("{\"token_endpoint\":\"" + UAA_URL + "\"}", MediaType.APPLICATION_JSON));
.andRespond(withSuccess("{\"token_endpoint\":\"" + UAA_URL + "\"}", MediaType.APPLICATION_JSON));
this.server.expect(requestTo(UAA_URL + "/token_keys")).andRespond(withServerError());
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(() -> this.securityService.fetchTokenKeys())
.satisfies(reasonRequirement(Reason.SERVICE_UNAVAILABLE));
.isThrownBy(() -> this.securityService.fetchTokenKeys())
.satisfies(reasonRequirement(Reason.SERVICE_UNAVAILABLE));
}
@Test
void getUaaUrlShouldCallCloudControllerInfoOnlyOnce() {
this.server.expect(requestTo(CLOUD_CONTROLLER + "/info"))
.andRespond(withSuccess("{\"token_endpoint\":\"" + UAA_URL + "\"}", MediaType.APPLICATION_JSON));
.andRespond(withSuccess("{\"token_endpoint\":\"" + UAA_URL + "\"}", MediaType.APPLICATION_JSON));
String uaaUrl = this.securityService.getUaaUrl();
this.server.verify();
assertThat(uaaUrl).isEqualTo(UAA_URL);
@@ -194,8 +196,8 @@ class CloudFoundrySecurityServiceTests {
void getUaaUrlWhenCloudControllerUrlIsNotReachableShouldThrowException() {
this.server.expect(requestTo(CLOUD_CONTROLLER + "/info")).andRespond(withServerError());
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(() -> this.securityService.getUaaUrl())
.satisfies(reasonRequirement(Reason.SERVICE_UNAVAILABLE));
.isThrownBy(() -> this.securityService.getUaaUrl())
.satisfies(reasonRequirement(Reason.SERVICE_UNAVAILABLE));
}
private Consumer<CloudFoundryAuthorizationException> reasonRequirement(Reason reason) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -39,7 +39,7 @@ class CloudFoundryWebEndpointServletHandlerMappingTests {
new CloudFoundryWebEndpointServletHandlerMappingRuntimeHints().registerHints(runtimeHints,
getClass().getClassLoader());
assertThat(RuntimeHintsPredicates.reflection().onMethod(CloudFoundryLinksHandler.class, "links"))
.accepts(runtimeHints);
.accepts(runtimeHints);
assertThat(RuntimeHintsPredicates.reflection().onType(Link.class)).accepts(runtimeHints);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2023 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.
@@ -57,8 +57,8 @@ class SkipSslVerificationHttpRequestFactoryTests {
ResponseEntity<String> responseEntity = restTemplate.getForEntity(httpsUrl, String.class);
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThatExceptionOfType(ResourceAccessException.class)
.isThrownBy(() -> otherRestTemplate.getForEntity(httpsUrl, String.class))
.withCauseInstanceOf(SSLHandshakeException.class);
.isThrownBy(() -> otherRestTemplate.getForEntity(httpsUrl, String.class))
.withCauseInstanceOf(SSLHandshakeException.class);
}
private String getHttpsUrl() {

View File

@@ -100,9 +100,10 @@ class TokenValidatorTests {
given(this.securityService.fetchTokenKeys()).willReturn(INVALID_KEYS);
String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}";
String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
assertThatExceptionOfType(CloudFoundryAuthorizationException.class).isThrownBy(
() -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.satisfies(reasonRequirement(Reason.INVALID_KEY_ID));
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(
() -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.satisfies(reasonRequirement(Reason.INVALID_KEY_ID));
}
@Test
@@ -142,18 +143,20 @@ class TokenValidatorTests {
Collections.singletonMap("valid-key", INVALID_KEY));
String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
assertThatExceptionOfType(CloudFoundryAuthorizationException.class).isThrownBy(
() -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.satisfies(reasonRequirement(Reason.INVALID_SIGNATURE));
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(
() -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.satisfies(reasonRequirement(Reason.INVALID_SIGNATURE));
}
@Test
void validateTokenWhenTokenAlgorithmIsNotRS256ShouldThrowException() {
String header = "{ \"alg\": \"HS256\", \"typ\": \"JWT\"}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
assertThatExceptionOfType(CloudFoundryAuthorizationException.class).isThrownBy(
() -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.satisfies(reasonRequirement(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM));
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(
() -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.satisfies(reasonRequirement(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM));
}
@Test
@@ -162,9 +165,10 @@ class TokenValidatorTests {
given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS);
String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}";
String claims = "{ \"jti\": \"0236399c350c47f3ae77e67a75e75e7d\", \"exp\": 1477509977, \"scope\": [\"actuator.read\"]}";
assertThatExceptionOfType(CloudFoundryAuthorizationException.class).isThrownBy(
() -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.satisfies(reasonRequirement(Reason.TOKEN_EXPIRED));
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(
() -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.satisfies(reasonRequirement(Reason.TOKEN_EXPIRED));
}
@Test
@@ -173,9 +177,10 @@ class TokenValidatorTests {
given(this.securityService.getUaaUrl()).willReturn("https://other-uaa.com");
String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\", \"scope\": [\"actuator.read\"]}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\"}";
assertThatExceptionOfType(CloudFoundryAuthorizationException.class).isThrownBy(
() -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.satisfies(reasonRequirement(Reason.INVALID_ISSUER));
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(
() -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.satisfies(reasonRequirement(Reason.INVALID_ISSUER));
}
@Test
@@ -184,9 +189,10 @@ class TokenValidatorTests {
given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa");
String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"foo.bar\"]}";
assertThatExceptionOfType(CloudFoundryAuthorizationException.class).isThrownBy(
() -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.satisfies(reasonRequirement(Reason.INVALID_AUDIENCE));
assertThatExceptionOfType(CloudFoundryAuthorizationException.class)
.isThrownBy(
() -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))))
.satisfies(reasonRequirement(Reason.INVALID_AUDIENCE));
}
private String getSignedToken(byte[] header, byte[] claims) throws Exception {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2023 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.
@@ -31,12 +31,12 @@ import static org.assertj.core.api.Assertions.assertThat;
class ConditionsReportEndpointAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ConditionsReportEndpointAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(ConditionsReportEndpointAutoConfiguration.class));
@Test
void runShouldHaveEndpointBean() {
this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=conditions")
.run((context) -> assertThat(context).hasSingleBean(ConditionsReportEndpoint.class));
.run((context) -> assertThat(context).hasSingleBean(ConditionsReportEndpoint.class));
}
@Test
@@ -47,7 +47,7 @@ class ConditionsReportEndpointAutoConfigurationTests {
@Test
void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointBean() {
this.contextRunner.withPropertyValues("management.endpoint.conditions.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(ConditionsReportEndpoint.class));
.run((context) -> assertThat(context).doesNotHaveBean(ConditionsReportEndpoint.class));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -47,8 +47,10 @@ class ConditionsReportEndpointTests {
@Test
void invoke() {
new ApplicationContextRunner().withUserConfiguration(Config.class).run((context) -> {
ContextConditionsDescriptor report = context.getBean(ConditionsReportEndpoint.class).conditions()
.getContexts().get(context.getId());
ContextConditionsDescriptor report = context.getBean(ConditionsReportEndpoint.class)
.conditions()
.getContexts()
.get(context.getId());
assertThat(report.getPositiveMatches()).isEmpty();
assertThat(report.getNegativeMatches()).containsKey("a");
assertThat(report.getUnconditionalClasses()).contains("b");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2023 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.
@@ -36,31 +36,32 @@ import static org.assertj.core.api.Assertions.assertThat;
class ShutdownEndpointAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ShutdownEndpointAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(ShutdownEndpointAutoConfiguration.class));
@Test
@SuppressWarnings("unchecked")
void runShouldHaveEndpointBeanThatIsNotDisposable() {
this.contextRunner.withPropertyValues("management.endpoint.shutdown.enabled:true")
.withPropertyValues("management.endpoints.web.exposure.include=shutdown").run((context) -> {
assertThat(context).hasSingleBean(ShutdownEndpoint.class);
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
Map<String, Object> disposableBeans = (Map<String, Object>) ReflectionTestUtils
.getField(beanFactory, "disposableBeans");
assertThat(disposableBeans).isEmpty();
});
.withPropertyValues("management.endpoints.web.exposure.include=shutdown")
.run((context) -> {
assertThat(context).hasSingleBean(ShutdownEndpoint.class);
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
Map<String, Object> disposableBeans = (Map<String, Object>) ReflectionTestUtils.getField(beanFactory,
"disposableBeans");
assertThat(disposableBeans).isEmpty();
});
}
@Test
void runWhenNotExposedShouldNotHaveEndpointBean() {
this.contextRunner.withPropertyValues("management.endpoint.shutdown.enabled:true")
.run((context) -> assertThat(context).doesNotHaveBean(ShutdownEndpoint.class));
.run((context) -> assertThat(context).doesNotHaveBean(ShutdownEndpoint.class));
}
@Test
void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointBean() {
this.contextRunner.withPropertyValues("management.endpoint.shutdown.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(ShutdownEndpoint.class));
.run((context) -> assertThat(context).doesNotHaveBean(ShutdownEndpoint.class));
}
}

View File

@@ -47,66 +47,67 @@ import static org.assertj.core.api.Assertions.assertThat;
class ConfigurationPropertiesReportEndpointAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ConfigurationPropertiesReportEndpointAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(ConfigurationPropertiesReportEndpointAutoConfiguration.class));
@Test
void runShouldHaveEndpointBean() {
this.contextRunner.withUserConfiguration(Config.class)
.withPropertyValues("management.endpoints.web.exposure.include=configprops")
.run(validateTestProperties("******", "******"));
.withPropertyValues("management.endpoints.web.exposure.include=configprops")
.run(validateTestProperties("******", "******"));
}
@Test
void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointBean() {
this.contextRunner.withPropertyValues("management.endpoint.configprops.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(ConfigurationPropertiesReportEndpoint.class));
.run((context) -> assertThat(context).doesNotHaveBean(ConfigurationPropertiesReportEndpoint.class));
}
@Test
@SuppressWarnings("unchecked")
void rolesCanBeConfiguredViaTheEnvironment() {
this.contextRunner.withUserConfiguration(Config.class)
.withPropertyValues("management.endpoint.configprops.roles: test")
.withPropertyValues("management.endpoints.web.exposure.include=configprops").run((context) -> {
assertThat(context).hasSingleBean(ConfigurationPropertiesReportEndpointWebExtension.class);
ConfigurationPropertiesReportEndpointWebExtension endpoint = context
.getBean(ConfigurationPropertiesReportEndpointWebExtension.class);
Set<String> roles = (Set<String>) ReflectionTestUtils.getField(endpoint, "roles");
assertThat(roles).contains("test");
});
.withPropertyValues("management.endpoint.configprops.roles: test")
.withPropertyValues("management.endpoints.web.exposure.include=configprops")
.run((context) -> {
assertThat(context).hasSingleBean(ConfigurationPropertiesReportEndpointWebExtension.class);
ConfigurationPropertiesReportEndpointWebExtension endpoint = context
.getBean(ConfigurationPropertiesReportEndpointWebExtension.class);
Set<String> roles = (Set<String>) ReflectionTestUtils.getField(endpoint, "roles");
assertThat(roles).contains("test");
});
}
@Test
void showValuesCanBeConfiguredViaTheEnvironment() {
this.contextRunner.withUserConfiguration(Config.class)
.withPropertyValues("management.endpoint.configprops.show-values: WHEN_AUTHORIZED")
.withPropertyValues("management.endpoints.web.exposure.include=configprops").run((context) -> {
assertThat(context).hasSingleBean(ConfigurationPropertiesReportEndpoint.class);
assertThat(context).hasSingleBean(ConfigurationPropertiesReportEndpointWebExtension.class);
ConfigurationPropertiesReportEndpointWebExtension webExtension = context
.getBean(ConfigurationPropertiesReportEndpointWebExtension.class);
ConfigurationPropertiesReportEndpoint endpoint = context
.getBean(ConfigurationPropertiesReportEndpoint.class);
Show showValuesWebExtension = (Show) ReflectionTestUtils.getField(webExtension, "showValues");
assertThat(showValuesWebExtension).isEqualTo(Show.WHEN_AUTHORIZED);
Show showValues = (Show) ReflectionTestUtils.getField(endpoint, "showValues");
assertThat(showValues).isEqualTo(Show.WHEN_AUTHORIZED);
});
.withPropertyValues("management.endpoint.configprops.show-values: WHEN_AUTHORIZED")
.withPropertyValues("management.endpoints.web.exposure.include=configprops")
.run((context) -> {
assertThat(context).hasSingleBean(ConfigurationPropertiesReportEndpoint.class);
assertThat(context).hasSingleBean(ConfigurationPropertiesReportEndpointWebExtension.class);
ConfigurationPropertiesReportEndpointWebExtension webExtension = context
.getBean(ConfigurationPropertiesReportEndpointWebExtension.class);
ConfigurationPropertiesReportEndpoint endpoint = context
.getBean(ConfigurationPropertiesReportEndpoint.class);
Show showValuesWebExtension = (Show) ReflectionTestUtils.getField(webExtension, "showValues");
assertThat(showValuesWebExtension).isEqualTo(Show.WHEN_AUTHORIZED);
Show showValues = (Show) ReflectionTestUtils.getField(endpoint, "showValues");
assertThat(showValues).isEqualTo(Show.WHEN_AUTHORIZED);
});
}
@Test
void customSanitizingFunctionsAreAppliedInOrder() {
this.contextRunner.withPropertyValues("management.endpoint.configprops.show-values: ALWAYS")
.withUserConfiguration(Config.class, SanitizingFunctionConfiguration.class)
.withPropertyValues("management.endpoints.web.exposure.include=configprops",
"test.my-test-property=abc")
.run(validateTestProperties("$$$111$$$", "$$$222$$$"));
.withUserConfiguration(Config.class, SanitizingFunctionConfiguration.class)
.withPropertyValues("management.endpoints.web.exposure.include=configprops", "test.my-test-property=abc")
.run(validateTestProperties("$$$111$$$", "$$$222$$$"));
}
@Test
void runWhenNotExposedShouldNotHaveEndpointBean() {
this.contextRunner
.run((context) -> assertThat(context).doesNotHaveBean(ConfigurationPropertiesReportEndpoint.class));
.run((context) -> assertThat(context).doesNotHaveBean(ConfigurationPropertiesReportEndpoint.class));
}
private ContextConsumer<AssertableApplicationContext> validateTestProperties(String dbPassword,
@@ -114,10 +115,13 @@ class ConfigurationPropertiesReportEndpointAutoConfigurationTests {
return (context) -> {
assertThat(context).hasSingleBean(ConfigurationPropertiesReportEndpoint.class);
ConfigurationPropertiesReportEndpoint endpoint = context
.getBean(ConfigurationPropertiesReportEndpoint.class);
.getBean(ConfigurationPropertiesReportEndpoint.class);
ConfigurationPropertiesDescriptor properties = endpoint.configurationProperties();
Map<String, Object> nestedProperties = properties.getContexts().get(context.getId()).getBeans()
.get("testProperties").getProperties();
Map<String, Object> nestedProperties = properties.getContexts()
.get(context.getId())
.getBeans()
.get("testProperties")
.getProperties();
assertThat(nestedProperties).isNotNull();
assertThat(nestedProperties).containsEntry("dbPassword", dbPassword);
assertThat(nestedProperties).containsEntry("myTestProperty", myTestProperty);
@@ -127,10 +131,10 @@ class ConfigurationPropertiesReportEndpointAutoConfigurationTests {
@Test
void runWhenOnlyExposedOverJmxShouldHaveEndpointBeanWithoutWebExtension() {
this.contextRunner
.withPropertyValues("management.endpoints.web.exposure.include=info", "spring.jmx.enabled=true",
"management.endpoints.jmx.exposure.include=configprops")
.run((context) -> assertThat(context).hasSingleBean(ConfigurationPropertiesReportEndpoint.class)
.doesNotHaveBean(ConfigurationPropertiesReportEndpointWebExtension.class));
.withPropertyValues("management.endpoints.web.exposure.include=info", "spring.jmx.enabled=true",
"management.endpoints.jmx.exposure.include=configprops")
.run((context) -> assertThat(context).hasSingleBean(ConfigurationPropertiesReportEndpoint.class)
.doesNotHaveBean(ConfigurationPropertiesReportEndpointWebExtension.class));
}
@Configuration(proxyBeanMethods = false)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2023 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.
@@ -37,19 +37,20 @@ import static org.mockito.Mockito.mock;
class CouchbaseHealthContributorAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withBean(Cluster.class, () -> mock(Cluster.class)).withConfiguration(AutoConfigurations
.of(CouchbaseHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
.withBean(Cluster.class, () -> mock(Cluster.class))
.withConfiguration(AutoConfigurations.of(CouchbaseHealthContributorAutoConfiguration.class,
HealthContributorAutoConfiguration.class));
@Test
void runShouldCreateIndicator() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(CouchbaseHealthIndicator.class)
.doesNotHaveBean(CouchbaseReactiveHealthIndicator.class));
.doesNotHaveBean(CouchbaseReactiveHealthIndicator.class));
}
@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withPropertyValues("management.health.couchbase.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(CouchbaseHealthIndicator.class));
.run((context) -> assertThat(context).doesNotHaveBean(CouchbaseHealthIndicator.class));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2023 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.
@@ -36,28 +36,29 @@ import static org.mockito.Mockito.mock;
class CouchbaseReactiveHealthContributorAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withBean(Cluster.class, () -> mock(Cluster.class))
.withConfiguration(AutoConfigurations.of(CouchbaseReactiveHealthContributorAutoConfiguration.class,
HealthContributorAutoConfiguration.class));
.withBean(Cluster.class, () -> mock(Cluster.class))
.withConfiguration(AutoConfigurations.of(CouchbaseReactiveHealthContributorAutoConfiguration.class,
HealthContributorAutoConfiguration.class));
@Test
void runShouldCreateIndicator() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(CouchbaseReactiveHealthIndicator.class)
.hasBean("couchbaseHealthContributor"));
.hasBean("couchbaseHealthContributor"));
}
@Test
void runWithRegularIndicatorShouldOnlyCreateReactiveIndicator() {
this.contextRunner.withConfiguration(AutoConfigurations.of(CouchbaseHealthContributorAutoConfiguration.class))
.run((context) -> assertThat(context).hasSingleBean(CouchbaseReactiveHealthIndicator.class)
.hasBean("couchbaseHealthContributor").doesNotHaveBean(CouchbaseHealthIndicator.class));
.run((context) -> assertThat(context).hasSingleBean(CouchbaseReactiveHealthIndicator.class)
.hasBean("couchbaseHealthContributor")
.doesNotHaveBean(CouchbaseHealthIndicator.class));
}
@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withPropertyValues("management.health.couchbase.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(CouchbaseReactiveHealthIndicator.class)
.doesNotHaveBean("couchbaseHealthContributor"));
.run((context) -> assertThat(context).doesNotHaveBean(CouchbaseReactiveHealthIndicator.class)
.doesNotHaveBean("couchbaseHealthContributor"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -38,31 +38,32 @@ import static org.assertj.core.api.Assertions.assertThat;
class ElasticsearchReactiveHealthContributorAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ElasticsearchDataAutoConfiguration.class,
ReactiveElasticsearchClientAutoConfiguration.class, ElasticsearchRestClientAutoConfiguration.class,
ElasticsearchReactiveHealthContributorAutoConfiguration.class,
HealthContributorAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(ElasticsearchDataAutoConfiguration.class,
ReactiveElasticsearchClientAutoConfiguration.class, ElasticsearchRestClientAutoConfiguration.class,
ElasticsearchReactiveHealthContributorAutoConfiguration.class,
HealthContributorAutoConfiguration.class));
@Test
void runShouldCreateIndicator() {
this.contextRunner.run((context) -> assertThat(context)
.hasSingleBean(ElasticsearchReactiveHealthIndicator.class).hasBean("elasticsearchHealthContributor"));
this.contextRunner
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchReactiveHealthIndicator.class)
.hasBean("elasticsearchHealthContributor"));
}
@Test
void runWithRegularIndicatorShouldOnlyCreateReactiveIndicator() {
this.contextRunner
.withConfiguration(AutoConfigurations.of(ElasticsearchRestHealthContributorAutoConfiguration.class))
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchReactiveHealthIndicator.class)
.hasBean("elasticsearchHealthContributor")
.doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class));
.withConfiguration(AutoConfigurations.of(ElasticsearchRestHealthContributorAutoConfiguration.class))
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchReactiveHealthIndicator.class)
.hasBean("elasticsearchHealthContributor")
.doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class));
}
@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withPropertyValues("management.health.elasticsearch.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchReactiveHealthIndicator.class)
.doesNotHaveBean("elasticsearchHealthContributor"));
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchReactiveHealthIndicator.class)
.doesNotHaveBean("elasticsearchHealthContributor"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -35,8 +35,8 @@ import static org.assertj.core.api.Assertions.assertThat;
class MongoHealthContributorAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class, MongoDataAutoConfiguration.class,
MongoHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class, MongoDataAutoConfiguration.class,
MongoHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
@Test
void runShouldCreateIndicator() {
@@ -46,7 +46,7 @@ class MongoHealthContributorAutoConfigurationTests {
@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withPropertyValues("management.health.mongo.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(MongoHealthIndicator.class));
.run((context) -> assertThat(context).doesNotHaveBean(MongoHealthIndicator.class));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -38,28 +38,29 @@ import static org.assertj.core.api.Assertions.assertThat;
class MongoReactiveHealthContributorAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class, MongoDataAutoConfiguration.class,
MongoReactiveAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class,
MongoReactiveHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class, MongoDataAutoConfiguration.class,
MongoReactiveAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class,
MongoReactiveHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
@Test
void runShouldCreateIndicator() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(MongoReactiveHealthIndicator.class)
.hasBean("mongoHealthContributor"));
.hasBean("mongoHealthContributor"));
}
@Test
void runWithRegularIndicatorShouldOnlyCreateReactiveIndicator() {
this.contextRunner.withConfiguration(AutoConfigurations.of(MongoHealthContributorAutoConfiguration.class))
.run((context) -> assertThat(context).hasSingleBean(MongoReactiveHealthIndicator.class)
.hasBean("mongoHealthContributor").doesNotHaveBean(MongoHealthIndicator.class));
.run((context) -> assertThat(context).hasSingleBean(MongoReactiveHealthIndicator.class)
.hasBean("mongoHealthContributor")
.doesNotHaveBean(MongoHealthIndicator.class));
}
@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withPropertyValues("management.health.mongo.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(MongoReactiveHealthIndicator.class)
.doesNotHaveBean("mongoHealthContributor"));
.run((context) -> assertThat(context).doesNotHaveBean(MongoReactiveHealthIndicator.class)
.doesNotHaveBean("mongoHealthContributor"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -37,20 +37,20 @@ import static org.assertj.core.api.Assertions.assertThat;
class RedisHealthContributorAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class,
RedisHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class,
RedisHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
@Test
void runShouldCreateIndicator() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(RedisHealthIndicator.class)
.doesNotHaveBean(RedisReactiveHealthIndicator.class));
.doesNotHaveBean(RedisReactiveHealthIndicator.class));
}
@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withPropertyValues("management.health.redis.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(RedisHealthIndicator.class)
.doesNotHaveBean(RedisReactiveHealthIndicator.class));
.run((context) -> assertThat(context).doesNotHaveBean(RedisHealthIndicator.class)
.doesNotHaveBean(RedisReactiveHealthIndicator.class));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -35,27 +35,28 @@ import static org.assertj.core.api.Assertions.assertThat;
class RedisReactiveHealthContributorAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class,
RedisReactiveHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class,
RedisReactiveHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
@Test
void runShouldCreateIndicator() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(RedisReactiveHealthIndicator.class)
.hasBean("redisHealthContributor"));
.hasBean("redisHealthContributor"));
}
@Test
void runWithRegularIndicatorShouldOnlyCreateReactiveIndicator() {
this.contextRunner.withConfiguration(AutoConfigurations.of(RedisHealthContributorAutoConfiguration.class))
.run((context) -> assertThat(context).hasSingleBean(RedisReactiveHealthIndicator.class)
.hasBean("redisHealthContributor").doesNotHaveBean(RedisHealthIndicator.class));
.run((context) -> assertThat(context).hasSingleBean(RedisReactiveHealthIndicator.class)
.hasBean("redisHealthContributor")
.doesNotHaveBean(RedisHealthIndicator.class));
}
@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withPropertyValues("management.health.redis.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(RedisReactiveHealthIndicator.class)
.doesNotHaveBean("redisHealthContributor"));
.run((context) -> assertThat(context).doesNotHaveBean(RedisReactiveHealthIndicator.class)
.doesNotHaveBean("redisHealthContributor"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -40,35 +40,35 @@ import static org.assertj.core.api.Assertions.assertThat;
class ElasticsearchRestHealthContributorAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class,
ElasticsearchRestHealthContributorAutoConfiguration.class,
HealthContributorAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class,
ElasticsearchRestHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
@Test
void runShouldCreateIndicator() {
this.contextRunner.run((context) -> assertThat(context)
.hasSingleBean(ElasticsearchRestClientHealthIndicator.class).hasBean("elasticsearchHealthContributor"));
this.contextRunner
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestClientHealthIndicator.class)
.hasBean("elasticsearchHealthContributor"));
}
@Test
void runWithoutRestClientShouldNotCreateIndicator() {
this.contextRunner.withClassLoader(new FilteredClassLoader(RestClient.class))
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class)
.doesNotHaveBean("elasticsearchHealthContributor"));
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class)
.doesNotHaveBean("elasticsearchHealthContributor"));
}
@Test
void runWithRestClientShouldCreateIndicator() {
this.contextRunner.withUserConfiguration(CustomRestClientConfiguration.class)
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestClientHealthIndicator.class)
.hasBean("elasticsearchHealthContributor"));
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestClientHealthIndicator.class)
.hasBean("elasticsearchHealthContributor"));
}
@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withPropertyValues("management.health.elasticsearch.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class)
.doesNotHaveBean("elasticsearchHealthContributor"));
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class)
.doesNotHaveBean("elasticsearchHealthContributor"));
}
@Configuration(proxyBeanMethods = false)

View File

@@ -47,7 +47,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
class EndpointAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EndpointAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(EndpointAutoConfiguration.class));
@Test
void mapShouldUseConfigurationConverter() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -37,172 +37,219 @@ import static org.assertj.core.api.Assertions.assertThat;
class ConditionalOnAvailableEndpointTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withUserConfiguration(AllEndpointsConfiguration.class);
.withUserConfiguration(AllEndpointsConfiguration.class);
@Test
void outcomeShouldMatchDefaults() {
this.contextRunner.run((context) -> assertThat(context).hasBean("health").doesNotHaveBean("spring")
.doesNotHaveBean("test").doesNotHaveBean("shutdown"));
this.contextRunner.run((context) -> assertThat(context).hasBean("health")
.doesNotHaveBean("spring")
.doesNotHaveBean("test")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWithEnabledByDefaultSetToFalseShouldNotMatchAnything() {
this.contextRunner.withPropertyValues("management.endpoints.enabled-by-default=false")
.run((context) -> assertThat(context).doesNotHaveBean("info").doesNotHaveBean("health")
.doesNotHaveBean("spring").doesNotHaveBean("test").doesNotHaveBean("shutdown"));
.run((context) -> assertThat(context).doesNotHaveBean("info")
.doesNotHaveBean("health")
.doesNotHaveBean("spring")
.doesNotHaveBean("test")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWhenIncludeAllWebShouldMatchEnabledEndpoints() {
this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=*")
.run((context) -> assertThat(context).hasBean("info").hasBean("health").hasBean("test")
.hasBean("spring").doesNotHaveBean("shutdown"));
.run((context) -> assertThat(context).hasBean("info")
.hasBean("health")
.hasBean("test")
.hasBean("spring")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWhenIncludeAllWebAndDisablingEndpointShouldMatchEnabledEndpoints() {
this.contextRunner
.withPropertyValues("management.endpoints.web.exposure.include=*",
"management.endpoint.test.enabled=false", "management.endpoint.health.enabled=false")
.run((context) -> assertThat(context).hasBean("info").doesNotHaveBean("health").doesNotHaveBean("test")
.hasBean("spring").doesNotHaveBean("shutdown"));
.withPropertyValues("management.endpoints.web.exposure.include=*", "management.endpoint.test.enabled=false",
"management.endpoint.health.enabled=false")
.run((context) -> assertThat(context).hasBean("info")
.doesNotHaveBean("health")
.doesNotHaveBean("test")
.hasBean("spring")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWhenIncludeAllWebAndEnablingEndpointDisabledByDefaultShouldMatchAll() {
this.contextRunner
.withPropertyValues("management.endpoints.web.exposure.include=*",
"management.endpoint.shutdown.enabled=true")
.run((context) -> assertThat(context).hasBean("info").hasBean("health").hasBean("test")
.hasBean("spring").hasBean("shutdown"));
.withPropertyValues("management.endpoints.web.exposure.include=*",
"management.endpoint.shutdown.enabled=true")
.run((context) -> assertThat(context).hasBean("info")
.hasBean("health")
.hasBean("test")
.hasBean("spring")
.hasBean("shutdown"));
}
@Test
void outcomeWhenIncludeAllJmxButJmxDisabledShouldMatchDefaults() {
this.contextRunner.withPropertyValues("management.endpoints.jmx.exposure.include=*")
.run((context) -> assertThat(context).hasBean("health").doesNotHaveBean("spring")
.doesNotHaveBean("test").doesNotHaveBean("shutdown"));
.run((context) -> assertThat(context).hasBean("health")
.doesNotHaveBean("spring")
.doesNotHaveBean("test")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWhenIncludeAllJmxAndJmxEnabledShouldMatchEnabledEndpoints() {
this.contextRunner.withPropertyValues("management.endpoints.jmx.exposure.include=*", "spring.jmx.enabled=true")
.run((context) -> assertThat(context).hasBean("info").hasBean("health").hasBean("test")
.hasBean("spring").doesNotHaveBean("shutdown"));
.run((context) -> assertThat(context).hasBean("info")
.hasBean("health")
.hasBean("test")
.hasBean("spring")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWhenIncludeAllJmxAndJmxEnabledAndEnablingEndpointDisabledByDefaultShouldMatchAll() {
this.contextRunner
.withPropertyValues("management.endpoints.jmx.exposure.include=*", "spring.jmx.enabled=true",
"management.endpoint.shutdown.enabled=true")
.run((context) -> assertThat(context).hasBean("health").hasBean("test").hasBean("spring")
.hasBean("shutdown"));
.withPropertyValues("management.endpoints.jmx.exposure.include=*", "spring.jmx.enabled=true",
"management.endpoint.shutdown.enabled=true")
.run((context) -> assertThat(context).hasBean("health")
.hasBean("test")
.hasBean("spring")
.hasBean("shutdown"));
}
@Test
void outcomeWhenIncludeAllWebAndExcludeMatchesShouldNotMatch() {
this.contextRunner
.withPropertyValues("management.endpoints.web.exposure.include=*",
"management.endpoints.web.exposure.exclude=spring,info")
.run((context) -> assertThat(context).hasBean("health").hasBean("test").doesNotHaveBean("info")
.doesNotHaveBean("spring").doesNotHaveBean("shutdown"));
.withPropertyValues("management.endpoints.web.exposure.include=*",
"management.endpoints.web.exposure.exclude=spring,info")
.run((context) -> assertThat(context).hasBean("health")
.hasBean("test")
.doesNotHaveBean("info")
.doesNotHaveBean("spring")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWhenIncludeMatchesAndExcludeMatchesShouldNotMatch() {
this.contextRunner
.withPropertyValues("management.endpoints.web.exposure.include=info,health,spring,test",
"management.endpoints.web.exposure.exclude=spring,info")
.run((context) -> assertThat(context).hasBean("health").hasBean("test").doesNotHaveBean("info")
.doesNotHaveBean("spring").doesNotHaveBean("shutdown"));
.withPropertyValues("management.endpoints.web.exposure.include=info,health,spring,test",
"management.endpoints.web.exposure.exclude=spring,info")
.run((context) -> assertThat(context).hasBean("health")
.hasBean("test")
.doesNotHaveBean("info")
.doesNotHaveBean("spring")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWhenIncludeMatchesShouldMatchEnabledEndpoints() {
this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=spring")
.run((context) -> assertThat(context).hasBean("spring").doesNotHaveBean("health")
.doesNotHaveBean("info").doesNotHaveBean("test").doesNotHaveBean("shutdown"));
.run((context) -> assertThat(context).hasBean("spring")
.doesNotHaveBean("health")
.doesNotHaveBean("info")
.doesNotHaveBean("test")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWhenIncludeMatchOnDisabledEndpointShouldNotMatch() {
this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=shutdown")
.run((context) -> assertThat(context).doesNotHaveBean("spring").doesNotHaveBean("health")
.doesNotHaveBean("info").doesNotHaveBean("test").doesNotHaveBean("shutdown"));
.run((context) -> assertThat(context).doesNotHaveBean("spring")
.doesNotHaveBean("health")
.doesNotHaveBean("info")
.doesNotHaveBean("test")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWhenIncludeMatchOnEnabledEndpointShouldNotMatch() {
this.contextRunner
.withPropertyValues("management.endpoints.web.exposure.include=shutdown",
"management.endpoint.shutdown.enabled=true")
.run((context) -> assertThat(context).doesNotHaveBean("spring").doesNotHaveBean("health")
.doesNotHaveBean("info").doesNotHaveBean("test").hasBean("shutdown"));
.withPropertyValues("management.endpoints.web.exposure.include=shutdown",
"management.endpoint.shutdown.enabled=true")
.run((context) -> assertThat(context).doesNotHaveBean("spring")
.doesNotHaveBean("health")
.doesNotHaveBean("info")
.doesNotHaveBean("test")
.hasBean("shutdown"));
}
@Test
void outcomeWhenIncludeMatchesWithCaseShouldMatch() {
this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=sPRing")
.run((context) -> assertThat(context).hasBean("spring").doesNotHaveBean("health")
.doesNotHaveBean("info").doesNotHaveBean("test").doesNotHaveBean("shutdown"));
.run((context) -> assertThat(context).hasBean("spring")
.doesNotHaveBean("health")
.doesNotHaveBean("info")
.doesNotHaveBean("test")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWhenIncludeMatchesAndExcludeAllShouldNotMatch() {
this.contextRunner
.withPropertyValues("management.endpoints.web.exposure.include=info,health,spring,test",
"management.endpoints.web.exposure.exclude=*")
.run((context) -> assertThat(context).doesNotHaveBean("health").doesNotHaveBean("info")
.doesNotHaveBean("spring").doesNotHaveBean("test").doesNotHaveBean("shutdown"));
.withPropertyValues("management.endpoints.web.exposure.include=info,health,spring,test",
"management.endpoints.web.exposure.exclude=*")
.run((context) -> assertThat(context).doesNotHaveBean("health")
.doesNotHaveBean("info")
.doesNotHaveBean("spring")
.doesNotHaveBean("test")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWhenIncludeMatchesShouldMatchWithExtensionsAndComponents() {
this.contextRunner.withUserConfiguration(ComponentEnabledIfEndpointIsExposedConfiguration.class)
.withPropertyValues("management.endpoints.web.exposure.include=spring")
.run((context) -> assertThat(context).hasBean("spring").hasBean("springComponent")
.hasBean("springExtension").doesNotHaveBean("info").doesNotHaveBean("health")
.doesNotHaveBean("test").doesNotHaveBean("shutdown"));
.withPropertyValues("management.endpoints.web.exposure.include=spring")
.run((context) -> assertThat(context).hasBean("spring")
.hasBean("springComponent")
.hasBean("springExtension")
.doesNotHaveBean("info")
.doesNotHaveBean("health")
.doesNotHaveBean("test")
.doesNotHaveBean("shutdown"));
}
@Test
void outcomeWithNoEndpointReferenceShouldFail() {
this.contextRunner.withUserConfiguration(ComponentWithNoEndpointReferenceConfiguration.class)
.withPropertyValues("management.endpoints.web.exposure.include=*").run((context) -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure().getCause().getMessage())
.contains("No endpoint is specified and the return type of the @Bean method "
+ "is neither an @Endpoint, nor an @EndpointExtension");
});
.withPropertyValues("management.endpoints.web.exposure.include=*")
.run((context) -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure().getCause().getMessage())
.contains("No endpoint is specified and the return type of the @Bean method "
+ "is neither an @Endpoint, nor an @EndpointExtension");
});
}
@Test
void outcomeOnCloudFoundryShouldMatchAll() {
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---").run(
(context) -> assertThat(context).hasBean("info").hasBean("health").hasBean("spring").hasBean("test"));
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---")
.run((context) -> assertThat(context).hasBean("info").hasBean("health").hasBean("spring").hasBean("test"));
}
@Test // gh-21044
void outcomeWhenIncludeAllShouldMatchDashedEndpoint() {
this.contextRunner.withUserConfiguration(DashedEndpointConfiguration.class)
.withPropertyValues("management.endpoints.web.exposure.include=*")
.run((context) -> assertThat(context).hasSingleBean(DashedEndpoint.class));
.withPropertyValues("management.endpoints.web.exposure.include=*")
.run((context) -> assertThat(context).hasSingleBean(DashedEndpoint.class));
}
@Test // gh-21044
void outcomeWhenIncludeDashedShouldMatchDashedEndpoint() {
this.contextRunner.withUserConfiguration(DashedEndpointConfiguration.class)
.withPropertyValues("management.endpoints.web.exposure.include=test-dashed")
.run((context) -> assertThat(context).hasSingleBean(DashedEndpoint.class));
.withPropertyValues("management.endpoints.web.exposure.include=test-dashed")
.run((context) -> assertThat(context).hasSingleBean(DashedEndpoint.class));
}
@Test
void outcomeWhenEndpointNotExposedOnSpecifiedTechnology() {
this.contextRunner.withUserConfiguration(ExposureEndpointConfiguration.class)
.withPropertyValues("spring.jmx.enabled=true", "management.endpoints.jmx.exposure.include=test",
"management.endpoints.web.exposure.exclude=test")
.run((context) -> assertThat(context).doesNotHaveBean("unexposed"));
.withPropertyValues("spring.jmx.enabled=true", "management.endpoints.jmx.exposure.include=test",
"management.endpoints.web.exposure.exclude=test")
.run((context) -> assertThat(context).doesNotHaveBean("unexposed"));
}
@Endpoint(id = "health")

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -44,31 +44,29 @@ class IncludeExcludeEndpointFilterTests {
@Test
void createWhenEndpointTypeIsNullShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new IncludeExcludeEndpointFilter<>(null, new MockEnvironment(), "foo"))
.withMessageContaining("EndpointType must not be null");
.isThrownBy(() -> new IncludeExcludeEndpointFilter<>(null, new MockEnvironment(), "foo"))
.withMessageContaining("EndpointType must not be null");
}
@Test
void createWhenEnvironmentIsNullShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new IncludeExcludeEndpointFilter<>(ExposableEndpoint.class, null, "foo"))
.withMessageContaining("Environment must not be null");
.isThrownBy(() -> new IncludeExcludeEndpointFilter<>(ExposableEndpoint.class, null, "foo"))
.withMessageContaining("Environment must not be null");
}
@Test
void createWhenPrefixIsNullShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(
() -> new IncludeExcludeEndpointFilter<>(ExposableEndpoint.class, new MockEnvironment(), null))
.withMessageContaining("Prefix must not be empty");
.isThrownBy(() -> new IncludeExcludeEndpointFilter<>(ExposableEndpoint.class, new MockEnvironment(), null))
.withMessageContaining("Prefix must not be empty");
}
@Test
void createWhenPrefixIsEmptyShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(
() -> new IncludeExcludeEndpointFilter<>(ExposableEndpoint.class, new MockEnvironment(), ""))
.withMessageContaining("Prefix must not be empty");
.isThrownBy(() -> new IncludeExcludeEndpointFilter<>(ExposableEndpoint.class, new MockEnvironment(), ""))
.withMessageContaining("Prefix must not be empty");
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -41,7 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class JacksonEndpointAutoConfigurationTests {
private final ApplicationContextRunner runner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(JacksonEndpointAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(JacksonEndpointAutoConfiguration.class));
@Test
void endpointObjectMapperWhenNoProperty() {
@@ -51,13 +51,13 @@ class JacksonEndpointAutoConfigurationTests {
@Test
void endpointObjectMapperWhenPropertyTrue() {
this.runner.withPropertyValues("management.endpoints.jackson.isolated-object-mapper=true")
.run((context) -> assertThat(context).hasSingleBean(EndpointObjectMapper.class));
.run((context) -> assertThat(context).hasSingleBean(EndpointObjectMapper.class));
}
@Test
void endpointObjectMapperWhenPropertyFalse() {
this.runner.withPropertyValues("management.endpoints.jackson.isolated-object-mapper=false")
.run((context) -> assertThat(context).doesNotHaveBean(EndpointObjectMapper.class));
.run((context) -> assertThat(context).doesNotHaveBean(EndpointObjectMapper.class));
}
@Test

Some files were not shown because too many files have changed in this diff Show More