commit
aef92b9295
2
pom.xml
2
pom.xml
|
@ -24,7 +24,7 @@
|
|||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<spring-javaformat.version>0.0.9</spring-javaformat.version>
|
||||
<spring-javaformat.version>0.0.11</spring-javaformat.version>
|
||||
<nohttp-checkstyle.version>0.0.1.RELEASE</nohttp-checkstyle.version>
|
||||
</properties>
|
||||
<build>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 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,15 +40,13 @@ public abstract class OnEndpointElementCondition extends SpringBootCondition {
|
|||
|
||||
private final Class<? extends Annotation> annotationType;
|
||||
|
||||
protected OnEndpointElementCondition(String prefix,
|
||||
Class<? extends Annotation> annotationType) {
|
||||
protected OnEndpointElementCondition(String prefix, Class<? extends Annotation> annotationType) {
|
||||
this.prefix = prefix;
|
||||
this.annotationType = annotationType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
AnnotationAttributes annotationAttributes = AnnotationAttributes
|
||||
.fromMap(metadata.getAnnotationAttributes(this.annotationType.getName()));
|
||||
String endpointName = annotationAttributes.getString("value");
|
||||
|
@ -59,25 +57,21 @@ public abstract class OnEndpointElementCondition extends SpringBootCondition {
|
|||
return getDefaultEndpointsOutcome(context);
|
||||
}
|
||||
|
||||
protected ConditionOutcome getEndpointOutcome(ConditionContext context,
|
||||
String endpointName) {
|
||||
protected ConditionOutcome getEndpointOutcome(ConditionContext context, String endpointName) {
|
||||
Environment environment = context.getEnvironment();
|
||||
String enabledProperty = this.prefix + endpointName + ".enabled";
|
||||
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));
|
||||
return new ConditionOutcome(match, ConditionMessage.forCondition(this.annotationType)
|
||||
.because(this.prefix + endpointName + ".enabled is " + match));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ConditionOutcome getDefaultEndpointsOutcome(ConditionContext context) {
|
||||
boolean match = Boolean.valueOf(context.getEnvironment()
|
||||
.getProperty(this.prefix + "defaults.enabled", "true"));
|
||||
return new ConditionOutcome(match,
|
||||
ConditionMessage.forCondition(this.annotationType).because(
|
||||
this.prefix + "defaults.enabled is considered " + match));
|
||||
boolean match = Boolean.valueOf(context.getEnvironment().getProperty(this.prefix + "defaults.enabled", "true"));
|
||||
return new ConditionOutcome(match, ConditionMessage.forCondition(this.annotationType)
|
||||
.because(this.prefix + "defaults.enabled is considered " + match));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,13 +46,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
@ConditionalOnEnabledHealthIndicator("rabbit")
|
||||
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
|
||||
@AutoConfigureAfter(RabbitAutoConfiguration.class)
|
||||
public class RabbitHealthIndicatorAutoConfiguration extends
|
||||
CompositeHealthIndicatorConfiguration<RabbitHealthIndicator, RabbitTemplate> {
|
||||
public class RabbitHealthIndicatorAutoConfiguration
|
||||
extends CompositeHealthIndicatorConfiguration<RabbitHealthIndicator, RabbitTemplate> {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "rabbitHealthIndicator")
|
||||
public HealthIndicator rabbitHealthIndicator(
|
||||
Map<String, RabbitTemplate> rabbitTemplates) {
|
||||
public HealthIndicator rabbitHealthIndicator(Map<String, RabbitTemplate> rabbitTemplates) {
|
||||
return createHealthIndicator(rabbitTemplates);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,8 +41,7 @@ import org.springframework.context.annotation.Configuration;
|
|||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnBean(AuditEventRepository.class)
|
||||
@ConditionalOnProperty(prefix = "management.auditevents", name = "enabled",
|
||||
matchIfMissing = true)
|
||||
@ConditionalOnProperty(prefix = "management.auditevents", name = "enabled", matchIfMissing = true)
|
||||
public class AuditAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
|
@ -52,16 +51,14 @@ public class AuditAutoConfiguration {
|
|||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(
|
||||
name = "org.springframework.security.authentication.event.AbstractAuthenticationEvent")
|
||||
@ConditionalOnClass(name = "org.springframework.security.authentication.event.AbstractAuthenticationEvent")
|
||||
@ConditionalOnMissingBean(AbstractAuthenticationAuditListener.class)
|
||||
public AuthenticationAuditListener authenticationAuditListener() throws Exception {
|
||||
return new AuthenticationAuditListener();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(
|
||||
name = "org.springframework.security.access.event.AbstractAuthorizationEvent")
|
||||
@ConditionalOnClass(name = "org.springframework.security.access.event.AbstractAuthorizationEvent")
|
||||
@ConditionalOnMissingBean(AbstractAuthorizationAuditListener.class)
|
||||
public AuthorizationAuditListener authorizationAuditListener() throws Exception {
|
||||
return new AuthorizationAuditListener();
|
||||
|
|
|
@ -42,8 +42,7 @@ public class AuditEventsEndpointAutoConfiguration {
|
|||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(AuditEventRepository.class)
|
||||
public AuditEventsEndpoint auditEventsEndpoint(
|
||||
AuditEventRepository auditEventRepository) {
|
||||
public AuditEventsEndpoint auditEventsEndpoint(AuditEventRepository auditEventRepository) {
|
||||
return new AuditEventsEndpoint(auditEventRepository);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,8 +36,7 @@ public class BeansEndpointAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public BeansEndpoint beansEndpoint(
|
||||
ConfigurableApplicationContext applicationContext) {
|
||||
public BeansEndpoint beansEndpoint(ConfigurableApplicationContext applicationContext) {
|
||||
return new BeansEndpoint(applicationContext);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,8 +53,7 @@ public class CachesEndpointAutoConfiguration {
|
|||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(CachesEndpoint.class)
|
||||
public CachesEndpointWebExtension cachesEndpointWebExtension(
|
||||
CachesEndpoint cachesEndpoint) {
|
||||
public CachesEndpointWebExtension cachesEndpointWebExtension(CachesEndpoint cachesEndpoint) {
|
||||
return new CachesEndpointWebExtension(cachesEndpoint);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,16 +50,14 @@ import org.springframework.data.cassandra.core.CassandraOperations;
|
|||
@ConditionalOnBean(CassandraOperations.class)
|
||||
@ConditionalOnEnabledHealthIndicator("cassandra")
|
||||
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
|
||||
@AutoConfigureAfter({ CassandraAutoConfiguration.class,
|
||||
CassandraDataAutoConfiguration.class,
|
||||
@AutoConfigureAfter({ CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class,
|
||||
CassandraReactiveHealthIndicatorAutoConfiguration.class })
|
||||
public class CassandraHealthIndicatorAutoConfiguration extends
|
||||
CompositeHealthIndicatorConfiguration<CassandraHealthIndicator, CassandraOperations> {
|
||||
public class CassandraHealthIndicatorAutoConfiguration
|
||||
extends CompositeHealthIndicatorConfiguration<CassandraHealthIndicator, CassandraOperations> {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "cassandraHealthIndicator")
|
||||
public HealthIndicator cassandraHealthIndicator(
|
||||
Map<String, CassandraOperations> cassandraOperations) {
|
||||
public HealthIndicator cassandraHealthIndicator(Map<String, CassandraOperations> cassandraOperations) {
|
||||
return createHealthIndicator(cassandraOperations);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,8 +32,7 @@ public class CloudFoundryAuthorizationException extends RuntimeException {
|
|||
this(reason, message, null);
|
||||
}
|
||||
|
||||
public CloudFoundryAuthorizationException(Reason reason, String message,
|
||||
Throwable cause) {
|
||||
public CloudFoundryAuthorizationException(Reason reason, String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.reason = reason;
|
||||
}
|
||||
|
|
|
@ -50,18 +50,16 @@ public class CloudFoundryWebEndpointDiscoverer extends WebEndpointDiscoverer {
|
|||
* @param filters filters to apply
|
||||
*/
|
||||
public CloudFoundryWebEndpointDiscoverer(ApplicationContext applicationContext,
|
||||
ParameterValueMapper parameterValueMapper,
|
||||
EndpointMediaTypes endpointMediaTypes, List<PathMapper> endpointPathMappers,
|
||||
Collection<OperationInvokerAdvisor> invokerAdvisors,
|
||||
ParameterValueMapper parameterValueMapper, EndpointMediaTypes endpointMediaTypes,
|
||||
List<PathMapper> endpointPathMappers, Collection<OperationInvokerAdvisor> invokerAdvisors,
|
||||
Collection<EndpointFilter<ExposableWebEndpoint>> filters) {
|
||||
super(applicationContext, parameterValueMapper, endpointMediaTypes,
|
||||
endpointPathMappers, invokerAdvisors, filters);
|
||||
super(applicationContext, parameterValueMapper, endpointMediaTypes, endpointPathMappers, invokerAdvisors,
|
||||
filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isExtensionExposed(Object extensionBean) {
|
||||
if (isHealthEndpointExtension(extensionBean)
|
||||
&& !isCloudFoundryHealthEndpointExtension(extensionBean)) {
|
||||
if (isHealthEndpointExtension(extensionBean) && !isCloudFoundryHealthEndpointExtension(extensionBean)) {
|
||||
// Filter regular health endpoint extensions so a CF version can replace them
|
||||
return false;
|
||||
}
|
||||
|
@ -69,14 +67,12 @@ public class CloudFoundryWebEndpointDiscoverer extends WebEndpointDiscoverer {
|
|||
}
|
||||
|
||||
private boolean isHealthEndpointExtension(Object extensionBean) {
|
||||
return MergedAnnotations.from(extensionBean.getClass())
|
||||
.get(EndpointWebExtension.class).getValue("endpoint", Class.class)
|
||||
.map(HealthEndpoint.class::isAssignableFrom).orElse(false);
|
||||
return MergedAnnotations.from(extensionBean.getClass()).get(EndpointWebExtension.class)
|
||||
.getValue("endpoint", Class.class).map(HealthEndpoint.class::isAssignableFrom).orElse(false);
|
||||
}
|
||||
|
||||
private boolean isCloudFoundryHealthEndpointExtension(Object extensionBean) {
|
||||
return MergedAnnotations.from(extensionBean.getClass())
|
||||
.isPresent(EndpointCloudFoundryExtension.class);
|
||||
return MergedAnnotations.from(extensionBean.getClass()).isPresent(EndpointCloudFoundryExtension.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,12 +61,10 @@ public class Token {
|
|||
private Map<String, Object> parseJson(String base64) {
|
||||
try {
|
||||
byte[] bytes = Base64Utils.decodeFromUrlSafeString(base64);
|
||||
return JsonParserFactory.getJsonParser()
|
||||
.parseMap(new String(bytes, StandardCharsets.UTF_8));
|
||||
return JsonParserFactory.getJsonParser().parseMap(new String(bytes, StandardCharsets.UTF_8));
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
throw new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
|
||||
"Token could not be parsed", ex);
|
||||
throw new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN, "Token could not be parsed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,8 +101,7 @@ public class Token {
|
|||
private <T> T getRequired(Map<String, Object> map, String key, Class<T> type) {
|
||||
Object value = map.get(key);
|
||||
if (value == null) {
|
||||
throw new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
|
||||
"Unable to get value from key " + key);
|
||||
throw new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN, "Unable to get value from key " + key);
|
||||
}
|
||||
if (!type.isInstance(value)) {
|
||||
throw new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
|
||||
|
|
|
@ -39,8 +39,7 @@ public class CloudFoundryReactiveHealthEndpointWebExtension {
|
|||
|
||||
private final ReactiveHealthEndpointWebExtension delegate;
|
||||
|
||||
public CloudFoundryReactiveHealthEndpointWebExtension(
|
||||
ReactiveHealthEndpointWebExtension delegate) {
|
||||
public CloudFoundryReactiveHealthEndpointWebExtension(ReactiveHealthEndpointWebExtension delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,8 +39,7 @@ import org.springframework.web.server.ServerWebExchange;
|
|||
*/
|
||||
class CloudFoundrySecurityInterceptor {
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(CloudFoundrySecurityInterceptor.class);
|
||||
private static final Log logger = LogFactory.getLog(CloudFoundrySecurityInterceptor.class);
|
||||
|
||||
private final ReactiveTokenValidator tokenValidator;
|
||||
|
||||
|
@ -48,12 +47,10 @@ class CloudFoundrySecurityInterceptor {
|
|||
|
||||
private final String applicationId;
|
||||
|
||||
private static final Mono<SecurityResponse> SUCCESS = Mono
|
||||
.just(SecurityResponse.success());
|
||||
private static final Mono<SecurityResponse> SUCCESS = Mono.just(SecurityResponse.success());
|
||||
|
||||
CloudFoundrySecurityInterceptor(ReactiveTokenValidator tokenValidator,
|
||||
ReactiveCloudFoundrySecurityService cloudFoundrySecurityService,
|
||||
String applicationId) {
|
||||
ReactiveCloudFoundrySecurityService cloudFoundrySecurityService, String applicationId) {
|
||||
this.tokenValidator = tokenValidator;
|
||||
this.cloudFoundrySecurityService = cloudFoundrySecurityService;
|
||||
this.applicationId = applicationId;
|
||||
|
@ -65,15 +62,14 @@ class CloudFoundrySecurityInterceptor {
|
|||
return SUCCESS;
|
||||
}
|
||||
if (!StringUtils.hasText(this.applicationId)) {
|
||||
return Mono.error(new CloudFoundryAuthorizationException(
|
||||
Reason.SERVICE_UNAVAILABLE, "Application id is not available"));
|
||||
return Mono.error(new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,
|
||||
"Application id is not available"));
|
||||
}
|
||||
if (this.cloudFoundrySecurityService == null) {
|
||||
return Mono.error(new CloudFoundryAuthorizationException(
|
||||
Reason.SERVICE_UNAVAILABLE, "Cloud controller URL is not available"));
|
||||
return Mono.error(new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,
|
||||
"Cloud controller URL is not available"));
|
||||
}
|
||||
return check(exchange, id).then(SUCCESS).doOnError(this::logError)
|
||||
.onErrorResume(this::getErrorResponse);
|
||||
return check(exchange, id).then(SUCCESS).doOnError(this::logError).onErrorResume(this::getErrorResponse);
|
||||
}
|
||||
|
||||
private void logError(Throwable ex) {
|
||||
|
@ -84,13 +80,11 @@ class CloudFoundrySecurityInterceptor {
|
|||
try {
|
||||
Token token = getToken(exchange.getRequest());
|
||||
return this.tokenValidator.validate(token)
|
||||
.then(this.cloudFoundrySecurityService
|
||||
.getAccessLevel(token.toString(), this.applicationId))
|
||||
.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))
|
||||
.switchIfEmpty(
|
||||
Mono.error(new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied")))
|
||||
.doOnSuccess((accessLevel) -> exchange.getAttributes().put("cloudFoundryAccessLevel", accessLevel))
|
||||
.then();
|
||||
}
|
||||
catch (CloudFoundryAuthorizationException ex) {
|
||||
|
@ -104,15 +98,13 @@ class CloudFoundrySecurityInterceptor {
|
|||
return Mono.just(new SecurityResponse(cfException.getStatusCode(),
|
||||
"{\"security_error\":\"" + cfException.getMessage() + "\"}"));
|
||||
}
|
||||
return Mono.just(new SecurityResponse(HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
throwable.getMessage()));
|
||||
return Mono.just(new SecurityResponse(HttpStatus.INTERNAL_SERVER_ERROR, throwable.getMessage()));
|
||||
}
|
||||
|
||||
private Token getToken(ServerHttpRequest request) {
|
||||
String authorization = request.getHeaders().getFirst("Authorization");
|
||||
String bearerPrefix = "bearer ";
|
||||
if (authorization == null
|
||||
|| !authorization.toLowerCase(Locale.ENGLISH).startsWith(bearerPrefix)) {
|
||||
if (authorization == null || !authorization.toLowerCase(Locale.ENGLISH).startsWith(bearerPrefix)) {
|
||||
throw new CloudFoundryAuthorizationException(Reason.MISSING_AUTHORIZATION,
|
||||
"Authorization header is missing or invalid");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,17 +50,15 @@ import org.springframework.web.server.ServerWebExchange;
|
|||
* @author Phillip Webb
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class CloudFoundryWebFluxEndpointHandlerMapping
|
||||
extends AbstractWebFluxEndpointHandlerMapping {
|
||||
class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandlerMapping {
|
||||
|
||||
private final CloudFoundrySecurityInterceptor securityInterceptor;
|
||||
|
||||
private final EndpointLinksResolver linksResolver;
|
||||
|
||||
CloudFoundryWebFluxEndpointHandlerMapping(EndpointMapping endpointMapping,
|
||||
Collection<ExposableWebEndpoint> endpoints,
|
||||
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
|
||||
CloudFoundrySecurityInterceptor securityInterceptor,
|
||||
Collection<ExposableWebEndpoint> endpoints, EndpointMediaTypes endpointMediaTypes,
|
||||
CorsConfiguration corsConfiguration, CloudFoundrySecurityInterceptor securityInterceptor,
|
||||
EndpointLinksResolver linksResolver) {
|
||||
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration);
|
||||
this.linksResolver = linksResolver;
|
||||
|
@ -68,10 +66,9 @@ class CloudFoundryWebFluxEndpointHandlerMapping
|
|||
}
|
||||
|
||||
@Override
|
||||
protected ReactiveWebOperation wrapReactiveWebOperation(ExposableWebEndpoint endpoint,
|
||||
WebOperation operation, ReactiveWebOperation reactiveWebOperation) {
|
||||
return new SecureReactiveWebOperation(reactiveWebOperation,
|
||||
this.securityInterceptor, endpoint.getEndpointId());
|
||||
protected ReactiveWebOperation wrapReactiveWebOperation(ExposableWebEndpoint endpoint, WebOperation operation,
|
||||
ReactiveWebOperation reactiveWebOperation) {
|
||||
return new SecureReactiveWebOperation(reactiveWebOperation, this.securityInterceptor, endpoint.getEndpointId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -84,30 +81,26 @@ class CloudFoundryWebFluxEndpointHandlerMapping
|
|||
@Override
|
||||
public Publisher<ResponseEntity<Object>> links(ServerWebExchange exchange) {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
return CloudFoundryWebFluxEndpointHandlerMapping.this.securityInterceptor
|
||||
.preHandle(exchange, "").map((securityResponse) -> {
|
||||
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);
|
||||
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)),
|
||||
Collections.singletonMap("_links", getAccessibleLinks(accessLevel, links)),
|
||||
HttpStatus.OK);
|
||||
});
|
||||
}
|
||||
|
||||
private Map<String, Link> getAccessibleLinks(AccessLevel accessLevel,
|
||||
Map<String, Link> links) {
|
||||
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()))
|
||||
.filter((entry) -> entry.getKey().equals("self") || accessLevel.isAccessAllowed(entry.getKey()))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
|
||||
|
@ -129,8 +122,7 @@ class CloudFoundryWebFluxEndpointHandlerMapping
|
|||
|
||||
private final EndpointId endpointId;
|
||||
|
||||
SecureReactiveWebOperation(ReactiveWebOperation delegate,
|
||||
CloudFoundrySecurityInterceptor securityInterceptor,
|
||||
SecureReactiveWebOperation(ReactiveWebOperation delegate, CloudFoundrySecurityInterceptor securityInterceptor,
|
||||
EndpointId endpointId) {
|
||||
this.delegate = delegate;
|
||||
this.securityInterceptor = securityInterceptor;
|
||||
|
@ -138,16 +130,13 @@ class CloudFoundryWebFluxEndpointHandlerMapping
|
|||
}
|
||||
|
||||
@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));
|
||||
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));
|
||||
}
|
||||
|
||||
private Mono<ResponseEntity<Object>> flatMapResponse(ServerWebExchange exchange,
|
||||
Map<String, String> body, SecurityResponse securityResponse) {
|
||||
private Mono<ResponseEntity<Object>> flatMapResponse(ServerWebExchange exchange, Map<String, String> body,
|
||||
SecurityResponse securityResponse) {
|
||||
if (!securityResponse.getStatus().equals(HttpStatus.OK)) {
|
||||
return Mono.just(new ResponseEntity<>(securityResponse.getStatus()));
|
||||
}
|
||||
|
|
|
@ -75,10 +75,8 @@ import org.springframework.web.server.WebFilter;
|
|||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(prefix = "management.cloudfoundry", name = "enabled",
|
||||
matchIfMissing = true)
|
||||
@AutoConfigureAfter({ HealthEndpointAutoConfiguration.class,
|
||||
InfoEndpointAutoConfiguration.class })
|
||||
@ConditionalOnProperty(prefix = "management.cloudfoundry", name = "enabled", matchIfMissing = true)
|
||||
@AutoConfigureAfter({ HealthEndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class })
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||
@ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY)
|
||||
public class ReactiveCloudFoundryActuatorAutoConfiguration {
|
||||
|
@ -89,21 +87,18 @@ public class ReactiveCloudFoundryActuatorAutoConfiguration {
|
|||
@ConditionalOnBean({ HealthEndpoint.class, ReactiveHealthEndpointWebExtension.class })
|
||||
public CloudFoundryReactiveHealthEndpointWebExtension cloudFoundryReactiveHealthEndpointWebExtension(
|
||||
ReactiveHealthEndpointWebExtension reactiveHealthEndpointWebExtension) {
|
||||
return new CloudFoundryReactiveHealthEndpointWebExtension(
|
||||
reactiveHealthEndpointWebExtension);
|
||||
return new CloudFoundryReactiveHealthEndpointWebExtension(reactiveHealthEndpointWebExtension);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnAvailableEndpoint
|
||||
@ConditionalOnBean({ InfoEndpoint.class, GitProperties.class })
|
||||
public CloudFoundryInfoEndpointWebExtension cloudFoundryInfoEndpointWebExtension(
|
||||
GitProperties properties, ObjectProvider<InfoContributor> infoContributors) {
|
||||
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)
|
||||
? new GitInfoContributor(properties, InfoPropertiesInfoContributor.Mode.FULL) : infoContributor)
|
||||
.collect(Collectors.toList());
|
||||
return new CloudFoundryInfoEndpointWebExtension(new InfoEndpoint(contributors));
|
||||
}
|
||||
|
@ -111,51 +106,45 @@ public class ReactiveCloudFoundryActuatorAutoConfiguration {
|
|||
@Bean
|
||||
public CloudFoundryWebFluxEndpointHandlerMapping cloudFoundryWebFluxEndpointHandlerMapping(
|
||||
ParameterValueMapper parameterMapper, EndpointMediaTypes endpointMediaTypes,
|
||||
WebClient.Builder webClientBuilder,
|
||||
ControllerEndpointsSupplier controllerEndpointsSupplier,
|
||||
WebClient.Builder webClientBuilder, ControllerEndpointsSupplier controllerEndpointsSupplier,
|
||||
ApplicationContext applicationContext) {
|
||||
CloudFoundryWebEndpointDiscoverer endpointDiscoverer = new CloudFoundryWebEndpointDiscoverer(
|
||||
applicationContext, parameterMapper, endpointMediaTypes, null,
|
||||
Collections.emptyList(), Collections.emptyList());
|
||||
CloudFoundrySecurityInterceptor securityInterceptor = getSecurityInterceptor(
|
||||
webClientBuilder, applicationContext.getEnvironment());
|
||||
CloudFoundryWebEndpointDiscoverer endpointDiscoverer = new CloudFoundryWebEndpointDiscoverer(applicationContext,
|
||||
parameterMapper, endpointMediaTypes, null, Collections.emptyList(), Collections.emptyList());
|
||||
CloudFoundrySecurityInterceptor securityInterceptor = getSecurityInterceptor(webClientBuilder,
|
||||
applicationContext.getEnvironment());
|
||||
Collection<ExposableWebEndpoint> webEndpoints = endpointDiscoverer.getEndpoints();
|
||||
List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
|
||||
allEndpoints.addAll(webEndpoints);
|
||||
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
|
||||
return new CloudFoundryWebFluxEndpointHandlerMapping(
|
||||
new EndpointMapping("/cloudfoundryapplication"), webEndpoints,
|
||||
endpointMediaTypes, getCorsConfiguration(), securityInterceptor,
|
||||
return new CloudFoundryWebFluxEndpointHandlerMapping(new EndpointMapping("/cloudfoundryapplication"),
|
||||
webEndpoints, endpointMediaTypes, getCorsConfiguration(), securityInterceptor,
|
||||
new EndpointLinksResolver(allEndpoints));
|
||||
}
|
||||
|
||||
private CloudFoundrySecurityInterceptor getSecurityInterceptor(
|
||||
WebClient.Builder webClientBuilder, Environment environment) {
|
||||
private CloudFoundrySecurityInterceptor getSecurityInterceptor(WebClient.Builder webClientBuilder,
|
||||
Environment environment) {
|
||||
ReactiveCloudFoundrySecurityService cloudfoundrySecurityService = getCloudFoundrySecurityService(
|
||||
webClientBuilder, environment);
|
||||
ReactiveTokenValidator tokenValidator = new ReactiveTokenValidator(
|
||||
cloudfoundrySecurityService);
|
||||
return new CloudFoundrySecurityInterceptor(tokenValidator,
|
||||
cloudfoundrySecurityService,
|
||||
ReactiveTokenValidator tokenValidator = new ReactiveTokenValidator(cloudfoundrySecurityService);
|
||||
return new CloudFoundrySecurityInterceptor(tokenValidator, cloudfoundrySecurityService,
|
||||
environment.getProperty("vcap.application.application_id"));
|
||||
}
|
||||
|
||||
private ReactiveCloudFoundrySecurityService getCloudFoundrySecurityService(
|
||||
WebClient.Builder webClientBuilder, Environment environment) {
|
||||
private ReactiveCloudFoundrySecurityService getCloudFoundrySecurityService(WebClient.Builder webClientBuilder,
|
||||
Environment environment) {
|
||||
String cloudControllerUrl = environment.getProperty("vcap.application.cf_api");
|
||||
boolean skipSslValidation = environment.getProperty(
|
||||
"management.cloudfoundry.skip-ssl-validation", Boolean.class, false);
|
||||
return (cloudControllerUrl != null) ? new ReactiveCloudFoundrySecurityService(
|
||||
webClientBuilder, cloudControllerUrl, skipSslValidation) : null;
|
||||
boolean skipSslValidation = environment.getProperty("management.cloudfoundry.skip-ssl-validation",
|
||||
Boolean.class, false);
|
||||
return (cloudControllerUrl != null)
|
||||
? new ReactiveCloudFoundrySecurityService(webClientBuilder, cloudControllerUrl, skipSslValidation)
|
||||
: null;
|
||||
}
|
||||
|
||||
private CorsConfiguration getCorsConfiguration() {
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL);
|
||||
corsConfiguration.setAllowedMethods(
|
||||
Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name()));
|
||||
corsConfiguration.setAllowedHeaders(
|
||||
Arrays.asList("Authorization", "X-Cf-App-Instance", "Content-Type"));
|
||||
corsConfiguration.setAllowedMethods(Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name()));
|
||||
corsConfiguration.setAllowedHeaders(Arrays.asList("Authorization", "X-Cf-App-Instance", "Content-Type"));
|
||||
return corsConfiguration;
|
||||
}
|
||||
|
||||
|
@ -173,8 +162,7 @@ public class ReactiveCloudFoundryActuatorAutoConfiguration {
|
|||
private static class WebFilterChainPostProcessor implements BeanPostProcessor {
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof WebFilterChainProxy) {
|
||||
return postProcess((WebFilterChainProxy) bean);
|
||||
}
|
||||
|
@ -188,10 +176,8 @@ public class ReactiveCloudFoundryActuatorAutoConfiguration {
|
|||
MatcherSecurityWebFilterChain ignoredRequestFilterChain = new MatcherSecurityWebFilterChain(
|
||||
cloudFoundryRequestMatcher, Collections.singletonList(noOpFilter));
|
||||
MatcherSecurityWebFilterChain allRequestsFilterChain = new MatcherSecurityWebFilterChain(
|
||||
ServerWebExchangeMatchers.anyExchange(),
|
||||
Collections.singletonList(existing));
|
||||
return new WebFilterChainProxy(ignoredRequestFilterChain,
|
||||
allRequestsFilterChain);
|
||||
ServerWebExchangeMatchers.anyExchange(), Collections.singletonList(existing));
|
||||
return new WebFilterChainProxy(ignoredRequestFilterChain, allRequestsFilterChain);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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.
|
||||
|
@ -54,8 +54,8 @@ class ReactiveCloudFoundrySecurityService {
|
|||
|
||||
private Mono<String> uaaUrl;
|
||||
|
||||
ReactiveCloudFoundrySecurityService(WebClient.Builder webClientBuilder,
|
||||
String cloudControllerUrl, boolean skipSslValidation) {
|
||||
ReactiveCloudFoundrySecurityService(WebClient.Builder webClientBuilder, String cloudControllerUrl,
|
||||
boolean skipSslValidation) {
|
||||
Assert.notNull(webClientBuilder, "Webclient must not be null");
|
||||
Assert.notNull(cloudControllerUrl, "CloudControllerUrl must not be null");
|
||||
if (skipSslValidation) {
|
||||
|
@ -66,8 +66,8 @@ class ReactiveCloudFoundrySecurityService {
|
|||
}
|
||||
|
||||
protected ReactorClientHttpConnector buildTrustAllSslConnector() {
|
||||
HttpClient client = HttpClient.create().secure(
|
||||
(sslContextSpec) -> sslContextSpec.sslContext(createSslContext()));
|
||||
HttpClient client = HttpClient.create()
|
||||
.secure((sslContextSpec) -> sslContextSpec.sslContext(createSslContext()));
|
||||
return new ReactorClientHttpConnector(client);
|
||||
}
|
||||
|
||||
|
@ -86,26 +86,21 @@ class ReactiveCloudFoundrySecurityService {
|
|||
public 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) {
|
||||
if (throwable instanceof WebClientResponseException) {
|
||||
HttpStatus statusCode = ((WebClientResponseException) throwable)
|
||||
.getStatusCode();
|
||||
HttpStatus statusCode = ((WebClientResponseException) throwable).getStatusCode();
|
||||
if (statusCode.equals(HttpStatus.FORBIDDEN)) {
|
||||
return new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED,
|
||||
"Access denied");
|
||||
return new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied");
|
||||
}
|
||||
if (statusCode.is4xxClientError()) {
|
||||
return new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
|
||||
"Invalid token", throwable);
|
||||
return new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN, "Invalid token", throwable);
|
||||
}
|
||||
}
|
||||
return new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,
|
||||
"Cloud controller not reachable");
|
||||
return new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, "Cloud controller not reachable");
|
||||
}
|
||||
|
||||
private AccessLevel getAccessLevel(Map<?, ?> body) {
|
||||
|
@ -129,9 +124,8 @@ 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) {
|
||||
|
@ -148,11 +142,9 @@ class ReactiveCloudFoundrySecurityService {
|
|||
* @return the UAA url Mono
|
||||
*/
|
||||
public Mono<String> getUaaUrl() {
|
||||
this.uaaUrl = this.webClient.get().uri(this.cloudControllerUrl + "/info")
|
||||
.retrieve().bodyToMono(Map.class)
|
||||
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,
|
||||
.onErrorMap((ex) -> new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,
|
||||
"Unable to fetch token keys from UAA."));
|
||||
return this.uaaUrl;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 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,20 +51,18 @@ class ReactiveTokenValidator {
|
|||
}
|
||||
|
||||
public 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) {
|
||||
String algorithm = token.getSignatureAlgorithm();
|
||||
if (algorithm == null) {
|
||||
return Mono.error(new CloudFoundryAuthorizationException(
|
||||
Reason.INVALID_SIGNATURE, "Signing algorithm cannot be null"));
|
||||
return Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE,
|
||||
"Signing algorithm cannot be null"));
|
||||
}
|
||||
if (!algorithm.equals("RS256")) {
|
||||
return Mono.error(new CloudFoundryAuthorizationException(
|
||||
Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM,
|
||||
return Mono.error(new CloudFoundryAuthorizationException(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM,
|
||||
"Signing algorithm " + algorithm + " not supported"));
|
||||
}
|
||||
return Mono.empty();
|
||||
|
@ -72,8 +70,8 @@ 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")))
|
||||
.switchIfEmpty(Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE,
|
||||
"RSA Signature did not match content")))
|
||||
.then();
|
||||
}
|
||||
|
||||
|
@ -84,11 +82,9 @@ class ReactiveTokenValidator {
|
|||
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")));
|
||||
.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) {
|
||||
|
@ -108,8 +104,7 @@ class ReactiveTokenValidator {
|
|||
}
|
||||
}
|
||||
|
||||
private PublicKey getPublicKey(String key)
|
||||
throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
private PublicKey getPublicKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
key = key.replace("-----BEGIN PUBLIC KEY-----\n", "");
|
||||
key = key.replace("-----END PUBLIC KEY-----", "");
|
||||
key = key.trim().replace("\n", "");
|
||||
|
@ -121,25 +116,23 @@ class ReactiveTokenValidator {
|
|||
private Mono<Void> validateExpiry(Token token) {
|
||||
long currentTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
|
||||
if (currentTime > token.getExpiry()) {
|
||||
return Mono.error(new CloudFoundryAuthorizationException(Reason.TOKEN_EXPIRED,
|
||||
"Token expired"));
|
||||
return Mono.error(new CloudFoundryAuthorizationException(Reason.TOKEN_EXPIRED, "Token expired"));
|
||||
}
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
private Mono<Void> validateIssuer(Token token) {
|
||||
return this.securityService.getUaaUrl()
|
||||
.map((uaaUrl) -> String.format("%s/oauth/token", uaaUrl))
|
||||
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")))
|
||||
.switchIfEmpty(Mono.error(
|
||||
new CloudFoundryAuthorizationException(Reason.INVALID_ISSUER, "Token issuer does not match")))
|
||||
.then();
|
||||
}
|
||||
|
||||
private Mono<Void> validateAudience(Token token) {
|
||||
if (!token.getScope().contains("actuator.read")) {
|
||||
return Mono.error(new CloudFoundryAuthorizationException(
|
||||
Reason.INVALID_AUDIENCE, "Token does not have audience actuator"));
|
||||
return Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_AUDIENCE,
|
||||
"Token does not have audience actuator"));
|
||||
}
|
||||
return Mono.empty();
|
||||
}
|
||||
|
|
|
@ -75,10 +75,9 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(prefix = "management.cloudfoundry", name = "enabled",
|
||||
matchIfMissing = true)
|
||||
@AutoConfigureAfter({ ServletManagementContextAutoConfiguration.class,
|
||||
HealthEndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class })
|
||||
@ConditionalOnProperty(prefix = "management.cloudfoundry", name = "enabled", matchIfMissing = true)
|
||||
@AutoConfigureAfter({ ServletManagementContextAutoConfiguration.class, HealthEndpointAutoConfiguration.class,
|
||||
InfoEndpointAutoConfiguration.class })
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
@ConditionalOnClass(DispatcherServlet.class)
|
||||
@ConditionalOnBean(DispatcherServlet.class)
|
||||
|
@ -98,13 +97,11 @@ public class CloudFoundryActuatorAutoConfiguration {
|
|||
@ConditionalOnMissingBean
|
||||
@ConditionalOnAvailableEndpoint
|
||||
@ConditionalOnBean({ InfoEndpoint.class, GitProperties.class })
|
||||
public CloudFoundryInfoEndpointWebExtension cloudFoundryInfoEndpointWebExtension(
|
||||
GitProperties properties, ObjectProvider<InfoContributor> infoContributors) {
|
||||
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)
|
||||
? new GitInfoContributor(properties, InfoPropertiesInfoContributor.Mode.FULL) : infoContributor)
|
||||
.collect(Collectors.toList());
|
||||
return new CloudFoundryInfoEndpointWebExtension(new InfoEndpoint(contributors));
|
||||
}
|
||||
|
@ -112,52 +109,45 @@ public class CloudFoundryActuatorAutoConfiguration {
|
|||
@Bean
|
||||
public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServletHandlerMapping(
|
||||
ParameterValueMapper parameterMapper, EndpointMediaTypes endpointMediaTypes,
|
||||
RestTemplateBuilder restTemplateBuilder,
|
||||
ServletEndpointsSupplier servletEndpointsSupplier,
|
||||
ControllerEndpointsSupplier controllerEndpointsSupplier,
|
||||
ApplicationContext applicationContext) {
|
||||
CloudFoundryWebEndpointDiscoverer discoverer = new CloudFoundryWebEndpointDiscoverer(
|
||||
applicationContext, parameterMapper, endpointMediaTypes, null,
|
||||
Collections.emptyList(), Collections.emptyList());
|
||||
CloudFoundrySecurityInterceptor securityInterceptor = getSecurityInterceptor(
|
||||
restTemplateBuilder, applicationContext.getEnvironment());
|
||||
RestTemplateBuilder restTemplateBuilder, ServletEndpointsSupplier servletEndpointsSupplier,
|
||||
ControllerEndpointsSupplier controllerEndpointsSupplier, ApplicationContext applicationContext) {
|
||||
CloudFoundryWebEndpointDiscoverer discoverer = new CloudFoundryWebEndpointDiscoverer(applicationContext,
|
||||
parameterMapper, endpointMediaTypes, null, Collections.emptyList(), Collections.emptyList());
|
||||
CloudFoundrySecurityInterceptor securityInterceptor = getSecurityInterceptor(restTemplateBuilder,
|
||||
applicationContext.getEnvironment());
|
||||
Collection<ExposableWebEndpoint> webEndpoints = discoverer.getEndpoints();
|
||||
List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
|
||||
allEndpoints.addAll(webEndpoints);
|
||||
allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
|
||||
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
|
||||
return new CloudFoundryWebEndpointServletHandlerMapping(
|
||||
new EndpointMapping("/cloudfoundryapplication"), webEndpoints,
|
||||
endpointMediaTypes, getCorsConfiguration(), securityInterceptor,
|
||||
return new CloudFoundryWebEndpointServletHandlerMapping(new EndpointMapping("/cloudfoundryapplication"),
|
||||
webEndpoints, endpointMediaTypes, getCorsConfiguration(), securityInterceptor,
|
||||
new EndpointLinksResolver(allEndpoints));
|
||||
}
|
||||
|
||||
private CloudFoundrySecurityInterceptor getSecurityInterceptor(
|
||||
RestTemplateBuilder restTemplateBuilder, Environment environment) {
|
||||
CloudFoundrySecurityService cloudfoundrySecurityService = getCloudFoundrySecurityService(
|
||||
restTemplateBuilder, environment);
|
||||
private CloudFoundrySecurityInterceptor getSecurityInterceptor(RestTemplateBuilder restTemplateBuilder,
|
||||
Environment environment) {
|
||||
CloudFoundrySecurityService cloudfoundrySecurityService = getCloudFoundrySecurityService(restTemplateBuilder,
|
||||
environment);
|
||||
TokenValidator tokenValidator = new TokenValidator(cloudfoundrySecurityService);
|
||||
return new CloudFoundrySecurityInterceptor(tokenValidator,
|
||||
cloudfoundrySecurityService,
|
||||
return new CloudFoundrySecurityInterceptor(tokenValidator, cloudfoundrySecurityService,
|
||||
environment.getProperty("vcap.application.application_id"));
|
||||
}
|
||||
|
||||
private CloudFoundrySecurityService getCloudFoundrySecurityService(
|
||||
RestTemplateBuilder restTemplateBuilder, Environment environment) {
|
||||
private CloudFoundrySecurityService getCloudFoundrySecurityService(RestTemplateBuilder restTemplateBuilder,
|
||||
Environment environment) {
|
||||
String cloudControllerUrl = environment.getProperty("vcap.application.cf_api");
|
||||
boolean skipSslValidation = environment.getProperty(
|
||||
"management.cloudfoundry.skip-ssl-validation", Boolean.class, false);
|
||||
return (cloudControllerUrl != null) ? new CloudFoundrySecurityService(
|
||||
restTemplateBuilder, cloudControllerUrl, skipSslValidation) : null;
|
||||
boolean skipSslValidation = environment.getProperty("management.cloudfoundry.skip-ssl-validation",
|
||||
Boolean.class, false);
|
||||
return (cloudControllerUrl != null)
|
||||
? new CloudFoundrySecurityService(restTemplateBuilder, cloudControllerUrl, skipSslValidation) : null;
|
||||
}
|
||||
|
||||
private CorsConfiguration getCorsConfiguration() {
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL);
|
||||
corsConfiguration.setAllowedMethods(
|
||||
Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name()));
|
||||
corsConfiguration.setAllowedHeaders(
|
||||
Arrays.asList("Authorization", "X-Cf-App-Instance", "Content-Type"));
|
||||
corsConfiguration.setAllowedMethods(Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name()));
|
||||
corsConfiguration.setAllowedHeaders(Arrays.asList("Authorization", "X-Cf-App-Instance", "Content-Type"));
|
||||
return corsConfiguration;
|
||||
}
|
||||
|
||||
|
@ -169,13 +159,11 @@ public class CloudFoundryActuatorAutoConfiguration {
|
|||
@ConditionalOnClass(WebSecurity.class)
|
||||
@Order(SecurityProperties.IGNORED_ORDER)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public static class IgnoredPathsWebSecurityConfigurer
|
||||
implements WebSecurityConfigurer<WebSecurity> {
|
||||
public static class IgnoredPathsWebSecurityConfigurer implements WebSecurityConfigurer<WebSecurity> {
|
||||
|
||||
@Override
|
||||
public void init(WebSecurity builder) throws Exception {
|
||||
builder.ignoring().requestMatchers(
|
||||
new AntPathRequestMatcher("/cloudfoundryapplication/**"));
|
||||
builder.ignoring().requestMatchers(new AntPathRequestMatcher("/cloudfoundryapplication/**"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,8 +41,7 @@ import org.springframework.web.cors.CorsUtils;
|
|||
*/
|
||||
class CloudFoundrySecurityInterceptor {
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(CloudFoundrySecurityInterceptor.class);
|
||||
private static final Log logger = LogFactory.getLog(CloudFoundrySecurityInterceptor.class);
|
||||
|
||||
private final TokenValidator tokenValidator;
|
||||
|
||||
|
@ -53,8 +52,7 @@ class CloudFoundrySecurityInterceptor {
|
|||
private static final SecurityResponse SUCCESS = SecurityResponse.success();
|
||||
|
||||
CloudFoundrySecurityInterceptor(TokenValidator tokenValidator,
|
||||
CloudFoundrySecurityService cloudFoundrySecurityService,
|
||||
String applicationId) {
|
||||
CloudFoundrySecurityService cloudFoundrySecurityService, String applicationId) {
|
||||
this.tokenValidator = tokenValidator;
|
||||
this.cloudFoundrySecurityService = cloudFoundrySecurityService;
|
||||
this.applicationId = applicationId;
|
||||
|
@ -85,22 +83,17 @@ class CloudFoundrySecurityInterceptor {
|
|||
return new SecurityResponse(cfException.getStatusCode(),
|
||||
"{\"security_error\":\"" + cfException.getMessage() + "\"}");
|
||||
}
|
||||
return new SecurityResponse(HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
ex.getMessage());
|
||||
return new SecurityResponse(HttpStatus.INTERNAL_SERVER_ERROR, ex.getMessage());
|
||||
}
|
||||
return SecurityResponse.success();
|
||||
}
|
||||
|
||||
private void check(HttpServletRequest request, EndpointId endpointId)
|
||||
throws Exception {
|
||||
private void check(HttpServletRequest request, EndpointId endpointId) throws Exception {
|
||||
Token token = getToken(request);
|
||||
this.tokenValidator.validate(token);
|
||||
AccessLevel accessLevel = this.cloudFoundrySecurityService
|
||||
.getAccessLevel(token.toString(), this.applicationId);
|
||||
if (!accessLevel.isAccessAllowed(
|
||||
(endpointId != null) ? endpointId.toLowerCaseString() : "")) {
|
||||
throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED,
|
||||
"Access denied");
|
||||
AccessLevel accessLevel = this.cloudFoundrySecurityService.getAccessLevel(token.toString(), this.applicationId);
|
||||
if (!accessLevel.isAccessAllowed((endpointId != null) ? endpointId.toLowerCaseString() : "")) {
|
||||
throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied");
|
||||
}
|
||||
request.setAttribute(AccessLevel.REQUEST_ATTRIBUTE, accessLevel);
|
||||
}
|
||||
|
@ -108,8 +101,7 @@ class CloudFoundrySecurityInterceptor {
|
|||
private Token getToken(HttpServletRequest request) {
|
||||
String authorization = request.getHeader("Authorization");
|
||||
String bearerPrefix = "bearer ";
|
||||
if (authorization == null
|
||||
|| !authorization.toLowerCase(Locale.ENGLISH).startsWith(bearerPrefix)) {
|
||||
if (authorization == null || !authorization.toLowerCase(Locale.ENGLISH).startsWith(bearerPrefix)) {
|
||||
throw new CloudFoundryAuthorizationException(Reason.MISSING_AUTHORIZATION,
|
||||
"Authorization header is missing or invalid");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 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,13 +47,12 @@ class CloudFoundrySecurityService {
|
|||
|
||||
private String uaaUrl;
|
||||
|
||||
CloudFoundrySecurityService(RestTemplateBuilder restTemplateBuilder,
|
||||
String cloudControllerUrl, boolean skipSslValidation) {
|
||||
CloudFoundrySecurityService(RestTemplateBuilder restTemplateBuilder, String cloudControllerUrl,
|
||||
boolean skipSslValidation) {
|
||||
Assert.notNull(restTemplateBuilder, "RestTemplateBuilder must not be null");
|
||||
Assert.notNull(cloudControllerUrl, "CloudControllerUrl must not be null");
|
||||
if (skipSslValidation) {
|
||||
restTemplateBuilder = restTemplateBuilder
|
||||
.requestFactory(SkipSslVerificationHttpRequestFactory.class);
|
||||
restTemplateBuilder = restTemplateBuilder.requestFactory(SkipSslVerificationHttpRequestFactory.class);
|
||||
}
|
||||
this.restTemplate = restTemplateBuilder.build();
|
||||
this.cloudControllerUrl = cloudControllerUrl;
|
||||
|
@ -66,12 +65,10 @@ class CloudFoundrySecurityService {
|
|||
* @return the access level that should be granted
|
||||
* @throws CloudFoundryAuthorizationException if the token is not authorized
|
||||
*/
|
||||
public AccessLevel getAccessLevel(String token, String applicationId)
|
||||
throws CloudFoundryAuthorizationException {
|
||||
public AccessLevel getAccessLevel(String token, String applicationId) throws CloudFoundryAuthorizationException {
|
||||
try {
|
||||
URI uri = getPermissionsUri(applicationId);
|
||||
RequestEntity<?> request = RequestEntity.get(uri)
|
||||
.header("Authorization", "bearer " + token).build();
|
||||
RequestEntity<?> request = RequestEntity.get(uri).header("Authorization", "bearer " + token).build();
|
||||
Map<?, ?> body = this.restTemplate.exchange(request, Map.class).getBody();
|
||||
if (Boolean.TRUE.equals(body.get("read_sensitive_data"))) {
|
||||
return AccessLevel.FULL;
|
||||
|
@ -80,22 +77,18 @@ class CloudFoundrySecurityService {
|
|||
}
|
||||
catch (HttpClientErrorException ex) {
|
||||
if (ex.getStatusCode().equals(HttpStatus.FORBIDDEN)) {
|
||||
throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED,
|
||||
"Access denied");
|
||||
throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied");
|
||||
}
|
||||
throw new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
|
||||
"Invalid token", ex);
|
||||
throw new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN, "Invalid token", ex);
|
||||
}
|
||||
catch (HttpServerErrorException ex) {
|
||||
throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,
|
||||
"Cloud controller not reachable");
|
||||
throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, "Cloud controller not reachable");
|
||||
}
|
||||
}
|
||||
|
||||
private URI getPermissionsUri(String applicationId) {
|
||||
try {
|
||||
return new URI(this.cloudControllerUrl + "/v2/apps/" + applicationId
|
||||
+ "/permissions");
|
||||
return new URI(this.cloudControllerUrl + "/v2/apps/" + applicationId + "/permissions");
|
||||
}
|
||||
catch (URISyntaxException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
|
@ -108,12 +101,10 @@ class CloudFoundrySecurityService {
|
|||
*/
|
||||
public Map<String, String> fetchTokenKeys() {
|
||||
try {
|
||||
return extractTokenKeys(this.restTemplate
|
||||
.getForObject(getUaaUrl() + "/token_keys", Map.class));
|
||||
return extractTokenKeys(this.restTemplate.getForObject(getUaaUrl() + "/token_keys", Map.class));
|
||||
}
|
||||
catch (HttpStatusCodeException ex) {
|
||||
throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,
|
||||
"UAA not reachable");
|
||||
throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, "UAA not reachable");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,8 +124,7 @@ class CloudFoundrySecurityService {
|
|||
public String getUaaUrl() {
|
||||
if (this.uaaUrl == null) {
|
||||
try {
|
||||
Map<?, ?> response = this.restTemplate
|
||||
.getForObject(this.cloudControllerUrl + "/info", Map.class);
|
||||
Map<?, ?> response = this.restTemplate.getForObject(this.cloudControllerUrl + "/info", Map.class);
|
||||
this.uaaUrl = (String) response.get("token_endpoint");
|
||||
}
|
||||
catch (HttpStatusCodeException ex) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,17 +49,15 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi
|
|||
* @author Phillip Webb
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class CloudFoundryWebEndpointServletHandlerMapping
|
||||
extends AbstractWebMvcEndpointHandlerMapping {
|
||||
class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpointHandlerMapping {
|
||||
|
||||
private final CloudFoundrySecurityInterceptor securityInterceptor;
|
||||
|
||||
private final EndpointLinksResolver linksResolver;
|
||||
|
||||
CloudFoundryWebEndpointServletHandlerMapping(EndpointMapping endpointMapping,
|
||||
Collection<ExposableWebEndpoint> endpoints,
|
||||
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
|
||||
CloudFoundrySecurityInterceptor securityInterceptor,
|
||||
Collection<ExposableWebEndpoint> endpoints, EndpointMediaTypes endpointMediaTypes,
|
||||
CorsConfiguration corsConfiguration, CloudFoundrySecurityInterceptor securityInterceptor,
|
||||
EndpointLinksResolver linksResolver) {
|
||||
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration);
|
||||
this.securityInterceptor = securityInterceptor;
|
||||
|
@ -67,10 +65,9 @@ class CloudFoundryWebEndpointServletHandlerMapping
|
|||
}
|
||||
|
||||
@Override
|
||||
protected ServletWebOperation wrapServletWebOperation(ExposableWebEndpoint endpoint,
|
||||
WebOperation operation, ServletWebOperation servletWebOperation) {
|
||||
return new SecureServletWebOperation(servletWebOperation,
|
||||
this.securityInterceptor, endpoint.getEndpointId());
|
||||
protected ServletWebOperation wrapServletWebOperation(ExposableWebEndpoint endpoint, WebOperation operation,
|
||||
ServletWebOperation servletWebOperation) {
|
||||
return new SecureServletWebOperation(servletWebOperation, this.securityInterceptor, endpoint.getEndpointId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -82,15 +79,13 @@ class CloudFoundryWebEndpointServletHandlerMapping
|
|||
|
||||
@Override
|
||||
@ResponseBody
|
||||
public Map<String, Map<String, Link>> links(HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
public Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
|
||||
SecurityResponse securityResponse = CloudFoundryWebEndpointServletHandlerMapping.this.securityInterceptor
|
||||
.preHandle(request, null);
|
||||
if (!securityResponse.getStatus().equals(HttpStatus.OK)) {
|
||||
sendFailureResponse(response, securityResponse);
|
||||
}
|
||||
AccessLevel accessLevel = (AccessLevel) request
|
||||
.getAttribute(AccessLevel.REQUEST_ATTRIBUTE);
|
||||
AccessLevel accessLevel = (AccessLevel) request.getAttribute(AccessLevel.REQUEST_ATTRIBUTE);
|
||||
Map<String, Link> filteredLinks = new LinkedHashMap<>();
|
||||
if (accessLevel == null) {
|
||||
return Collections.singletonMap("_links", filteredLinks);
|
||||
|
@ -98,8 +93,7 @@ class CloudFoundryWebEndpointServletHandlerMapping
|
|||
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()))
|
||||
.filter((e) -> e.getKey().equals("self") || accessLevel.isAccessAllowed(e.getKey()))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
return Collections.singletonMap("_links", filteredLinks);
|
||||
}
|
||||
|
@ -109,11 +103,9 @@ class CloudFoundryWebEndpointServletHandlerMapping
|
|||
return "Actuator root web endpoint";
|
||||
}
|
||||
|
||||
private void sendFailureResponse(HttpServletResponse response,
|
||||
SecurityResponse securityResponse) {
|
||||
private void sendFailureResponse(HttpServletResponse response, SecurityResponse securityResponse) {
|
||||
try {
|
||||
response.sendError(securityResponse.getStatus().value(),
|
||||
securityResponse.getMessage());
|
||||
response.sendError(securityResponse.getStatus().value(), securityResponse.getMessage());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.debug("Failed to send error response", ex);
|
||||
|
@ -133,8 +125,7 @@ class CloudFoundryWebEndpointServletHandlerMapping
|
|||
|
||||
private final EndpointId endpointId;
|
||||
|
||||
SecureServletWebOperation(ServletWebOperation delegate,
|
||||
CloudFoundrySecurityInterceptor securityInterceptor,
|
||||
SecureServletWebOperation(ServletWebOperation delegate, CloudFoundrySecurityInterceptor securityInterceptor,
|
||||
EndpointId endpointId) {
|
||||
this.delegate = delegate;
|
||||
this.securityInterceptor = securityInterceptor;
|
||||
|
@ -143,11 +134,9 @@ class CloudFoundryWebEndpointServletHandlerMapping
|
|||
|
||||
@Override
|
||||
public Object handle(HttpServletRequest request, Map<String, String> body) {
|
||||
SecurityResponse securityResponse = this.securityInterceptor
|
||||
.preHandle(request, this.endpointId);
|
||||
SecurityResponse securityResponse = this.securityInterceptor.preHandle(request, this.endpointId);
|
||||
if (!securityResponse.getStatus().equals(HttpStatus.OK)) {
|
||||
return new ResponseEntity<Object>(securityResponse.getMessage(),
|
||||
securityResponse.getStatus());
|
||||
return new ResponseEntity<Object>(securityResponse.getMessage(), securityResponse.getStatus());
|
||||
}
|
||||
return this.delegate.handle(request, body);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 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,8 +39,7 @@ import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
|||
class SkipSslVerificationHttpRequestFactory extends SimpleClientHttpRequestFactory {
|
||||
|
||||
@Override
|
||||
protected void prepareConnection(HttpURLConnection connection, String httpMethod)
|
||||
throws IOException {
|
||||
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
|
||||
if (connection instanceof HttpsURLConnection) {
|
||||
prepareHttpsConnection((HttpsURLConnection) connection);
|
||||
}
|
||||
|
@ -59,8 +58,7 @@ class SkipSslVerificationHttpRequestFactory extends SimpleClientHttpRequestFacto
|
|||
|
||||
private SSLSocketFactory createSslSocketFactory() throws Exception {
|
||||
SSLContext context = SSLContext.getInstance("TLS");
|
||||
context.init(null, new TrustManager[] { new SkipX509TrustManager() },
|
||||
new SecureRandom());
|
||||
context.init(null, new TrustManager[] { new SkipX509TrustManager() }, new SecureRandom());
|
||||
return context.getSocketFactory();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,12 +57,10 @@ class TokenValidator {
|
|||
private void validateAlgorithm(Token token) {
|
||||
String algorithm = token.getSignatureAlgorithm();
|
||||
if (algorithm == null) {
|
||||
throw new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE,
|
||||
"Signing algorithm cannot be null");
|
||||
throw new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE, "Signing algorithm cannot be null");
|
||||
}
|
||||
if (!algorithm.equals("RS256")) {
|
||||
throw new CloudFoundryAuthorizationException(
|
||||
Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM,
|
||||
throw new CloudFoundryAuthorizationException(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM,
|
||||
"Signing algorithm " + algorithm + " not supported");
|
||||
}
|
||||
}
|
||||
|
@ -100,8 +98,7 @@ class TokenValidator {
|
|||
}
|
||||
}
|
||||
|
||||
private PublicKey getPublicKey(String key)
|
||||
throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
private PublicKey getPublicKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
key = key.replace("-----BEGIN PUBLIC KEY-----\n", "");
|
||||
key = key.replace("-----END PUBLIC KEY-----", "");
|
||||
key = key.trim().replace("\n", "");
|
||||
|
@ -113,8 +110,7 @@ class TokenValidator {
|
|||
private void validateExpiry(Token token) {
|
||||
long currentTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
|
||||
if (currentTime > token.getExpiry()) {
|
||||
throw new CloudFoundryAuthorizationException(Reason.TOKEN_EXPIRED,
|
||||
"Token expired");
|
||||
throw new CloudFoundryAuthorizationException(Reason.TOKEN_EXPIRED, "Token expired");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,15 +64,13 @@ public class ConditionsReportEndpoint {
|
|||
Map<String, ContextConditionEvaluation> contextConditionEvaluations = new HashMap<>();
|
||||
ConfigurableApplicationContext target = this.context;
|
||||
while (target != null) {
|
||||
contextConditionEvaluations.put(target.getId(),
|
||||
new ContextConditionEvaluation(target));
|
||||
contextConditionEvaluations.put(target.getId(), new ContextConditionEvaluation(target));
|
||||
target = getConfigurableParent(target);
|
||||
}
|
||||
return new ApplicationConditionEvaluation(contextConditionEvaluations);
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext getConfigurableParent(
|
||||
ConfigurableApplicationContext context) {
|
||||
private ConfigurableApplicationContext getConfigurableParent(ConfigurableApplicationContext context) {
|
||||
ApplicationContext parent = context.getParent();
|
||||
if (parent instanceof ConfigurableApplicationContext) {
|
||||
return (ConfigurableApplicationContext) parent;
|
||||
|
@ -88,8 +86,7 @@ public class ConditionsReportEndpoint {
|
|||
|
||||
private final Map<String, ContextConditionEvaluation> contexts;
|
||||
|
||||
private ApplicationConditionEvaluation(
|
||||
Map<String, ContextConditionEvaluation> contexts) {
|
||||
private ApplicationConditionEvaluation(Map<String, ContextConditionEvaluation> contexts) {
|
||||
this.contexts = contexts;
|
||||
}
|
||||
|
||||
|
@ -117,26 +114,23 @@ public class ConditionsReportEndpoint {
|
|||
private final String parentId;
|
||||
|
||||
public ContextConditionEvaluation(ConfigurableApplicationContext context) {
|
||||
ConditionEvaluationReport report = ConditionEvaluationReport
|
||||
.get(context.getBeanFactory());
|
||||
ConditionEvaluationReport report = ConditionEvaluationReport.get(context.getBeanFactory());
|
||||
this.positiveMatches = new LinkedMultiValueMap<>();
|
||||
this.negativeMatches = new LinkedHashMap<>();
|
||||
this.exclusions = report.getExclusions();
|
||||
this.unconditionalClasses = report.getUnconditionalClasses();
|
||||
report.getConditionAndOutcomesBySource().forEach(this::add);
|
||||
this.parentId = (context.getParent() != null) ? context.getParent().getId()
|
||||
: null;
|
||||
this.parentId = (context.getParent() != null) ? context.getParent().getId() : null;
|
||||
}
|
||||
|
||||
private void add(String source, ConditionAndOutcomes conditionAndOutcomes) {
|
||||
String name = ClassUtils.getShortName(source);
|
||||
if (conditionAndOutcomes.isFullMatch()) {
|
||||
conditionAndOutcomes.forEach((conditionAndOutcome) -> this.positiveMatches
|
||||
.add(name, new MessageAndCondition(conditionAndOutcome)));
|
||||
conditionAndOutcomes.forEach((conditionAndOutcome) -> this.positiveMatches.add(name,
|
||||
new MessageAndCondition(conditionAndOutcome)));
|
||||
}
|
||||
else {
|
||||
this.negativeMatches.put(name,
|
||||
new MessageAndConditions(conditionAndOutcomes));
|
||||
this.negativeMatches.put(name, new MessageAndConditions(conditionAndOutcomes));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,8 +168,8 @@ public class ConditionsReportEndpoint {
|
|||
|
||||
public MessageAndConditions(ConditionAndOutcomes conditionAndOutcomes) {
|
||||
for (ConditionAndOutcome conditionAndOutcome : conditionAndOutcomes) {
|
||||
List<MessageAndCondition> target = (conditionAndOutcome.getOutcome()
|
||||
.isMatch() ? this.matched : this.notMatched);
|
||||
List<MessageAndCondition> target = (conditionAndOutcome.getOutcome().isMatch() ? this.matched
|
||||
: this.notMatched);
|
||||
target.add(new MessageAndCondition(conditionAndOutcome));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,8 +37,7 @@ public class ConditionsReportEndpointAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(search = SearchStrategy.CURRENT)
|
||||
public ConditionsReportEndpoint conditionsReportEndpoint(
|
||||
ConfigurableApplicationContext context) {
|
||||
public ConditionsReportEndpoint conditionsReportEndpoint(ConfigurableApplicationContext context) {
|
||||
return new ConditionsReportEndpoint(context);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,13 +49,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
@ConditionalOnEnabledHealthIndicator("couchbase")
|
||||
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
|
||||
@AutoConfigureAfter(CouchbaseAutoConfiguration.class)
|
||||
public class CouchbaseReactiveHealthIndicatorAutoConfiguration extends
|
||||
CompositeReactiveHealthIndicatorConfiguration<CouchbaseReactiveHealthIndicator, Cluster> {
|
||||
public class CouchbaseReactiveHealthIndicatorAutoConfiguration
|
||||
extends CompositeReactiveHealthIndicatorConfiguration<CouchbaseReactiveHealthIndicator, Cluster> {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "couchbaseReactiveHealthIndicator")
|
||||
public ReactiveHealthIndicator couchbaseReactiveHealthIndicator(
|
||||
Map<String, Cluster> clusters) {
|
||||
public ReactiveHealthIndicator couchbaseReactiveHealthIndicator(Map<String, Cluster> clusters) {
|
||||
return createHealthIndicator(clusters);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,13 +54,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
@AutoConfigureAfter(ElasticsearchAutoConfiguration.class)
|
||||
@EnableConfigurationProperties(ElasticsearchHealthIndicatorProperties.class)
|
||||
@Deprecated
|
||||
public class ElasticSearchClientHealthIndicatorAutoConfiguration extends
|
||||
CompositeHealthIndicatorConfiguration<ElasticsearchHealthIndicator, Client> {
|
||||
public class ElasticSearchClientHealthIndicatorAutoConfiguration
|
||||
extends CompositeHealthIndicatorConfiguration<ElasticsearchHealthIndicator, Client> {
|
||||
|
||||
private final ElasticsearchHealthIndicatorProperties properties;
|
||||
|
||||
public ElasticSearchClientHealthIndicatorAutoConfiguration(
|
||||
ElasticsearchHealthIndicatorProperties properties) {
|
||||
public ElasticSearchClientHealthIndicatorAutoConfiguration(ElasticsearchHealthIndicatorProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
|
@ -73,8 +72,7 @@ public class ElasticSearchClientHealthIndicatorAutoConfiguration extends
|
|||
@Override
|
||||
protected ElasticsearchHealthIndicator createHealthIndicator(Client client) {
|
||||
Duration responseTimeout = this.properties.getResponseTimeout();
|
||||
return new ElasticsearchHealthIndicator(client,
|
||||
(responseTimeout != null) ? responseTimeout.toMillis() : 100,
|
||||
return new ElasticsearchHealthIndicator(client, (responseTimeout != null) ? responseTimeout.toMillis() : 100,
|
||||
this.properties.getIndices());
|
||||
}
|
||||
|
||||
|
|
|
@ -48,11 +48,10 @@ import org.springframework.context.annotation.Configuration;
|
|||
@ConditionalOnBean(JestClient.class)
|
||||
@ConditionalOnEnabledHealthIndicator("elasticsearch")
|
||||
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
|
||||
@AutoConfigureAfter({ JestAutoConfiguration.class,
|
||||
ElasticSearchClientHealthIndicatorAutoConfiguration.class })
|
||||
@AutoConfigureAfter({ JestAutoConfiguration.class, ElasticSearchClientHealthIndicatorAutoConfiguration.class })
|
||||
@Deprecated
|
||||
public class ElasticSearchJestHealthIndicatorAutoConfiguration extends
|
||||
CompositeHealthIndicatorConfiguration<ElasticsearchJestHealthIndicator, JestClient> {
|
||||
public class ElasticSearchJestHealthIndicatorAutoConfiguration
|
||||
extends CompositeHealthIndicatorConfiguration<ElasticsearchJestHealthIndicator, JestClient> {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "elasticsearchHealthIndicator")
|
||||
|
|
|
@ -47,16 +47,14 @@ import org.springframework.context.annotation.Configuration;
|
|||
@ConditionalOnBean(RestClient.class)
|
||||
@ConditionalOnEnabledHealthIndicator("elasticsearch")
|
||||
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
|
||||
@AutoConfigureAfter({ RestClientAutoConfiguration.class,
|
||||
ElasticSearchClientHealthIndicatorAutoConfiguration.class })
|
||||
@AutoConfigureAfter({ RestClientAutoConfiguration.class, ElasticSearchClientHealthIndicatorAutoConfiguration.class })
|
||||
@SuppressWarnings("deprecation")
|
||||
public class ElasticSearchRestHealthIndicatorAutoConfiguration extends
|
||||
CompositeHealthIndicatorConfiguration<ElasticsearchRestHealthIndicator, RestClient> {
|
||||
public class ElasticSearchRestHealthIndicatorAutoConfiguration
|
||||
extends CompositeHealthIndicatorConfiguration<ElasticsearchRestHealthIndicator, RestClient> {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "elasticsearchRestHealthIndicator")
|
||||
public HealthIndicator elasticsearchRestHealthIndicator(
|
||||
Map<String, RestClient> clients) {
|
||||
public HealthIndicator elasticsearchRestHealthIndicator(Map<String, RestClient> clients) {
|
||||
return createHealthIndicator(clients);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,7 @@ import org.springframework.boot.context.properties.DeprecatedConfigurationProper
|
|||
* @deprecated since 2.2.0 as {@literal org.elasticsearch.client:transport} has been
|
||||
* deprecated upstream
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "management.health.elasticsearch",
|
||||
ignoreUnknownFields = false)
|
||||
@ConfigurationProperties(prefix = "management.health.elasticsearch", ignoreUnknownFields = false)
|
||||
@Deprecated
|
||||
public class ElasticsearchHealthIndicatorProperties {
|
||||
|
||||
|
@ -48,8 +47,7 @@ public class ElasticsearchHealthIndicatorProperties {
|
|||
*/
|
||||
private Duration responseTimeout = Duration.ofMillis(100);
|
||||
|
||||
@DeprecatedConfigurationProperty(
|
||||
reason = "Upstream elasticsearch transport is deprected")
|
||||
@DeprecatedConfigurationProperty(reason = "Upstream elasticsearch transport is deprected")
|
||||
public List<String> getIndices() {
|
||||
return this.indices;
|
||||
}
|
||||
|
@ -58,8 +56,7 @@ public class ElasticsearchHealthIndicatorProperties {
|
|||
this.indices = indices;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(
|
||||
reason = "Upstream elasticsearch transport is deprected")
|
||||
@DeprecatedConfigurationProperty(reason = "Upstream elasticsearch transport is deprected")
|
||||
public Duration getResponseTimeout() {
|
||||
return this.responseTimeout;
|
||||
}
|
||||
|
|
|
@ -45,10 +45,8 @@ public class EndpointAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public CachingOperationInvokerAdvisor endpointCachingOperationInvokerAdvisor(
|
||||
Environment environment) {
|
||||
return new CachingOperationInvokerAdvisor(
|
||||
new EndpointIdTimeToLivePropertyFunction(environment));
|
||||
public CachingOperationInvokerAdvisor endpointCachingOperationInvokerAdvisor(Environment environment) {
|
||||
return new CachingOperationInvokerAdvisor(new EndpointIdTimeToLivePropertyFunction(environment));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,8 +50,7 @@ class EndpointIdTimeToLivePropertyFunction implements Function<EndpointId, Long>
|
|||
|
||||
@Override
|
||||
public Long apply(EndpointId endpointId) {
|
||||
String name = String.format("management.endpoint.%s.cache.time-to-live",
|
||||
endpointId.toLowerCaseString());
|
||||
String name = String.format("management.endpoint.%s.cache.time-to-live", endpointId.toLowerCaseString());
|
||||
BindResult<Duration> duration = Binder.get(this.environment).bind(name, DURATION);
|
||||
return duration.map(Duration::toMillis).orElse(null);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,8 +41,7 @@ import org.springframework.util.Assert;
|
|||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class ExposeExcludePropertyEndpointFilter<E extends ExposableEndpoint<?>>
|
||||
implements EndpointFilter<E> {
|
||||
public class ExposeExcludePropertyEndpointFilter<E extends ExposableEndpoint<?>> implements EndpointFilter<E> {
|
||||
|
||||
private final Class<E> endpointType;
|
||||
|
||||
|
@ -52,8 +51,8 @@ public class ExposeExcludePropertyEndpointFilter<E extends ExposableEndpoint<?>>
|
|||
|
||||
private final Set<String> exposeDefaults;
|
||||
|
||||
public ExposeExcludePropertyEndpointFilter(Class<E> endpointType,
|
||||
Environment environment, String prefix, String... exposeDefaults) {
|
||||
public ExposeExcludePropertyEndpointFilter(Class<E> endpointType, Environment environment, String prefix,
|
||||
String... exposeDefaults) {
|
||||
Assert.notNull(endpointType, "EndpointType must not be null");
|
||||
Assert.notNull(environment, "Environment must not be null");
|
||||
Assert.hasText(prefix, "Prefix must not be empty");
|
||||
|
@ -64,9 +63,8 @@ public class ExposeExcludePropertyEndpointFilter<E extends ExposableEndpoint<?>>
|
|||
this.exposeDefaults = asSet(Arrays.asList(exposeDefaults));
|
||||
}
|
||||
|
||||
public ExposeExcludePropertyEndpointFilter(Class<E> endpointType,
|
||||
Collection<String> include, Collection<String> exclude,
|
||||
String... exposeDefaults) {
|
||||
public ExposeExcludePropertyEndpointFilter(Class<E> endpointType, Collection<String> include,
|
||||
Collection<String> exclude, String... exposeDefaults) {
|
||||
Assert.notNull(endpointType, "EndpointType Type must not be null");
|
||||
this.endpointType = endpointType;
|
||||
this.include = asSet(include);
|
||||
|
@ -75,8 +73,7 @@ public class ExposeExcludePropertyEndpointFilter<E extends ExposableEndpoint<?>>
|
|||
}
|
||||
|
||||
private Set<String> bind(Binder binder, String name) {
|
||||
return asSet(binder.bind(name, Bindable.listOf(String.class)).map(this::cleanup)
|
||||
.orElseGet(ArrayList::new));
|
||||
return asSet(binder.bind(name, Bindable.listOf(String.class)).map(this::cleanup).orElseGet(ArrayList::new));
|
||||
}
|
||||
|
||||
private List<String> cleanup(List<String> values) {
|
||||
|
@ -84,16 +81,14 @@ public class ExposeExcludePropertyEndpointFilter<E extends ExposableEndpoint<?>>
|
|||
}
|
||||
|
||||
private String cleanup(String value) {
|
||||
return "*".equals(value) ? "*"
|
||||
: EndpointId.fromPropertyValue(value).toLowerCaseString();
|
||||
return "*".equals(value) ? "*" : EndpointId.fromPropertyValue(value).toLowerCaseString();
|
||||
}
|
||||
|
||||
private Set<String> asSet(Collection<String> items) {
|
||||
if (items == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return items.stream().map((item) -> item.toLowerCase(Locale.ENGLISH))
|
||||
.collect(Collectors.toSet());
|
||||
return items.stream().map((item) -> item.toLowerCase(Locale.ENGLISH)).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -106,8 +101,7 @@ public class ExposeExcludePropertyEndpointFilter<E extends ExposableEndpoint<?>>
|
|||
|
||||
private boolean isExposed(ExposableEndpoint<?> endpoint) {
|
||||
if (this.include.isEmpty()) {
|
||||
return this.exposeDefaults.contains("*")
|
||||
|| contains(this.exposeDefaults, endpoint);
|
||||
return this.exposeDefaults.contains("*") || contains(this.exposeDefaults, endpoint);
|
||||
}
|
||||
return this.include.contains("*") || contains(this.include, endpoint);
|
||||
}
|
||||
|
|
|
@ -53,85 +53,69 @@ abstract class AbstractEndpointCondition extends SpringBootCondition {
|
|||
|
||||
private static final ConcurrentReferenceHashMap<Environment, Optional<Boolean>> enabledByDefaultCache = new ConcurrentReferenceHashMap<>();
|
||||
|
||||
AnnotationAttributes getEndpointAttributes(Class<?> annotationClass,
|
||||
ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
AnnotationAttributes getEndpointAttributes(Class<?> annotationClass, ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
return getEndpointAttributes(getEndpointType(annotationClass, context, metadata));
|
||||
}
|
||||
|
||||
protected ConditionOutcome getEnablementOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata, Class<? extends Annotation> annotationClass) {
|
||||
protected ConditionOutcome getEnablementOutcome(ConditionContext context, AnnotatedTypeMetadata metadata,
|
||||
Class<? extends Annotation> annotationClass) {
|
||||
Environment environment = context.getEnvironment();
|
||||
AnnotationAttributes attributes = getEndpointAttributes(annotationClass, context,
|
||||
metadata);
|
||||
AnnotationAttributes attributes = getEndpointAttributes(annotationClass, context, metadata);
|
||||
EndpointId id = EndpointId.of(attributes.getString("id"));
|
||||
String key = "management.endpoint." + id.toLowerCaseString() + ".enabled";
|
||||
Boolean userDefinedEnabled = environment.getProperty(key, Boolean.class);
|
||||
if (userDefinedEnabled != null) {
|
||||
return new ConditionOutcome(userDefinedEnabled,
|
||||
ConditionMessage.forCondition(annotationClass)
|
||||
.because("found property " + key + " with value "
|
||||
+ userDefinedEnabled));
|
||||
return new ConditionOutcome(userDefinedEnabled, ConditionMessage.forCondition(annotationClass)
|
||||
.because("found property " + key + " with value " + userDefinedEnabled));
|
||||
}
|
||||
Boolean userDefinedDefault = isEnabledByDefault(environment);
|
||||
if (userDefinedDefault != null) {
|
||||
return new ConditionOutcome(userDefinedDefault,
|
||||
ConditionMessage.forCondition(annotationClass)
|
||||
.because("no property " + key
|
||||
+ " found so using user defined default from "
|
||||
+ ENABLED_BY_DEFAULT_KEY));
|
||||
return new ConditionOutcome(userDefinedDefault, ConditionMessage.forCondition(annotationClass).because(
|
||||
"no property " + key + " found so using user defined default from " + ENABLED_BY_DEFAULT_KEY));
|
||||
}
|
||||
boolean endpointDefault = attributes.getBoolean("enableByDefault");
|
||||
return new ConditionOutcome(endpointDefault,
|
||||
ConditionMessage.forCondition(annotationClass).because(
|
||||
"no property " + key + " found so using endpoint default"));
|
||||
return new ConditionOutcome(endpointDefault, ConditionMessage.forCondition(annotationClass)
|
||||
.because("no property " + key + " found so using endpoint default"));
|
||||
}
|
||||
|
||||
protected Class<?> getEndpointType(Class<?> annotationClass, ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
Map<String, Object> attributes = metadata
|
||||
.getAnnotationAttributes(annotationClass.getName());
|
||||
Map<String, Object> attributes = metadata.getAnnotationAttributes(annotationClass.getName());
|
||||
if (attributes != null && attributes.containsKey("endpoint")) {
|
||||
Class<?> target = (Class<?>) attributes.get("endpoint");
|
||||
if (target != Void.class) {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
Assert.state(
|
||||
metadata instanceof MethodMetadata
|
||||
&& metadata.isAnnotated(Bean.class.getName()),
|
||||
Assert.state(metadata instanceof MethodMetadata && metadata.isAnnotated(Bean.class.getName()),
|
||||
"EndpointCondition must be used on @Bean methods when the endpoint is not specified");
|
||||
MethodMetadata methodMetadata = (MethodMetadata) metadata;
|
||||
try {
|
||||
return ClassUtils.forName(methodMetadata.getReturnTypeName(),
|
||||
context.getClassLoader());
|
||||
return ClassUtils.forName(methodMetadata.getReturnTypeName(), context.getClassLoader());
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new IllegalStateException("Failed to extract endpoint id for "
|
||||
+ methodMetadata.getDeclaringClassName() + "."
|
||||
+ methodMetadata.getMethodName(), ex);
|
||||
+ methodMetadata.getDeclaringClassName() + "." + methodMetadata.getMethodName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected AnnotationAttributes getEndpointAttributes(Class<?> type) {
|
||||
MergedAnnotations annotations = MergedAnnotations.from(type,
|
||||
SearchStrategy.EXHAUSTIVE);
|
||||
MergedAnnotations annotations = MergedAnnotations.from(type, SearchStrategy.EXHAUSTIVE);
|
||||
MergedAnnotation<Endpoint> endpoint = annotations.get(Endpoint.class);
|
||||
if (endpoint.isPresent()) {
|
||||
return endpoint.asAnnotationAttributes();
|
||||
}
|
||||
MergedAnnotation<EndpointExtension> extension = annotations
|
||||
.get(EndpointExtension.class);
|
||||
Assert.state(extension.isPresent(),
|
||||
"No endpoint is specified and the return type of the @Bean method is "
|
||||
+ "neither an @Endpoint, nor an @EndpointExtension");
|
||||
MergedAnnotation<EndpointExtension> extension = annotations.get(EndpointExtension.class);
|
||||
Assert.state(extension.isPresent(), "No endpoint is specified and the return type of the @Bean method is "
|
||||
+ "neither an @Endpoint, nor an @EndpointExtension");
|
||||
return getEndpointAttributes(extension.getClass("endpoint"));
|
||||
}
|
||||
|
||||
private Boolean isEnabledByDefault(Environment environment) {
|
||||
Optional<Boolean> enabledByDefault = enabledByDefaultCache.get(environment);
|
||||
if (enabledByDefault == null) {
|
||||
enabledByDefault = Optional.ofNullable(
|
||||
environment.getProperty(ENABLED_BY_DEFAULT_KEY, Boolean.class));
|
||||
enabledByDefault = Optional.ofNullable(environment.getProperty(ENABLED_BY_DEFAULT_KEY, Boolean.class));
|
||||
enabledByDefaultCache.put(environment, enabledByDefault);
|
||||
}
|
||||
return enabledByDefault.orElse(null);
|
||||
|
|
|
@ -48,8 +48,7 @@ class OnAvailableEndpointCondition extends AbstractEndpointCondition {
|
|||
private static final ConcurrentReferenceHashMap<Environment, Set<ExposureInformation>> endpointExposureCache = new ConcurrentReferenceHashMap<>();
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
ConditionOutcome enablementOutcome = getEnablementOutcome(context, metadata,
|
||||
ConditionalOnAvailableEndpoint.class);
|
||||
if (!enablementOutcome.isMatch()) {
|
||||
|
@ -58,40 +57,34 @@ class OnAvailableEndpointCondition extends AbstractEndpointCondition {
|
|||
ConditionMessage message = enablementOutcome.getConditionMessage();
|
||||
Environment environment = context.getEnvironment();
|
||||
if (CloudPlatform.CLOUD_FOUNDRY.isActive(environment)) {
|
||||
return new ConditionOutcome(true,
|
||||
message.andCondition(ConditionalOnAvailableEndpoint.class)
|
||||
.because("application is running on Cloud Foundry"));
|
||||
return new ConditionOutcome(true, message.andCondition(ConditionalOnAvailableEndpoint.class)
|
||||
.because("application is running on Cloud Foundry"));
|
||||
}
|
||||
AnnotationAttributes attributes = getEndpointAttributes(
|
||||
ConditionalOnAvailableEndpoint.class, context, metadata);
|
||||
AnnotationAttributes attributes = getEndpointAttributes(ConditionalOnAvailableEndpoint.class, context,
|
||||
metadata);
|
||||
EndpointId id = EndpointId.of(attributes.getString("id"));
|
||||
Set<ExposureInformation> exposureInformations = getExposureInformation(
|
||||
environment);
|
||||
Set<ExposureInformation> exposureInformations = getExposureInformation(environment);
|
||||
for (ExposureInformation exposureInformation : exposureInformations) {
|
||||
if (exposureInformation.isExposed(id)) {
|
||||
return new ConditionOutcome(true,
|
||||
message.andCondition(ConditionalOnAvailableEndpoint.class)
|
||||
.because("marked as exposed by a 'management.endpoints."
|
||||
+ exposureInformation.getPrefix()
|
||||
+ ".exposure' property"));
|
||||
+ exposureInformation.getPrefix() + ".exposure' property"));
|
||||
}
|
||||
}
|
||||
return new ConditionOutcome(false,
|
||||
message.andCondition(ConditionalOnAvailableEndpoint.class).because(
|
||||
"no 'management.endpoints' property marked it as exposed"));
|
||||
return new ConditionOutcome(false, message.andCondition(ConditionalOnAvailableEndpoint.class)
|
||||
.because("no 'management.endpoints' property marked it as exposed"));
|
||||
}
|
||||
|
||||
private Set<ExposureInformation> getExposureInformation(Environment environment) {
|
||||
Set<ExposureInformation> exposureInformations = endpointExposureCache
|
||||
.get(environment);
|
||||
Set<ExposureInformation> exposureInformations = endpointExposureCache.get(environment);
|
||||
if (exposureInformations == null) {
|
||||
exposureInformations = new HashSet<>(2);
|
||||
Binder binder = Binder.get(environment);
|
||||
if (environment.getProperty(JMX_ENABLED_KEY, Boolean.class, false)) {
|
||||
exposureInformations.add(new ExposureInformation(binder, "jmx", "*"));
|
||||
}
|
||||
exposureInformations
|
||||
.add(new ExposureInformation(binder, "web", "info", "health"));
|
||||
exposureInformations.add(new ExposureInformation(binder, "web", "info", "health"));
|
||||
endpointExposureCache.put(environment, exposureInformations);
|
||||
}
|
||||
return exposureInformations;
|
||||
|
@ -109,20 +102,16 @@ class OnAvailableEndpointCondition extends AbstractEndpointCondition {
|
|||
|
||||
ExposureInformation(Binder binder, String prefix, String... exposeDefaults) {
|
||||
this.prefix = prefix;
|
||||
this.include = bind(binder,
|
||||
"management.endpoints." + prefix + ".exposure.include");
|
||||
this.exclude = bind(binder,
|
||||
"management.endpoints." + prefix + ".exposure.exclude");
|
||||
this.include = bind(binder, "management.endpoints." + prefix + ".exposure.include");
|
||||
this.exclude = bind(binder, "management.endpoints." + prefix + ".exposure.exclude");
|
||||
this.exposeDefaults = new HashSet<>(Arrays.asList(exposeDefaults));
|
||||
}
|
||||
|
||||
private Set<String> bind(Binder binder, String name) {
|
||||
List<String> values = binder.bind(name, Bindable.listOf(String.class))
|
||||
.orElse(Collections.emptyList());
|
||||
List<String> values = binder.bind(name, Bindable.listOf(String.class)).orElse(Collections.emptyList());
|
||||
Set<String> result = new HashSet<>(values.size());
|
||||
for (String value : values) {
|
||||
result.add("*".equals(value) ? "*"
|
||||
: EndpointId.fromPropertyValue(value).toLowerCaseString());
|
||||
result.add("*".equals(value) ? "*" : EndpointId.fromPropertyValue(value).toLowerCaseString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -139,8 +128,7 @@ class OnAvailableEndpointCondition extends AbstractEndpointCondition {
|
|||
}
|
||||
}
|
||||
if (this.include.isEmpty()) {
|
||||
if (this.exposeDefaults.contains("*")
|
||||
|| this.exposeDefaults.contains(id)) {
|
||||
if (this.exposeDefaults.contains("*") || this.exposeDefaults.contains(id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,10 +33,8 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
|
|||
class OnEnabledEndpointCondition extends AbstractEndpointCondition {
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
return getEnablementOutcome(context, metadata,
|
||||
ConditionalOnEnabledEndpoint.class);
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
return getEnablementOutcome(context, metadata, ConditionalOnEnabledEndpoint.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,23 +45,20 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory {
|
|||
|
||||
private final boolean uniqueNames;
|
||||
|
||||
DefaultEndpointObjectNameFactory(JmxEndpointProperties properties,
|
||||
Environment environment, MBeanServer mBeanServer, String contextId) {
|
||||
DefaultEndpointObjectNameFactory(JmxEndpointProperties properties, Environment environment, MBeanServer mBeanServer,
|
||||
String contextId) {
|
||||
this.properties = properties;
|
||||
this.environment = environment;
|
||||
this.mBeanServer = mBeanServer;
|
||||
this.contextId = contextId;
|
||||
this.uniqueNames = environment.getProperty("spring.jmx.unique-names",
|
||||
Boolean.class, false);
|
||||
this.uniqueNames = environment.getProperty("spring.jmx.unique-names", Boolean.class, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectName getObjectName(ExposableJmxEndpoint endpoint)
|
||||
throws MalformedObjectNameException {
|
||||
public ObjectName getObjectName(ExposableJmxEndpoint endpoint) throws MalformedObjectNameException {
|
||||
StringBuilder builder = new StringBuilder(determineDomain());
|
||||
builder.append(":type=Endpoint");
|
||||
builder.append(",name=")
|
||||
.append(StringUtils.capitalize(endpoint.getEndpointId().toString()));
|
||||
builder.append(",name=").append(StringUtils.capitalize(endpoint.getEndpointId().toString()));
|
||||
String baseName = builder.toString();
|
||||
if (this.mBeanServer != null && hasMBean(baseName)) {
|
||||
builder.append(",context=").append(this.contextId);
|
||||
|
@ -78,8 +75,7 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory {
|
|||
if (StringUtils.hasText(this.properties.getDomain())) {
|
||||
return this.properties.getDomain();
|
||||
}
|
||||
return this.environment.getProperty("spring.jmx.default-domain",
|
||||
"org.springframework.boot");
|
||||
return this.environment.getProperty("spring.jmx.default-domain", "org.springframework.boot");
|
||||
}
|
||||
|
||||
private boolean hasMBean(String baseObjectName) throws MalformedObjectNameException {
|
||||
|
@ -92,8 +88,8 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory {
|
|||
return "";
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
this.properties.getStaticNames().forEach((name, value) -> builder.append(",")
|
||||
.append(name).append("=").append(value));
|
||||
this.properties.getStaticNames()
|
||||
.forEach((name, value) -> builder.append(",").append(name).append("=").append(value));
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -67,16 +67,14 @@ public class JmxEndpointAutoConfiguration {
|
|||
|
||||
private final JmxEndpointProperties properties;
|
||||
|
||||
public JmxEndpointAutoConfiguration(ApplicationContext applicationContext,
|
||||
JmxEndpointProperties properties) {
|
||||
public JmxEndpointAutoConfiguration(ApplicationContext applicationContext, JmxEndpointProperties properties) {
|
||||
this.applicationContext = applicationContext;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(JmxEndpointsSupplier.class)
|
||||
public JmxEndpointDiscoverer jmxAnnotationEndpointDiscoverer(
|
||||
ParameterValueMapper parameterValueMapper,
|
||||
public JmxEndpointDiscoverer jmxAnnotationEndpointDiscoverer(ParameterValueMapper parameterValueMapper,
|
||||
ObjectProvider<OperationInvokerAdvisor> invokerAdvisors,
|
||||
ObjectProvider<EndpointFilter<ExposableJmxEndpoint>> filters) {
|
||||
return new JmxEndpointDiscoverer(this.applicationContext, parameterValueMapper,
|
||||
|
@ -86,12 +84,11 @@ public class JmxEndpointAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnSingleCandidate(MBeanServer.class)
|
||||
public JmxEndpointExporter jmxMBeanExporter(MBeanServer mBeanServer,
|
||||
Environment environment, ObjectProvider<ObjectMapper> objectMapper,
|
||||
JmxEndpointsSupplier jmxEndpointsSupplier) {
|
||||
public JmxEndpointExporter jmxMBeanExporter(MBeanServer mBeanServer, Environment environment,
|
||||
ObjectProvider<ObjectMapper> objectMapper, JmxEndpointsSupplier jmxEndpointsSupplier) {
|
||||
String contextId = ObjectUtils.getIdentityHexString(this.applicationContext);
|
||||
EndpointObjectNameFactory objectNameFactory = new DefaultEndpointObjectNameFactory(
|
||||
this.properties, environment, mBeanServer, contextId);
|
||||
EndpointObjectNameFactory objectNameFactory = new DefaultEndpointObjectNameFactory(this.properties, environment,
|
||||
mBeanServer, contextId);
|
||||
JmxOperationResponseMapper responseMapper = new JacksonJmxOperationResponseMapper(
|
||||
objectMapper.getIfAvailable());
|
||||
return new JmxEndpointExporter(mBeanServer, objectNameFactory, responseMapper,
|
||||
|
@ -102,8 +99,8 @@ public class JmxEndpointAutoConfiguration {
|
|||
@Bean
|
||||
public ExposeExcludePropertyEndpointFilter<ExposableJmxEndpoint> jmxIncludeExcludePropertyEndpointFilter() {
|
||||
JmxEndpointProperties.Exposure exposure = this.properties.getExposure();
|
||||
return new ExposeExcludePropertyEndpointFilter<>(ExposableJmxEndpoint.class,
|
||||
exposure.getInclude(), exposure.getExclude(), "*");
|
||||
return new ExposeExcludePropertyEndpointFilter<>(ExposableJmxEndpoint.class, exposure.getInclude(),
|
||||
exposure.getExclude(), "*");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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.
|
||||
|
@ -125,16 +125,11 @@ public class CorsEndpointProperties {
|
|||
PropertyMapper map = PropertyMapper.get();
|
||||
CorsConfiguration configuration = new CorsConfiguration();
|
||||
map.from(this::getAllowedOrigins).to(configuration::setAllowedOrigins);
|
||||
map.from(this::getAllowedHeaders).whenNot(CollectionUtils::isEmpty)
|
||||
.to(configuration::setAllowedHeaders);
|
||||
map.from(this::getAllowedMethods).whenNot(CollectionUtils::isEmpty)
|
||||
.to(configuration::setAllowedMethods);
|
||||
map.from(this::getExposedHeaders).whenNot(CollectionUtils::isEmpty)
|
||||
.to(configuration::setExposedHeaders);
|
||||
map.from(this::getMaxAge).whenNonNull().as(Duration::getSeconds)
|
||||
.to(configuration::setMaxAge);
|
||||
map.from(this::getAllowCredentials).whenNonNull()
|
||||
.to(configuration::setAllowCredentials);
|
||||
map.from(this::getAllowedHeaders).whenNot(CollectionUtils::isEmpty).to(configuration::setAllowedHeaders);
|
||||
map.from(this::getAllowedMethods).whenNot(CollectionUtils::isEmpty).to(configuration::setAllowedMethods);
|
||||
map.from(this::getExposedHeaders).whenNot(CollectionUtils::isEmpty).to(configuration::setExposedHeaders);
|
||||
map.from(this::getMaxAge).whenNonNull().as(Duration::getSeconds).to(configuration::setMaxAge);
|
||||
map.from(this::getAllowCredentials).whenNonNull().to(configuration::setAllowCredentials);
|
||||
return configuration;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,8 +38,7 @@ class MappingWebEndpointPathMapper implements PathMapper {
|
|||
|
||||
MappingWebEndpointPathMapper(Map<String, String> pathMapping) {
|
||||
this.pathMapping = new HashMap<>();
|
||||
pathMapping.forEach((id, path) -> this.pathMapping
|
||||
.put(EndpointId.fromPropertyValue(id), path));
|
||||
pathMapping.forEach((id, path) -> this.pathMapping.put(EndpointId.fromPropertyValue(id), path));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -50,8 +50,8 @@ public class ServletEndpointManagementContextConfiguration {
|
|||
public ExposeExcludePropertyEndpointFilter<ExposableServletEndpoint> servletExposeExcludePropertyEndpointFilter(
|
||||
WebEndpointProperties properties) {
|
||||
WebEndpointProperties.Exposure exposure = properties.getExposure();
|
||||
return new ExposeExcludePropertyEndpointFilter<>(ExposableServletEndpoint.class,
|
||||
exposure.getInclude(), exposure.getExclude());
|
||||
return new ExposeExcludePropertyEndpointFilter<>(ExposableServletEndpoint.class, exposure.getInclude(),
|
||||
exposure.getExclude());
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
|
@ -59,12 +59,9 @@ public class ServletEndpointManagementContextConfiguration {
|
|||
public static class WebMvcServletEndpointManagementContextConfiguration {
|
||||
|
||||
@Bean
|
||||
public ServletEndpointRegistrar servletEndpointRegistrar(
|
||||
WebEndpointProperties properties,
|
||||
ServletEndpointsSupplier servletEndpointsSupplier,
|
||||
DispatcherServletPath dispatcherServletPath) {
|
||||
return new ServletEndpointRegistrar(
|
||||
dispatcherServletPath.getRelativePath(properties.getBasePath()),
|
||||
public ServletEndpointRegistrar servletEndpointRegistrar(WebEndpointProperties properties,
|
||||
ServletEndpointsSupplier servletEndpointsSupplier, DispatcherServletPath dispatcherServletPath) {
|
||||
return new ServletEndpointRegistrar(dispatcherServletPath.getRelativePath(properties.getBasePath()),
|
||||
servletEndpointsSupplier.getEndpoints());
|
||||
}
|
||||
|
||||
|
@ -76,12 +73,9 @@ public class ServletEndpointManagementContextConfiguration {
|
|||
public static class JerseyServletEndpointManagementContextConfiguration {
|
||||
|
||||
@Bean
|
||||
public ServletEndpointRegistrar servletEndpointRegistrar(
|
||||
WebEndpointProperties properties,
|
||||
ServletEndpointsSupplier servletEndpointsSupplier,
|
||||
JerseyApplicationPath jerseyApplicationPath) {
|
||||
return new ServletEndpointRegistrar(
|
||||
jerseyApplicationPath.getRelativePath(properties.getBasePath()),
|
||||
public ServletEndpointRegistrar servletEndpointRegistrar(WebEndpointProperties properties,
|
||||
ServletEndpointsSupplier servletEndpointsSupplier, JerseyApplicationPath jerseyApplicationPath) {
|
||||
return new ServletEndpointRegistrar(jerseyApplicationPath.getRelativePath(properties.getBasePath()),
|
||||
servletEndpointsSupplier.getEndpoints());
|
||||
}
|
||||
|
||||
|
|
|
@ -67,15 +67,13 @@ import org.springframework.context.annotation.Configuration;
|
|||
@EnableConfigurationProperties(WebEndpointProperties.class)
|
||||
public class WebEndpointAutoConfiguration {
|
||||
|
||||
private static final List<String> MEDIA_TYPES = Arrays
|
||||
.asList(ActuatorMediaType.V2_JSON, "application/json");
|
||||
private static final List<String> MEDIA_TYPES = Arrays.asList(ActuatorMediaType.V2_JSON, "application/json");
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
private final WebEndpointProperties properties;
|
||||
|
||||
public WebEndpointAutoConfiguration(ApplicationContext applicationContext,
|
||||
WebEndpointProperties properties) {
|
||||
public WebEndpointAutoConfiguration(ApplicationContext applicationContext, WebEndpointProperties properties) {
|
||||
this.applicationContext = applicationContext;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
@ -93,14 +91,11 @@ public class WebEndpointAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(WebEndpointsSupplier.class)
|
||||
public WebEndpointDiscoverer webEndpointDiscoverer(
|
||||
ParameterValueMapper parameterValueMapper,
|
||||
EndpointMediaTypes endpointMediaTypes,
|
||||
ObjectProvider<PathMapper> endpointPathMappers,
|
||||
public WebEndpointDiscoverer webEndpointDiscoverer(ParameterValueMapper parameterValueMapper,
|
||||
EndpointMediaTypes endpointMediaTypes, ObjectProvider<PathMapper> endpointPathMappers,
|
||||
ObjectProvider<OperationInvokerAdvisor> invokerAdvisors,
|
||||
ObjectProvider<EndpointFilter<ExposableWebEndpoint>> filters) {
|
||||
return new WebEndpointDiscoverer(this.applicationContext, parameterValueMapper,
|
||||
endpointMediaTypes,
|
||||
return new WebEndpointDiscoverer(this.applicationContext, parameterValueMapper, endpointMediaTypes,
|
||||
endpointPathMappers.orderedStream().collect(Collectors.toList()),
|
||||
invokerAdvisors.orderedStream().collect(Collectors.toList()),
|
||||
filters.orderedStream().collect(Collectors.toList()));
|
||||
|
@ -108,8 +103,7 @@ public class WebEndpointAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ControllerEndpointsSupplier.class)
|
||||
public ControllerEndpointDiscoverer controllerEndpointDiscoverer(
|
||||
ObjectProvider<PathMapper> endpointPathMappers,
|
||||
public ControllerEndpointDiscoverer controllerEndpointDiscoverer(ObjectProvider<PathMapper> endpointPathMappers,
|
||||
ObjectProvider<Collection<EndpointFilter<ExposableControllerEndpoint>>> filters) {
|
||||
return new ControllerEndpointDiscoverer(this.applicationContext,
|
||||
endpointPathMappers.orderedStream().collect(Collectors.toList()),
|
||||
|
@ -118,25 +112,22 @@ public class WebEndpointAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public PathMappedEndpoints pathMappedEndpoints(
|
||||
Collection<EndpointsSupplier<?>> endpointSuppliers,
|
||||
public PathMappedEndpoints pathMappedEndpoints(Collection<EndpointsSupplier<?>> endpointSuppliers,
|
||||
WebEndpointProperties webEndpointProperties) {
|
||||
return new PathMappedEndpoints(webEndpointProperties.getBasePath(),
|
||||
endpointSuppliers);
|
||||
return new PathMappedEndpoints(webEndpointProperties.getBasePath(), endpointSuppliers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExposeExcludePropertyEndpointFilter<ExposableWebEndpoint> webExposeExcludePropertyEndpointFilter() {
|
||||
WebEndpointProperties.Exposure exposure = this.properties.getExposure();
|
||||
return new ExposeExcludePropertyEndpointFilter<>(ExposableWebEndpoint.class,
|
||||
exposure.getInclude(), exposure.getExclude(), "info", "health");
|
||||
return new ExposeExcludePropertyEndpointFilter<>(ExposableWebEndpoint.class, exposure.getInclude(),
|
||||
exposure.getExclude(), "info", "health");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExposeExcludePropertyEndpointFilter<ExposableControllerEndpoint> controllerExposeExcludePropertyEndpointFilter() {
|
||||
WebEndpointProperties.Exposure exposure = this.properties.getExposure();
|
||||
return new ExposeExcludePropertyEndpointFilter<>(
|
||||
ExposableControllerEndpoint.class, exposure.getInclude(),
|
||||
return new ExposeExcludePropertyEndpointFilter<>(ExposableControllerEndpoint.class, exposure.getInclude(),
|
||||
exposure.getExclude());
|
||||
}
|
||||
|
||||
|
@ -146,8 +137,7 @@ public class WebEndpointAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ServletEndpointsSupplier.class)
|
||||
public ServletEndpointDiscoverer servletEndpointDiscoverer(
|
||||
ApplicationContext applicationContext,
|
||||
public ServletEndpointDiscoverer servletEndpointDiscoverer(ApplicationContext applicationContext,
|
||||
ObjectProvider<PathMapper> endpointPathMappers,
|
||||
ObjectProvider<EndpointFilter<ExposableServletEndpoint>> filters) {
|
||||
return new ServletEndpointDiscoverer(applicationContext,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,7 @@ public class WebEndpointProperties {
|
|||
}
|
||||
|
||||
public void setBasePath(String basePath) {
|
||||
Assert.isTrue(basePath.isEmpty() || basePath.startsWith("/"),
|
||||
"Base path must start with '/' or be empty");
|
||||
Assert.isTrue(basePath.isEmpty() || basePath.startsWith("/"), "Base path must start with '/' or be empty");
|
||||
this.basePath = cleanBasePath(basePath);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,10 +60,8 @@ import org.springframework.context.annotation.Bean;
|
|||
class JerseyWebEndpointManagementContextConfiguration {
|
||||
|
||||
@Bean
|
||||
public ResourceConfigCustomizer webEndpointRegistrar(
|
||||
WebEndpointsSupplier webEndpointsSupplier,
|
||||
ServletEndpointsSupplier servletEndpointsSupplier,
|
||||
EndpointMediaTypes endpointMediaTypes,
|
||||
public ResourceConfigCustomizer webEndpointRegistrar(WebEndpointsSupplier webEndpointsSupplier,
|
||||
ServletEndpointsSupplier servletEndpointsSupplier, EndpointMediaTypes endpointMediaTypes,
|
||||
WebEndpointProperties webEndpointProperties) {
|
||||
List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
|
||||
allEndpoints.addAll(webEndpointsSupplier.getEndpoints());
|
||||
|
@ -74,10 +72,8 @@ class JerseyWebEndpointManagementContextConfiguration {
|
|||
EndpointMapping endpointMapping = new EndpointMapping(basePath);
|
||||
Collection<ExposableWebEndpoint> webEndpoints = Collections
|
||||
.unmodifiableCollection(webEndpointsSupplier.getEndpoints());
|
||||
resourceConfig.registerResources(
|
||||
new HashSet<>(resourceFactory.createEndpointResources(endpointMapping,
|
||||
webEndpoints, endpointMediaTypes,
|
||||
new EndpointLinksResolver(allEndpoints, basePath))));
|
||||
resourceConfig.registerResources(new HashSet<>(resourceFactory.createEndpointResources(endpointMapping,
|
||||
webEndpoints, endpointMediaTypes, new EndpointLinksResolver(allEndpoints, basePath))));
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -60,33 +60,26 @@ public class WebFluxEndpointManagementContextConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public WebFluxEndpointHandlerMapping webEndpointReactiveHandlerMapping(
|
||||
WebEndpointsSupplier webEndpointsSupplier,
|
||||
ControllerEndpointsSupplier controllerEndpointsSupplier,
|
||||
EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties,
|
||||
WebEndpointProperties webEndpointProperties) {
|
||||
EndpointMapping endpointMapping = new EndpointMapping(
|
||||
webEndpointProperties.getBasePath());
|
||||
public WebFluxEndpointHandlerMapping webEndpointReactiveHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,
|
||||
ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes,
|
||||
CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties) {
|
||||
EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath());
|
||||
Collection<ExposableWebEndpoint> endpoints = webEndpointsSupplier.getEndpoints();
|
||||
List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
|
||||
allEndpoints.addAll(endpoints);
|
||||
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
|
||||
return new WebFluxEndpointHandlerMapping(endpointMapping, endpoints,
|
||||
endpointMediaTypes, corsProperties.toCorsConfiguration(),
|
||||
new EndpointLinksResolver(allEndpoints,
|
||||
webEndpointProperties.getBasePath()));
|
||||
return new WebFluxEndpointHandlerMapping(endpointMapping, endpoints, endpointMediaTypes,
|
||||
corsProperties.toCorsConfiguration(),
|
||||
new EndpointLinksResolver(allEndpoints, webEndpointProperties.getBasePath()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ControllerEndpointHandlerMapping controllerEndpointHandlerMapping(
|
||||
ControllerEndpointsSupplier controllerEndpointsSupplier,
|
||||
CorsEndpointProperties corsProperties,
|
||||
ControllerEndpointsSupplier controllerEndpointsSupplier, CorsEndpointProperties corsProperties,
|
||||
WebEndpointProperties webEndpointProperties) {
|
||||
EndpointMapping endpointMapping = new EndpointMapping(
|
||||
webEndpointProperties.getBasePath());
|
||||
return new ControllerEndpointHandlerMapping(endpointMapping,
|
||||
controllerEndpointsSupplier.getEndpoints(),
|
||||
EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath());
|
||||
return new ControllerEndpointHandlerMapping(endpointMapping, controllerEndpointsSupplier.getEndpoints(),
|
||||
corsProperties.toCorsConfiguration());
|
||||
}
|
||||
|
||||
|
|
|
@ -60,36 +60,28 @@ public class WebMvcEndpointManagementContextConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(
|
||||
WebEndpointsSupplier webEndpointsSupplier,
|
||||
ServletEndpointsSupplier servletEndpointsSupplier,
|
||||
ControllerEndpointsSupplier controllerEndpointsSupplier,
|
||||
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,
|
||||
ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier,
|
||||
EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties,
|
||||
WebEndpointProperties webEndpointProperties) {
|
||||
List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
|
||||
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier
|
||||
.getEndpoints();
|
||||
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
|
||||
allEndpoints.addAll(webEndpoints);
|
||||
allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
|
||||
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
|
||||
EndpointMapping endpointMapping = new EndpointMapping(
|
||||
webEndpointProperties.getBasePath());
|
||||
return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints,
|
||||
endpointMediaTypes, corsProperties.toCorsConfiguration(),
|
||||
new EndpointLinksResolver(allEndpoints,
|
||||
webEndpointProperties.getBasePath()));
|
||||
EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath());
|
||||
return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes,
|
||||
corsProperties.toCorsConfiguration(),
|
||||
new EndpointLinksResolver(allEndpoints, webEndpointProperties.getBasePath()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ControllerEndpointHandlerMapping controllerEndpointHandlerMapping(
|
||||
ControllerEndpointsSupplier controllerEndpointsSupplier,
|
||||
CorsEndpointProperties corsProperties,
|
||||
ControllerEndpointsSupplier controllerEndpointsSupplier, CorsEndpointProperties corsProperties,
|
||||
WebEndpointProperties webEndpointProperties) {
|
||||
EndpointMapping endpointMapping = new EndpointMapping(
|
||||
webEndpointProperties.getBasePath());
|
||||
return new ControllerEndpointHandlerMapping(endpointMapping,
|
||||
controllerEndpointsSupplier.getEndpoints(),
|
||||
EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath());
|
||||
return new ControllerEndpointHandlerMapping(endpointMapping, controllerEndpointsSupplier.getEndpoints(),
|
||||
corsProperties.toCorsConfiguration());
|
||||
}
|
||||
|
||||
|
|
|
@ -41,8 +41,7 @@ public class EnvironmentEndpointAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public EnvironmentEndpoint environmentEndpoint(Environment environment,
|
||||
EnvironmentEndpointProperties properties) {
|
||||
public EnvironmentEndpoint environmentEndpoint(Environment environment, EnvironmentEndpointProperties properties) {
|
||||
EnvironmentEndpoint endpoint = new EnvironmentEndpoint(environment);
|
||||
String[] keysToSanitize = properties.getKeysToSanitize();
|
||||
if (keysToSanitize != null) {
|
||||
|
@ -54,8 +53,7 @@ public class EnvironmentEndpointAutoConfiguration {
|
|||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(EnvironmentEndpoint.class)
|
||||
public EnvironmentEndpointWebExtension environmentEndpointWebExtension(
|
||||
EnvironmentEndpoint environmentEndpoint) {
|
||||
public EnvironmentEndpointWebExtension environmentEndpointWebExtension(EnvironmentEndpoint environmentEndpoint) {
|
||||
return new EnvironmentEndpointWebExtension(environmentEndpoint);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,15 +45,13 @@ public abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndi
|
|||
return createHealthIndicator(beans.values().iterator().next());
|
||||
}
|
||||
HealthIndicatorRegistry registry = new DefaultHealthIndicatorRegistry();
|
||||
beans.forEach(
|
||||
(name, source) -> registry.register(name, createHealthIndicator(source)));
|
||||
beans.forEach((name, source) -> registry.register(name, createHealthIndicator(source)));
|
||||
return new CompositeHealthIndicator(this.healthAggregator, registry);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected H createHealthIndicator(S source) {
|
||||
Class<?>[] generics = ResolvableType
|
||||
.forClass(CompositeHealthIndicatorConfiguration.class, getClass())
|
||||
Class<?>[] generics = ResolvableType.forClass(CompositeHealthIndicatorConfiguration.class, getClass())
|
||||
.resolveGenerics();
|
||||
Class<H> indicatorClass = (Class<H>) generics[0];
|
||||
Class<S> sourceClass = (Class<S>) generics[1];
|
||||
|
@ -61,8 +59,8 @@ public abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndi
|
|||
return indicatorClass.getConstructor(sourceClass).newInstance(source);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Unable to create indicator " + indicatorClass
|
||||
+ " for source " + sourceClass, ex);
|
||||
throw new IllegalStateException(
|
||||
"Unable to create indicator " + indicatorClass + " for source " + sourceClass, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,15 +44,13 @@ public abstract class CompositeReactiveHealthIndicatorConfiguration<H extends Re
|
|||
return createHealthIndicator(beans.values().iterator().next());
|
||||
}
|
||||
ReactiveHealthIndicatorRegistry registry = new DefaultReactiveHealthIndicatorRegistry();
|
||||
beans.forEach(
|
||||
(name, source) -> registry.register(name, createHealthIndicator(source)));
|
||||
beans.forEach((name, source) -> registry.register(name, createHealthIndicator(source)));
|
||||
return new CompositeReactiveHealthIndicator(this.healthAggregator, registry);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected H createHealthIndicator(S source) {
|
||||
Class<?>[] generics = ResolvableType
|
||||
.forClass(CompositeReactiveHealthIndicatorConfiguration.class, getClass())
|
||||
Class<?>[] generics = ResolvableType.forClass(CompositeReactiveHealthIndicatorConfiguration.class, getClass())
|
||||
.resolveGenerics();
|
||||
Class<H> indicatorClass = (Class<H>) generics[0];
|
||||
Class<S> sourceClass = (Class<S>) generics[1];
|
||||
|
@ -60,8 +58,8 @@ public abstract class CompositeReactiveHealthIndicatorConfiguration<H extends Re
|
|||
return indicatorClass.getConstructor(sourceClass).newInstance(source);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Unable to create indicator " + indicatorClass
|
||||
+ " for source " + sourceClass, ex);
|
||||
throw new IllegalStateException(
|
||||
"Unable to create indicator " + indicatorClass + " for source " + sourceClass, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,11 +32,9 @@ import org.springframework.context.annotation.Import;
|
|||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties({ HealthEndpointProperties.class,
|
||||
HealthIndicatorProperties.class })
|
||||
@EnableConfigurationProperties({ HealthEndpointProperties.class, HealthIndicatorProperties.class })
|
||||
@AutoConfigureAfter(HealthIndicatorAutoConfiguration.class)
|
||||
@Import({ HealthEndpointConfiguration.class,
|
||||
HealthEndpointWebExtensionConfiguration.class })
|
||||
@Import({ HealthEndpointConfiguration.class, HealthEndpointWebExtensionConfiguration.class })
|
||||
public class HealthEndpointAutoConfiguration {
|
||||
|
||||
}
|
||||
|
|
|
@ -38,10 +38,8 @@ class HealthEndpointConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public HealthEndpoint healthEndpoint(HealthAggregator healthAggregator,
|
||||
HealthIndicatorRegistry registry) {
|
||||
return new HealthEndpoint(
|
||||
new CompositeHealthIndicator(healthAggregator, registry));
|
||||
public HealthEndpoint healthEndpoint(HealthAggregator healthAggregator, HealthIndicatorRegistry registry) {
|
||||
return new HealthEndpoint(new CompositeHealthIndicator(healthAggregator, registry));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,8 +48,7 @@ class HealthEndpointWebExtensionConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public HealthStatusHttpMapper createHealthStatusHttpMapper(
|
||||
HealthIndicatorProperties healthIndicatorProperties) {
|
||||
public HealthStatusHttpMapper createHealthStatusHttpMapper(HealthIndicatorProperties healthIndicatorProperties) {
|
||||
HealthStatusHttpMapper statusHttpMapper = new HealthStatusHttpMapper();
|
||||
if (healthIndicatorProperties.getHttpMapping() != null) {
|
||||
statusHttpMapper.addStatusMapping(healthIndicatorProperties.getHttpMapping());
|
||||
|
@ -59,11 +58,10 @@ class HealthEndpointWebExtensionConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public HealthWebEndpointResponseMapper healthWebEndpointResponseMapper(
|
||||
HealthStatusHttpMapper statusHttpMapper,
|
||||
public HealthWebEndpointResponseMapper healthWebEndpointResponseMapper(HealthStatusHttpMapper statusHttpMapper,
|
||||
HealthEndpointProperties properties) {
|
||||
return new HealthWebEndpointResponseMapper(statusHttpMapper,
|
||||
properties.getShowDetails(), properties.getRoles());
|
||||
return new HealthWebEndpointResponseMapper(statusHttpMapper, properties.getShowDetails(),
|
||||
properties.getRoles());
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
|
@ -75,14 +73,10 @@ class HealthEndpointWebExtensionConfiguration {
|
|||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(HealthEndpoint.class)
|
||||
public ReactiveHealthEndpointWebExtension reactiveHealthEndpointWebExtension(
|
||||
ObjectProvider<HealthAggregator> healthAggregator,
|
||||
ReactiveHealthIndicatorRegistry registry,
|
||||
ObjectProvider<HealthAggregator> healthAggregator, ReactiveHealthIndicatorRegistry registry,
|
||||
HealthWebEndpointResponseMapper responseMapper) {
|
||||
return new ReactiveHealthEndpointWebExtension(
|
||||
new CompositeReactiveHealthIndicator(
|
||||
healthAggregator.getIfAvailable(OrderedHealthAggregator::new),
|
||||
registry),
|
||||
responseMapper);
|
||||
return new ReactiveHealthEndpointWebExtension(new CompositeReactiveHealthIndicator(
|
||||
healthAggregator.getIfAvailable(OrderedHealthAggregator::new), registry), responseMapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -94,8 +88,7 @@ class HealthEndpointWebExtensionConfiguration {
|
|||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(HealthEndpoint.class)
|
||||
public HealthEndpointWebExtension healthEndpointWebExtension(
|
||||
HealthEndpoint healthEndpoint,
|
||||
public HealthEndpointWebExtension healthEndpointWebExtension(HealthEndpoint healthEndpoint,
|
||||
HealthWebEndpointResponseMapper responseMapper) {
|
||||
return new HealthEndpointWebExtension(healthEndpoint, responseMapper);
|
||||
}
|
||||
|
|
|
@ -57,8 +57,7 @@ public class HealthIndicatorAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(HealthAggregator.class)
|
||||
public OrderedHealthAggregator healthAggregator(
|
||||
HealthIndicatorProperties properties) {
|
||||
public OrderedHealthAggregator healthAggregator(HealthIndicatorProperties properties) {
|
||||
OrderedHealthAggregator healthAggregator = new OrderedHealthAggregator();
|
||||
if (properties.getOrder() != null) {
|
||||
healthAggregator.setStatusOrder(properties.getOrder());
|
||||
|
@ -68,8 +67,7 @@ public class HealthIndicatorAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(HealthIndicatorRegistry.class)
|
||||
public HealthIndicatorRegistry healthIndicatorRegistry(
|
||||
ApplicationContext applicationContext) {
|
||||
public HealthIndicatorRegistry healthIndicatorRegistry(ApplicationContext applicationContext) {
|
||||
return HealthIndicatorRegistryBeans.get(applicationContext);
|
||||
}
|
||||
|
||||
|
@ -83,8 +81,7 @@ public class HealthIndicatorAutoConfiguration {
|
|||
Map<String, ReactiveHealthIndicator> reactiveHealthIndicators,
|
||||
Map<String, HealthIndicator> healthIndicators) {
|
||||
return new ReactiveHealthIndicatorRegistryFactory()
|
||||
.createReactiveHealthIndicatorRegistry(reactiveHealthIndicators,
|
||||
healthIndicators);
|
||||
.createReactiveHealthIndicatorRegistry(reactiveHealthIndicators, healthIndicators);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,8 +41,7 @@ final class HealthIndicatorRegistryBeans {
|
|||
Map<String, HealthIndicator> indicators = new LinkedHashMap<>();
|
||||
indicators.putAll(applicationContext.getBeansOfType(HealthIndicator.class));
|
||||
if (ClassUtils.isPresent("reactor.core.publisher.Flux", null)) {
|
||||
new ReactiveHealthIndicators().get(applicationContext)
|
||||
.forEach(indicators::putIfAbsent);
|
||||
new ReactiveHealthIndicators().get(applicationContext).forEach(indicators::putIfAbsent);
|
||||
}
|
||||
HealthIndicatorRegistryFactory factory = new HealthIndicatorRegistryFactory();
|
||||
return factory.createHealthIndicatorRegistry(indicators);
|
||||
|
|
|
@ -55,8 +55,7 @@ public class InfoContributorAutoConfiguration {
|
|||
@Bean
|
||||
@ConditionalOnEnabledInfoContributor("env")
|
||||
@Order(DEFAULT_ORDER)
|
||||
public EnvironmentInfoContributor envInfoContributor(
|
||||
ConfigurableEnvironment environment) {
|
||||
public EnvironmentInfoContributor envInfoContributor(ConfigurableEnvironment environment) {
|
||||
return new EnvironmentInfoContributor(environment);
|
||||
}
|
||||
|
||||
|
@ -67,8 +66,7 @@ public class InfoContributorAutoConfiguration {
|
|||
@Order(DEFAULT_ORDER)
|
||||
public GitInfoContributor gitInfoContributor(GitProperties gitProperties,
|
||||
InfoContributorProperties infoContributorProperties) {
|
||||
return new GitInfoContributor(gitProperties,
|
||||
infoContributorProperties.getGit().getMode());
|
||||
return new GitInfoContributor(gitProperties, infoContributorProperties.getGit().getMode());
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
@ -42,8 +42,7 @@ public class InfoEndpointAutoConfiguration {
|
|||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public InfoEndpoint infoEndpoint(ObjectProvider<InfoContributor> infoContributors) {
|
||||
return new InfoEndpoint(
|
||||
infoContributors.orderedStream().collect(Collectors.toList()));
|
||||
return new InfoEndpoint(infoContributors.orderedStream().collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,8 +46,7 @@ public class IntegrationGraphEndpointAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public IntegrationGraphEndpoint integrationGraphEndpoint(
|
||||
IntegrationGraphServer integrationGraphServer) {
|
||||
public IntegrationGraphEndpoint integrationGraphEndpoint(IntegrationGraphServer integrationGraphServer) {
|
||||
return new IntegrationGraphEndpoint(integrationGraphServer);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,8 +63,7 @@ import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
|
|||
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
|
||||
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
|
||||
public class DataSourceHealthIndicatorAutoConfiguration extends
|
||||
CompositeHealthIndicatorConfiguration<DataSourceHealthIndicator, DataSource>
|
||||
implements InitializingBean {
|
||||
CompositeHealthIndicatorConfiguration<DataSourceHealthIndicator, DataSource> implements InitializingBean {
|
||||
|
||||
private final Collection<DataSourcePoolMetadataProvider> metadataProviders;
|
||||
|
||||
|
@ -72,14 +71,12 @@ public class DataSourceHealthIndicatorAutoConfiguration extends
|
|||
|
||||
public DataSourceHealthIndicatorAutoConfiguration(Map<String, DataSource> dataSources,
|
||||
ObjectProvider<DataSourcePoolMetadataProvider> metadataProviders) {
|
||||
this.metadataProviders = metadataProviders.orderedStream()
|
||||
.collect(Collectors.toList());
|
||||
this.metadataProviders = metadataProviders.orderedStream().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.poolMetadataProvider = new CompositeDataSourcePoolMetadataProvider(
|
||||
this.metadataProviders);
|
||||
this.poolMetadataProvider = new CompositeDataSourcePoolMetadataProvider(this.metadataProviders);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
@ -88,8 +85,7 @@ public class DataSourceHealthIndicatorAutoConfiguration extends
|
|||
return createHealthIndicator(filterDataSources(dataSources));
|
||||
}
|
||||
|
||||
private Map<String, DataSource> filterDataSources(
|
||||
Map<String, DataSource> candidates) {
|
||||
private Map<String, DataSource> filterDataSources(Map<String, DataSource> candidates) {
|
||||
if (candidates == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -108,8 +104,7 @@ public class DataSourceHealthIndicatorAutoConfiguration extends
|
|||
}
|
||||
|
||||
private String getValidationQuery(DataSource source) {
|
||||
DataSourcePoolMetadata poolMetadata = this.poolMetadataProvider
|
||||
.getDataSourcePoolMetadata(source);
|
||||
DataSourcePoolMetadata poolMetadata = this.poolMetadataProvider.getDataSourcePoolMetadata(source);
|
||||
return (poolMetadata != null) ? poolMetadata.getValidationQuery() : null;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,13 +48,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
@ConditionalOnEnabledHealthIndicator("jms")
|
||||
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
|
||||
@AutoConfigureAfter({ ActiveMQAutoConfiguration.class, ArtemisAutoConfiguration.class })
|
||||
public class JmsHealthIndicatorAutoConfiguration extends
|
||||
CompositeHealthIndicatorConfiguration<JmsHealthIndicator, ConnectionFactory> {
|
||||
public class JmsHealthIndicatorAutoConfiguration
|
||||
extends CompositeHealthIndicatorConfiguration<JmsHealthIndicator, ConnectionFactory> {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "jmsHealthIndicator")
|
||||
public HealthIndicator jmsHealthIndicator(
|
||||
Map<String, ConnectionFactory> connectionFactories) {
|
||||
public HealthIndicator jmsHealthIndicator(Map<String, ConnectionFactory> connectionFactories) {
|
||||
return createHealthIndicator(connectionFactories);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,8 +42,7 @@ public class JolokiaEndpoint implements Supplier<EndpointServlet> {
|
|||
|
||||
@Override
|
||||
public EndpointServlet get() {
|
||||
return new EndpointServlet(AgentServlet.class)
|
||||
.withInitParameters(this.initParameters);
|
||||
return new EndpointServlet(AgentServlet.class).withInitParameters(this.initParameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,13 +47,12 @@ import org.springframework.ldap.core.LdapOperations;
|
|||
@ConditionalOnEnabledHealthIndicator("ldap")
|
||||
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
|
||||
@AutoConfigureAfter(LdapAutoConfiguration.class)
|
||||
public class LdapHealthIndicatorAutoConfiguration extends
|
||||
CompositeHealthIndicatorConfiguration<LdapHealthIndicator, LdapOperations> {
|
||||
public class LdapHealthIndicatorAutoConfiguration
|
||||
extends CompositeHealthIndicatorConfiguration<LdapHealthIndicator, LdapOperations> {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "ldapHealthIndicator")
|
||||
public HealthIndicator ldapHealthIndicator(
|
||||
Map<String, LdapOperations> ldapOperations) {
|
||||
public HealthIndicator ldapHealthIndicator(Map<String, LdapOperations> ldapOperations) {
|
||||
return createHealthIndicator(ldapOperations);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,18 +58,15 @@ public class LiquibaseEndpointAutoConfiguration {
|
|||
return new BeanPostProcessor() {
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof DataSourceClosingSpringLiquibase) {
|
||||
((DataSourceClosingSpringLiquibase) bean)
|
||||
.setCloseDataSourceOnceMigrated(false);
|
||||
((DataSourceClosingSpringLiquibase) bean).setCloseDataSourceOnceMigrated(false);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,8 +48,7 @@ public class LogFileWebEndpointAutoConfiguration {
|
|||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@Conditional(LogFileCondition.class)
|
||||
public LogFileWebEndpoint logFileWebEndpoint(Environment environment,
|
||||
LogFileWebEndpointProperties properties) {
|
||||
public LogFileWebEndpoint logFileWebEndpoint(Environment environment, LogFileWebEndpointProperties properties) {
|
||||
return new LogFileWebEndpoint(environment, properties.getExternalFile());
|
||||
}
|
||||
|
||||
|
@ -57,33 +56,25 @@ public class LogFileWebEndpointAutoConfiguration {
|
|||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
Environment environment = context.getEnvironment();
|
||||
String config = getLogFileConfig(environment, LogFile.FILE_NAME_PROPERTY,
|
||||
LogFile.FILE_PROPERTY);
|
||||
String config = getLogFileConfig(environment, LogFile.FILE_NAME_PROPERTY, LogFile.FILE_PROPERTY);
|
||||
ConditionMessage.Builder message = ConditionMessage.forCondition("Log File");
|
||||
if (StringUtils.hasText(config)) {
|
||||
return ConditionOutcome
|
||||
.match(message.found(LogFile.FILE_NAME_PROPERTY).items(config));
|
||||
return ConditionOutcome.match(message.found(LogFile.FILE_NAME_PROPERTY).items(config));
|
||||
}
|
||||
config = getLogFileConfig(environment, LogFile.FILE_PATH_PROPERTY,
|
||||
LogFile.PATH_PROPERTY);
|
||||
config = getLogFileConfig(environment, LogFile.FILE_PATH_PROPERTY, LogFile.PATH_PROPERTY);
|
||||
if (StringUtils.hasText(config)) {
|
||||
return ConditionOutcome
|
||||
.match(message.found(LogFile.FILE_PATH_PROPERTY).items(config));
|
||||
return ConditionOutcome.match(message.found(LogFile.FILE_PATH_PROPERTY).items(config));
|
||||
}
|
||||
config = environment.getProperty("management.endpoint.logfile.external-file");
|
||||
if (StringUtils.hasText(config)) {
|
||||
return ConditionOutcome
|
||||
.match(message.found("management.endpoint.logfile.external-file")
|
||||
.items(config));
|
||||
return ConditionOutcome.match(message.found("management.endpoint.logfile.external-file").items(config));
|
||||
}
|
||||
return ConditionOutcome.noMatch(message.didNotFind("logging file").atAll());
|
||||
}
|
||||
|
||||
private String getLogFileConfig(Environment environment, String configName,
|
||||
String deprecatedConfigName) {
|
||||
private String getLogFileConfig(Environment environment, String configName, String deprecatedConfigName) {
|
||||
String config = environment.resolvePlaceholders("${" + configName + ":}");
|
||||
if (StringUtils.hasText(config)) {
|
||||
return config;
|
||||
|
|
|
@ -52,14 +52,12 @@ public class LoggersEndpointAutoConfiguration {
|
|||
static class OnEnabledLoggingSystemCondition extends SpringBootCondition {
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
ConditionMessage.Builder message = ConditionMessage
|
||||
.forCondition("Logging System");
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
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"));
|
||||
}
|
||||
|
|
|
@ -46,13 +46,12 @@ import org.springframework.mail.javamail.JavaMailSenderImpl;
|
|||
@ConditionalOnEnabledHealthIndicator("mail")
|
||||
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
|
||||
@AutoConfigureAfter(MailSenderAutoConfiguration.class)
|
||||
public class MailHealthIndicatorAutoConfiguration extends
|
||||
CompositeHealthIndicatorConfiguration<MailHealthIndicator, JavaMailSenderImpl> {
|
||||
public class MailHealthIndicatorAutoConfiguration
|
||||
extends CompositeHealthIndicatorConfiguration<MailHealthIndicator, JavaMailSenderImpl> {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "mailHealthIndicator")
|
||||
public HealthIndicator mailHealthIndicator(
|
||||
Map<String, JavaMailSenderImpl> mailSenders) {
|
||||
public HealthIndicator mailHealthIndicator(Map<String, JavaMailSenderImpl> mailSenders) {
|
||||
return createHealthIndicator(mailSenders);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,8 +69,7 @@ public final class AutoTimeProperties implements AutoTimer {
|
|||
|
||||
@Override
|
||||
public void apply(Builder builder) {
|
||||
builder.publishPercentileHistogram(this.percentilesHistogram)
|
||||
.publishPercentiles(this.percentiles);
|
||||
builder.publishPercentileHistogram(this.percentilesHistogram).publishPercentiles(this.percentiles);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,8 +31,7 @@ import org.springframework.context.annotation.Import;
|
|||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import({ NoOpMeterRegistryConfiguration.class,
|
||||
CompositeMeterRegistryConfiguration.class })
|
||||
@Import({ NoOpMeterRegistryConfiguration.class, CompositeMeterRegistryConfiguration.class })
|
||||
@ConditionalOnClass(CompositeMeterRegistry.class)
|
||||
public class CompositeMeterRegistryAutoConfiguration {
|
||||
|
||||
|
|
|
@ -42,8 +42,7 @@ class CompositeMeterRegistryConfiguration {
|
|||
|
||||
@Bean
|
||||
@Primary
|
||||
public CompositeMeterRegistry compositeMeterRegistry(Clock clock,
|
||||
List<MeterRegistry> registries) {
|
||||
public CompositeMeterRegistry compositeMeterRegistry(Clock clock, List<MeterRegistry> registries) {
|
||||
return new CompositeMeterRegistry(clock, registries);
|
||||
}
|
||||
|
||||
|
|
|
@ -57,21 +57,19 @@ public class Log4J2MetricsAutoConfiguration {
|
|||
static class Log4JCoreLoggerContextCondition extends SpringBootCondition {
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
LoggerContext loggerContext = LogManager.getContext(false);
|
||||
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");
|
||||
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");
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// Continue with no match
|
||||
}
|
||||
return ConditionOutcome.noMatch(
|
||||
"Logger context was not an instance of org.apache.logging.log4j.core.LoggerContext");
|
||||
return ConditionOutcome
|
||||
.noMatch("Logger context was not an instance of org.apache.logging.log4j.core.LoggerContext");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -59,18 +59,14 @@ public class LogbackMetricsAutoConfiguration {
|
|||
static class LogbackLoggingCondition extends SpringBootCondition {
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
|
||||
ConditionMessage.Builder message = ConditionMessage
|
||||
.forCondition("LogbackLoggingCondition");
|
||||
ConditionMessage.Builder message = ConditionMessage.forCondition("LogbackLoggingCondition");
|
||||
if (loggerFactory instanceof LoggerContext) {
|
||||
return ConditionOutcome.match(
|
||||
message.because("ILoggerFactory is a Logback LoggerContext"));
|
||||
return ConditionOutcome.match(message.because("ILoggerFactory is a Logback LoggerContext"));
|
||||
}
|
||||
return ConditionOutcome
|
||||
.noMatch(message.because("ILoggerFactory is an instance of "
|
||||
+ loggerFactory.getClass().getCanonicalName()));
|
||||
return ConditionOutcome.noMatch(
|
||||
message.because("ILoggerFactory is an instance of " + loggerFactory.getClass().getCanonicalName()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,9 +48,8 @@ class MeterRegistryConfigurer {
|
|||
|
||||
private final boolean hasCompositeMeterRegistry;
|
||||
|
||||
MeterRegistryConfigurer(ObjectProvider<MeterRegistryCustomizer<?>> customizers,
|
||||
ObjectProvider<MeterFilter> filters, ObjectProvider<MeterBinder> binders,
|
||||
boolean addToGlobalRegistry, boolean hasCompositeMeterRegistry) {
|
||||
MeterRegistryConfigurer(ObjectProvider<MeterRegistryCustomizer<?>> customizers, ObjectProvider<MeterFilter> filters,
|
||||
ObjectProvider<MeterBinder> binders, boolean addToGlobalRegistry, boolean hasCompositeMeterRegistry) {
|
||||
this.customizers = customizers;
|
||||
this.filters = filters;
|
||||
this.binders = binders;
|
||||
|
@ -63,8 +62,7 @@ class MeterRegistryConfigurer {
|
|||
// tags or alter timer or summary configuration.
|
||||
customize(registry);
|
||||
addFilters(registry);
|
||||
if (!this.hasCompositeMeterRegistry
|
||||
|| registry instanceof CompositeMeterRegistry) {
|
||||
if (!this.hasCompositeMeterRegistry || registry instanceof CompositeMeterRegistry) {
|
||||
addBinders(registry);
|
||||
}
|
||||
if (this.addToGlobalRegistry && registry != Metrics.globalRegistry) {
|
||||
|
@ -74,11 +72,8 @@ class MeterRegistryConfigurer {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void customize(MeterRegistry registry) {
|
||||
LambdaSafe
|
||||
.callbacks(MeterRegistryCustomizer.class, asOrderedList(this.customizers),
|
||||
registry)
|
||||
.withLogger(MeterRegistryConfigurer.class)
|
||||
.invoke((customizer) -> customizer.customize(registry));
|
||||
LambdaSafe.callbacks(MeterRegistryCustomizer.class, asOrderedList(this.customizers), registry)
|
||||
.withLogger(MeterRegistryConfigurer.class).invoke((customizer) -> customizer.customize(registry));
|
||||
}
|
||||
|
||||
private void addFilters(MeterRegistry registry) {
|
||||
|
|
|
@ -48,11 +48,9 @@ class MeterRegistryPostProcessor implements BeanPostProcessor {
|
|||
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
MeterRegistryPostProcessor(ObjectProvider<MeterBinder> meterBinders,
|
||||
ObjectProvider<MeterFilter> meterFilters,
|
||||
MeterRegistryPostProcessor(ObjectProvider<MeterBinder> meterBinders, ObjectProvider<MeterFilter> meterFilters,
|
||||
ObjectProvider<MeterRegistryCustomizer<?>> meterRegistryCustomizers,
|
||||
ObjectProvider<MetricsProperties> metricsProperties,
|
||||
ApplicationContext applicationContext) {
|
||||
ObjectProvider<MetricsProperties> metricsProperties, ApplicationContext applicationContext) {
|
||||
this.meterBinders = meterBinders;
|
||||
this.meterFilters = meterFilters;
|
||||
this.meterRegistryCustomizers = meterRegistryCustomizers;
|
||||
|
@ -61,8 +59,7 @@ class MeterRegistryPostProcessor implements BeanPostProcessor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof MeterRegistry) {
|
||||
getConfigurer().configure((MeterRegistry) bean);
|
||||
}
|
||||
|
@ -72,11 +69,9 @@ class MeterRegistryPostProcessor implements BeanPostProcessor {
|
|||
private MeterRegistryConfigurer getConfigurer() {
|
||||
if (this.configurer == null) {
|
||||
boolean hasCompositeMeterRegistry = this.applicationContext
|
||||
.getBeanNamesForType(CompositeMeterRegistry.class, false,
|
||||
false).length != 0;
|
||||
this.configurer = new MeterRegistryConfigurer(this.meterRegistryCustomizers,
|
||||
this.meterFilters, this.meterBinders,
|
||||
this.metricsProperties.getObject().isUseGlobalRegistry(),
|
||||
.getBeanNamesForType(CompositeMeterRegistry.class, false, false).length != 0;
|
||||
this.configurer = new MeterRegistryConfigurer(this.meterRegistryCustomizers, this.meterFilters,
|
||||
this.meterBinders, this.metricsProperties.getObject().isUseGlobalRegistry(),
|
||||
hasCompositeMeterRegistry);
|
||||
}
|
||||
return this.configurer;
|
||||
|
|
|
@ -52,14 +52,12 @@ public class MetricsAutoConfiguration {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public static MeterRegistryPostProcessor meterRegistryPostProcessor(
|
||||
ObjectProvider<MeterBinder> meterBinders,
|
||||
public static MeterRegistryPostProcessor meterRegistryPostProcessor(ObjectProvider<MeterBinder> meterBinders,
|
||||
ObjectProvider<MeterFilter> meterFilters,
|
||||
ObjectProvider<MeterRegistryCustomizer<?>> meterRegistryCustomizers,
|
||||
ObjectProvider<MetricsProperties> metricsProperties,
|
||||
ApplicationContext applicationContext) {
|
||||
return new MeterRegistryPostProcessor(meterBinders, meterFilters,
|
||||
meterRegistryCustomizers, metricsProperties, applicationContext);
|
||||
ObjectProvider<MetricsProperties> metricsProperties, ApplicationContext applicationContext) {
|
||||
return new MeterRegistryPostProcessor(meterBinders, meterFilters, meterRegistryCustomizers, metricsProperties,
|
||||
applicationContext);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
@ -38,8 +38,7 @@ import org.springframework.context.annotation.Configuration;
|
|||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(Timed.class)
|
||||
@ConditionalOnAvailableEndpoint(endpoint = MetricsEndpoint.class)
|
||||
@AutoConfigureAfter({ MetricsAutoConfiguration.class,
|
||||
CompositeMeterRegistryAutoConfiguration.class })
|
||||
@AutoConfigureAfter({ MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class })
|
||||
public class MetricsEndpointAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
|
|
|
@ -116,8 +116,7 @@ public class MetricsProperties {
|
|||
* @deprecated since 2.2.0 in favor of {@link ClientRequest#getMetricName()}
|
||||
*/
|
||||
@Deprecated
|
||||
@DeprecatedConfigurationProperty(
|
||||
replacement = "management.metrics.web.client.request.metric-name")
|
||||
@DeprecatedConfigurationProperty(replacement = "management.metrics.web.client.request.metric-name")
|
||||
public String getRequestsMetricName() {
|
||||
return this.request.getMetricName();
|
||||
}
|
||||
|
@ -190,8 +189,7 @@ public class MetricsProperties {
|
|||
* @return {@code true} if server request should be automatically timed
|
||||
* @deprecated since 2.2.0 in favor of {@link AutoTimeProperties#isEnabled()}
|
||||
*/
|
||||
@DeprecatedConfigurationProperty(
|
||||
replacement = "management.metrics.web.server.request.autotime.enabled")
|
||||
@DeprecatedConfigurationProperty(replacement = "management.metrics.web.server.request.autotime.enabled")
|
||||
@Deprecated
|
||||
public boolean isAutoTimeRequests() {
|
||||
return this.request.getAutotime().isEnabled();
|
||||
|
@ -213,8 +211,7 @@ public class MetricsProperties {
|
|||
* @return request metric name
|
||||
* @deprecated since 2.2.0 in favor of {@link ServerRequest#getMetricName()}
|
||||
*/
|
||||
@DeprecatedConfigurationProperty(
|
||||
replacement = "management.metrics.web.server.request.metric-name")
|
||||
@DeprecatedConfigurationProperty(replacement = "management.metrics.web.server.request.metric-name")
|
||||
@Deprecated
|
||||
public String getRequestsMetricName() {
|
||||
return this.request.getMetricName();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,8 +31,7 @@ class MissingRequiredConfigurationFailureAnalyzer
|
|||
extends AbstractFailureAnalyzer<MissingRequiredConfigurationException> {
|
||||
|
||||
@Override
|
||||
protected FailureAnalysis analyze(Throwable rootFailure,
|
||||
MissingRequiredConfigurationException cause) {
|
||||
protected FailureAnalysis analyze(Throwable rootFailure, MissingRequiredConfigurationException cause) {
|
||||
StringBuilder description = new StringBuilder();
|
||||
description.append(cause.getMessage());
|
||||
if (!cause.getMessage().endsWith(".")) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,8 +36,7 @@ import org.springframework.util.Assert;
|
|||
*/
|
||||
public final class OnlyOnceLoggingDenyMeterFilter implements MeterFilter {
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(OnlyOnceLoggingDenyMeterFilter.class);
|
||||
private static final Log logger = LogFactory.getLog(OnlyOnceLoggingDenyMeterFilter.class);
|
||||
|
||||
private final AtomicBoolean alreadyWarned = new AtomicBoolean(false);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,8 +61,7 @@ public class PropertiesMeterFilter implements MeterFilter {
|
|||
return new MeterFilter() {
|
||||
};
|
||||
}
|
||||
Tags commonTags = Tags.of(tags.entrySet().stream()
|
||||
.map((entry) -> Tag.of(entry.getKey(), entry.getValue()))
|
||||
Tags commonTags = Tags.of(tags.entrySet().stream().map((entry) -> Tag.of(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toList()));
|
||||
return MeterFilter.commonTags(commonTags);
|
||||
}
|
||||
|
@ -79,19 +78,16 @@ public class PropertiesMeterFilter implements MeterFilter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DistributionStatisticConfig configure(Meter.Id id,
|
||||
DistributionStatisticConfig config) {
|
||||
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))
|
||||
.percentilesHistogram(lookupWithFallbackToAll(distribution.getPercentilesHistogram(), id, null))
|
||||
.percentiles(lookupWithFallbackToAll(distribution.getPercentiles(), id, null))
|
||||
.sla(convertSla(id.getType(), lookup(distribution.getSla(), id, null)))
|
||||
.minimumExpectedValue(convertMeterValue(id.getType(),
|
||||
lookup(distribution.getMinimumExpectedValue(), id, null)))
|
||||
.maximumExpectedValue(convertMeterValue(id.getType(),
|
||||
lookup(distribution.getMaximumExpectedValue(), id, null)))
|
||||
.minimumExpectedValue(
|
||||
convertMeterValue(id.getType(), lookup(distribution.getMinimumExpectedValue(), id, null)))
|
||||
.maximumExpectedValue(
|
||||
convertMeterValue(id.getType(), lookup(distribution.getMaximumExpectedValue(), id, null)))
|
||||
.build().merge(config);
|
||||
}
|
||||
|
||||
|
@ -99,9 +95,8 @@ public class PropertiesMeterFilter implements MeterFilter {
|
|||
if (sla == null) {
|
||||
return null;
|
||||
}
|
||||
long[] converted = Arrays.stream(sla)
|
||||
.map((candidate) -> candidate.getValue(meterType))
|
||||
.filter(Objects::nonNull).mapToLong(Long::longValue).toArray();
|
||||
long[] converted = Arrays.stream(sla).map((candidate) -> candidate.getValue(meterType)).filter(Objects::nonNull)
|
||||
.mapToLong(Long::longValue).toArray();
|
||||
return (converted.length != 0) ? converted : null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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,19 +50,16 @@ class RabbitConnectionFactoryMetricsPostProcessor implements BeanPostProcessor,
|
|||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
if (bean instanceof AbstractConnectionFactory) {
|
||||
bindConnectionFactoryToRegistry(getMeterRegistry(), beanName,
|
||||
(AbstractConnectionFactory) bean);
|
||||
bindConnectionFactoryToRegistry(getMeterRegistry(), beanName, (AbstractConnectionFactory) bean);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
private void bindConnectionFactoryToRegistry(MeterRegistry registry, String beanName,
|
||||
AbstractConnectionFactory connectionFactory) {
|
||||
ConnectionFactory rabbitConnectionFactory = connectionFactory
|
||||
.getRabbitConnectionFactory();
|
||||
ConnectionFactory rabbitConnectionFactory = connectionFactory.getRabbitConnectionFactory();
|
||||
String connectionFactoryName = getConnectionFactoryName(beanName);
|
||||
new RabbitMetrics(rabbitConnectionFactory, Tags.of("name", connectionFactoryName))
|
||||
.bindTo(registry);
|
||||
new RabbitMetrics(rabbitConnectionFactory, Tags.of("name", connectionFactoryName)).bindTo(registry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,8 +70,7 @@ class RabbitConnectionFactoryMetricsPostProcessor implements BeanPostProcessor,
|
|||
private String getConnectionFactoryName(String beanName) {
|
||||
if (beanName.length() > CONNECTION_FACTORY_SUFFIX.length()
|
||||
&& StringUtils.endsWithIgnoreCase(beanName, CONNECTION_FACTORY_SUFFIX)) {
|
||||
return beanName.substring(0,
|
||||
beanName.length() - CONNECTION_FACTORY_SUFFIX.length());
|
||||
return beanName.substring(0, beanName.length() - CONNECTION_FACTORY_SUFFIX.length());
|
||||
}
|
||||
return beanName;
|
||||
}
|
||||
|
|
|
@ -43,8 +43,7 @@ import org.springframework.context.annotation.Configuration;
|
|||
class CacheMeterBinderProvidersConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ CaffeineCache.class,
|
||||
com.github.benmanes.caffeine.cache.Cache.class })
|
||||
@ConditionalOnClass({ CaffeineCache.class, com.github.benmanes.caffeine.cache.Cache.class })
|
||||
static class CaffeineCacheMeterBinderProviderConfiguration {
|
||||
|
||||
@Bean
|
||||
|
|
|
@ -36,8 +36,7 @@ import org.springframework.context.annotation.Import;
|
|||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureAfter({ MetricsAutoConfiguration.class, CacheAutoConfiguration.class })
|
||||
@ConditionalOnBean(CacheManager.class)
|
||||
@Import({ CacheMeterBinderProvidersConfiguration.class,
|
||||
CacheMetricsRegistrarConfiguration.class })
|
||||
@Import({ CacheMeterBinderProvidersConfiguration.class, CacheMetricsRegistrarConfiguration.class })
|
||||
public class CacheMetricsAutoConfiguration {
|
||||
|
||||
}
|
||||
|
|
|
@ -51,13 +51,11 @@ class CacheMetricsRegistrarConfiguration {
|
|||
|
||||
private final Map<String, CacheManager> cacheManagers;
|
||||
|
||||
CacheMetricsRegistrarConfiguration(MeterRegistry registry,
|
||||
Collection<CacheMeterBinderProvider<?>> binderProviders,
|
||||
CacheMetricsRegistrarConfiguration(MeterRegistry registry, Collection<CacheMeterBinderProvider<?>> binderProviders,
|
||||
Map<String, CacheManager> cacheManagers) {
|
||||
this.registry = registry;
|
||||
this.cacheManagers = cacheManagers;
|
||||
this.cacheMetricsRegistrar = new CacheMetricsRegistrar(this.registry,
|
||||
binderProviders);
|
||||
this.cacheMetricsRegistrar = new CacheMetricsRegistrar(this.registry, binderProviders);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
@ -71,8 +69,8 @@ class CacheMetricsRegistrarConfiguration {
|
|||
}
|
||||
|
||||
private void bindCacheManagerToRegistry(String beanName, CacheManager cacheManager) {
|
||||
cacheManager.getCacheNames().forEach((cacheName) -> bindCacheToRegistry(beanName,
|
||||
cacheManager.getCache(cacheName)));
|
||||
cacheManager.getCacheNames()
|
||||
.forEach((cacheName) -> bindCacheToRegistry(beanName, cacheManager.getCache(cacheName)));
|
||||
}
|
||||
|
||||
private void bindCacheToRegistry(String beanName, Cache cache) {
|
||||
|
@ -88,8 +86,7 @@ class CacheMetricsRegistrarConfiguration {
|
|||
private String getCacheManagerName(String beanName) {
|
||||
if (beanName.length() > CACHE_MANAGER_SUFFIX.length()
|
||||
&& StringUtils.endsWithIgnoreCase(beanName, CACHE_MANAGER_SUFFIX)) {
|
||||
return beanName.substring(0,
|
||||
beanName.length() - CACHE_MANAGER_SUFFIX.length());
|
||||
return beanName.substring(0, beanName.length() - CACHE_MANAGER_SUFFIX.length());
|
||||
}
|
||||
return beanName;
|
||||
}
|
||||
|
|
|
@ -43,13 +43,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
* @since 2.1.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class,
|
||||
SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureAfter(MetricsAutoConfiguration.class)
|
||||
@ConditionalOnBean(Clock.class)
|
||||
@ConditionalOnClass(AppOpticsMeterRegistry.class)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.appoptics", name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.appoptics", name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@EnableConfigurationProperties(AppOpticsProperties.class)
|
||||
public class AppOpticsMetricsExportAutoConfiguration {
|
||||
|
||||
|
@ -67,12 +66,9 @@ 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()))
|
||||
public AppOpticsMeterRegistry appOpticsMeterRegistry(AppOpticsConfig config, Clock clock) {
|
||||
return AppOpticsMeterRegistry.builder(config).clock(clock).httpClient(
|
||||
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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.
|
||||
|
@ -25,8 +25,7 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.
|
|||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class AppOpticsPropertiesConfigAdapter
|
||||
extends StepRegistryPropertiesConfigAdapter<AppOpticsProperties>
|
||||
class AppOpticsPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter<AppOpticsProperties>
|
||||
implements AppOpticsConfig {
|
||||
|
||||
AppOpticsPropertiesConfigAdapter(AppOpticsProperties properties) {
|
||||
|
|
|
@ -42,13 +42,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class,
|
||||
SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureAfter(MetricsAutoConfiguration.class)
|
||||
@ConditionalOnBean(Clock.class)
|
||||
@ConditionalOnClass(AtlasMeterRegistry.class)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.atlas", name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.atlas", name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@EnableConfigurationProperties(AtlasProperties.class)
|
||||
public class AtlasMetricsExportAutoConfiguration {
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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.
|
||||
|
@ -28,8 +28,7 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.
|
|||
* @author Jon Schneider
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class AtlasPropertiesConfigAdapter extends PropertiesConfigAdapter<AtlasProperties>
|
||||
implements AtlasConfig {
|
||||
class AtlasPropertiesConfigAdapter extends PropertiesConfigAdapter<AtlasProperties> implements AtlasConfig {
|
||||
|
||||
AtlasPropertiesConfigAdapter(AtlasProperties properties) {
|
||||
super(properties);
|
||||
|
@ -87,8 +86,7 @@ class AtlasPropertiesConfigAdapter extends PropertiesConfigAdapter<AtlasProperti
|
|||
|
||||
@Override
|
||||
public Duration configRefreshFrequency() {
|
||||
return get(AtlasProperties::getConfigRefreshFrequency,
|
||||
AtlasConfig.super::configRefreshFrequency);
|
||||
return get(AtlasProperties::getConfigRefreshFrequency, AtlasConfig.super::configRefreshFrequency);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -43,13 +43,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class,
|
||||
SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureAfter(MetricsAutoConfiguration.class)
|
||||
@ConditionalOnBean(Clock.class)
|
||||
@ConditionalOnClass(DatadogMeterRegistry.class)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.datadog", name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.datadog", name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@EnableConfigurationProperties(DatadogProperties.class)
|
||||
public class DatadogMetricsExportAutoConfiguration {
|
||||
|
||||
|
@ -67,12 +66,9 @@ 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()))
|
||||
public DatadogMeterRegistry datadogMeterRegistry(DatadogConfig datadogConfig, Clock clock) {
|
||||
return DatadogMeterRegistry.builder(datadogConfig).clock(clock).httpClient(
|
||||
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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.
|
||||
|
@ -26,8 +26,8 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.
|
|||
* @author Jon Schneider
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DatadogPropertiesConfigAdapter extends
|
||||
StepRegistryPropertiesConfigAdapter<DatadogProperties> implements DatadogConfig {
|
||||
class DatadogPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter<DatadogProperties>
|
||||
implements DatadogConfig {
|
||||
|
||||
DatadogPropertiesConfigAdapter(DatadogProperties properties) {
|
||||
super(properties);
|
||||
|
@ -40,8 +40,7 @@ class DatadogPropertiesConfigAdapter extends
|
|||
|
||||
@Override
|
||||
public String applicationKey() {
|
||||
return get(DatadogProperties::getApplicationKey,
|
||||
DatadogConfig.super::applicationKey);
|
||||
return get(DatadogProperties::getApplicationKey, DatadogConfig.super::applicationKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -43,13 +43,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
* @since 2.1.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class,
|
||||
SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureAfter(MetricsAutoConfiguration.class)
|
||||
@ConditionalOnBean(Clock.class)
|
||||
@ConditionalOnClass(DynatraceMeterRegistry.class)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.dynatrace", name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.dynatrace", name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@EnableConfigurationProperties(DynatraceProperties.class)
|
||||
public class DynatraceMetricsExportAutoConfiguration {
|
||||
|
||||
|
@ -67,12 +66,9 @@ 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()))
|
||||
public DynatraceMeterRegistry dynatraceMeterRegistry(DynatraceConfig dynatraceConfig, Clock clock) {
|
||||
return DynatraceMeterRegistry.builder(dynatraceConfig).clock(clock).httpClient(
|
||||
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,7 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.
|
|||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class DynatracePropertiesConfigAdapter
|
||||
extends StepRegistryPropertiesConfigAdapter<DynatraceProperties>
|
||||
class DynatracePropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter<DynatraceProperties>
|
||||
implements DynatraceConfig {
|
||||
|
||||
DynatracePropertiesConfigAdapter(DynatraceProperties properties) {
|
||||
|
@ -45,8 +44,7 @@ class DynatracePropertiesConfigAdapter
|
|||
|
||||
@Override
|
||||
public String technologyType() {
|
||||
return get(DynatraceProperties::getTechnologyType,
|
||||
DynatraceConfig.super::technologyType);
|
||||
return get(DynatraceProperties::getTechnologyType, DynatraceConfig.super::technologyType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -43,13 +43,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
* @since 2.1.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class,
|
||||
SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureAfter(MetricsAutoConfiguration.class)
|
||||
@ConditionalOnBean(Clock.class)
|
||||
@ConditionalOnClass(ElasticMeterRegistry.class)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.elastic", name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.elastic", name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@EnableConfigurationProperties(ElasticProperties.class)
|
||||
public class ElasticMetricsExportAutoConfiguration {
|
||||
|
||||
|
@ -67,12 +66,9 @@ 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()))
|
||||
public ElasticMeterRegistry elasticMeterRegistry(ElasticConfig elasticConfig, Clock clock) {
|
||||
return ElasticMeterRegistry.builder(elasticConfig).clock(clock).httpClient(
|
||||
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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.
|
||||
|
@ -25,8 +25,8 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.
|
|||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class ElasticPropertiesConfigAdapter extends
|
||||
StepRegistryPropertiesConfigAdapter<ElasticProperties> implements ElasticConfig {
|
||||
class ElasticPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter<ElasticProperties>
|
||||
implements ElasticConfig {
|
||||
|
||||
ElasticPropertiesConfigAdapter(ElasticProperties properties) {
|
||||
super(properties);
|
||||
|
@ -44,20 +44,17 @@ class ElasticPropertiesConfigAdapter extends
|
|||
|
||||
@Override
|
||||
public String indexDateFormat() {
|
||||
return get(ElasticProperties::getIndexDateFormat,
|
||||
ElasticConfig.super::indexDateFormat);
|
||||
return get(ElasticProperties::getIndexDateFormat, ElasticConfig.super::indexDateFormat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String timestampFieldName() {
|
||||
return get(ElasticProperties::getTimestampFieldName,
|
||||
ElasticConfig.super::timestampFieldName);
|
||||
return get(ElasticProperties::getTimestampFieldName, ElasticConfig.super::timestampFieldName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean autoCreateIndex() {
|
||||
return get(ElasticProperties::isAutoCreateIndex,
|
||||
ElasticConfig.super::autoCreateIndex);
|
||||
return get(ElasticProperties::isAutoCreateIndex, ElasticConfig.super::autoCreateIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -41,13 +41,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class,
|
||||
SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureAfter(MetricsAutoConfiguration.class)
|
||||
@ConditionalOnBean(Clock.class)
|
||||
@ConditionalOnClass(GangliaMeterRegistry.class)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.ganglia", name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.ganglia", name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@EnableConfigurationProperties(GangliaProperties.class)
|
||||
public class GangliaMetricsExportAutoConfiguration {
|
||||
|
||||
|
@ -59,8 +58,7 @@ public class GangliaMetricsExportAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public GangliaMeterRegistry gangliaMeterRegistry(GangliaConfig gangliaConfig,
|
||||
Clock clock) {
|
||||
public GangliaMeterRegistry gangliaMeterRegistry(GangliaConfig gangliaConfig, Clock clock) {
|
||||
return new GangliaMeterRegistry(gangliaConfig, clock);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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.
|
||||
|
@ -30,8 +30,7 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.
|
|||
* @author Jon Schneider
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class GangliaPropertiesConfigAdapter extends PropertiesConfigAdapter<GangliaProperties>
|
||||
implements GangliaConfig {
|
||||
class GangliaPropertiesConfigAdapter extends PropertiesConfigAdapter<GangliaProperties> implements GangliaConfig {
|
||||
|
||||
GangliaPropertiesConfigAdapter(GangliaProperties properties) {
|
||||
super(properties);
|
||||
|
@ -59,20 +58,17 @@ class GangliaPropertiesConfigAdapter extends PropertiesConfigAdapter<GangliaProp
|
|||
|
||||
@Override
|
||||
public TimeUnit durationUnits() {
|
||||
return get(GangliaProperties::getDurationUnits,
|
||||
GangliaConfig.super::durationUnits);
|
||||
return get(GangliaProperties::getDurationUnits, GangliaConfig.super::durationUnits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String protocolVersion() {
|
||||
return get(GangliaProperties::getProtocolVersion,
|
||||
GangliaConfig.super::protocolVersion);
|
||||
return get(GangliaProperties::getProtocolVersion, GangliaConfig.super::protocolVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GMetric.UDPAddressingMode addressingMode() {
|
||||
return get(GangliaProperties::getAddressingMode,
|
||||
GangliaConfig.super::addressingMode);
|
||||
return get(GangliaProperties::getAddressingMode, GangliaConfig.super::addressingMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -41,13 +41,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class,
|
||||
SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureAfter(MetricsAutoConfiguration.class)
|
||||
@ConditionalOnBean(Clock.class)
|
||||
@ConditionalOnClass(GraphiteMeterRegistry.class)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.graphite", name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.graphite", name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@EnableConfigurationProperties(GraphiteProperties.class)
|
||||
public class GraphiteMetricsExportAutoConfiguration {
|
||||
|
||||
|
@ -59,8 +58,7 @@ public class GraphiteMetricsExportAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public GraphiteMeterRegistry graphiteMeterRegistry(GraphiteConfig graphiteConfig,
|
||||
Clock clock) {
|
||||
public GraphiteMeterRegistry graphiteMeterRegistry(GraphiteConfig graphiteConfig, Clock clock) {
|
||||
return new GraphiteMeterRegistry(graphiteConfig, clock);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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.
|
||||
|
@ -30,8 +30,7 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.
|
|||
* @author Jon Schneider
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class GraphitePropertiesConfigAdapter extends PropertiesConfigAdapter<GraphiteProperties>
|
||||
implements GraphiteConfig {
|
||||
class GraphitePropertiesConfigAdapter extends PropertiesConfigAdapter<GraphiteProperties> implements GraphiteConfig {
|
||||
|
||||
GraphitePropertiesConfigAdapter(GraphiteProperties properties) {
|
||||
super(properties);
|
||||
|
@ -59,8 +58,7 @@ class GraphitePropertiesConfigAdapter extends PropertiesConfigAdapter<GraphitePr
|
|||
|
||||
@Override
|
||||
public TimeUnit durationUnits() {
|
||||
return get(GraphiteProperties::getDurationUnits,
|
||||
GraphiteConfig.super::durationUnits);
|
||||
return get(GraphiteProperties::getDurationUnits, GraphiteConfig.super::durationUnits);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -80,8 +78,7 @@ class GraphitePropertiesConfigAdapter extends PropertiesConfigAdapter<GraphitePr
|
|||
|
||||
@Override
|
||||
public String[] tagsAsPrefix() {
|
||||
return get(GraphiteProperties::getTagsAsPrefix,
|
||||
GraphiteConfig.super::tagsAsPrefix);
|
||||
return get(GraphiteProperties::getTagsAsPrefix, GraphiteConfig.super::tagsAsPrefix);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,13 +43,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
* @since 2.1.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class,
|
||||
SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureAfter(MetricsAutoConfiguration.class)
|
||||
@ConditionalOnBean(Clock.class)
|
||||
@ConditionalOnClass(HumioMeterRegistry.class)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.humio", name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.humio", name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@EnableConfigurationProperties(HumioProperties.class)
|
||||
public class HumioMetricsExportAutoConfiguration {
|
||||
|
||||
|
@ -68,10 +67,8 @@ 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()))
|
||||
return HumioMeterRegistry.builder(humioConfig).clock(clock).httpClient(
|
||||
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
|
||||
.build();
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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.
|
||||
|
@ -27,8 +27,7 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.
|
|||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class HumioPropertiesConfigAdapter extends
|
||||
StepRegistryPropertiesConfigAdapter<HumioProperties> implements HumioConfig {
|
||||
class HumioPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter<HumioProperties> implements HumioConfig {
|
||||
|
||||
HumioPropertiesConfigAdapter(HumioProperties properties) {
|
||||
super(properties);
|
||||
|
|
|
@ -43,13 +43,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class,
|
||||
SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class })
|
||||
@AutoConfigureAfter(MetricsAutoConfiguration.class)
|
||||
@ConditionalOnBean(Clock.class)
|
||||
@ConditionalOnClass(InfluxMeterRegistry.class)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.influx", name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnProperty(prefix = "management.metrics.export.influx", name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@EnableConfigurationProperties(InfluxProperties.class)
|
||||
public class InfluxMetricsExportAutoConfiguration {
|
||||
|
||||
|
@ -69,10 +68,8 @@ public class InfluxMetricsExportAutoConfiguration {
|
|||
@ConditionalOnMissingBean
|
||||
public InfluxMeterRegistry influxMeterRegistry(InfluxConfig influxConfig, Clock clock,
|
||||
InfluxProperties influxProperties) {
|
||||
return InfluxMeterRegistry.builder(influxConfig).clock(clock)
|
||||
.httpClient(
|
||||
new HttpUrlConnectionSender(this.properties.getConnectTimeout(),
|
||||
this.properties.getReadTimeout()))
|
||||
return InfluxMeterRegistry.builder(influxConfig).clock(clock).httpClient(
|
||||
new HttpUrlConnectionSender(this.properties.getConnectTimeout(), this.properties.getReadTimeout()))
|
||||
.build();
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 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.
|
||||
|
@ -27,8 +27,8 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.
|
|||
* @author Jon Schneider
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class InfluxPropertiesConfigAdapter extends
|
||||
StepRegistryPropertiesConfigAdapter<InfluxProperties> implements InfluxConfig {
|
||||
class InfluxPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter<InfluxProperties>
|
||||
implements InfluxConfig {
|
||||
|
||||
InfluxPropertiesConfigAdapter(InfluxProperties properties) {
|
||||
super(properties);
|
||||
|
@ -56,26 +56,22 @@ class InfluxPropertiesConfigAdapter extends
|
|||
|
||||
@Override
|
||||
public String retentionPolicy() {
|
||||
return get(InfluxProperties::getRetentionPolicy,
|
||||
InfluxConfig.super::retentionPolicy);
|
||||
return get(InfluxProperties::getRetentionPolicy, InfluxConfig.super::retentionPolicy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer retentionReplicationFactor() {
|
||||
return get(InfluxProperties::getRetentionReplicationFactor,
|
||||
InfluxConfig.super::retentionReplicationFactor);
|
||||
return get(InfluxProperties::getRetentionReplicationFactor, InfluxConfig.super::retentionReplicationFactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String retentionDuration() {
|
||||
return get(InfluxProperties::getRetentionDuration,
|
||||
InfluxConfig.super::retentionDuration);
|
||||
return get(InfluxProperties::getRetentionDuration, InfluxConfig.super::retentionDuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String retentionShardDuration() {
|
||||
return get(InfluxProperties::getRetentionShardDuration,
|
||||
InfluxConfig.super::retentionShardDuration);
|
||||
return get(InfluxProperties::getRetentionShardDuration, InfluxConfig.super::retentionShardDuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue