Merge branch '2.7.x' into 3.0.x
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,7 +46,7 @@ public class RabbitHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
private String getVersion() {
|
||||
return this.rabbitTemplate
|
||||
.execute((channel) -> channel.getConnection().getServerProperties().get("version").toString());
|
||||
.execute((channel) -> channel.getConnection().getServerProperties().get("version").toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -109,14 +109,22 @@ public class CachesEndpoint {
|
||||
|
||||
private List<CacheEntryDescriptor> getCacheEntries(Predicate<String> cacheNamePredicate,
|
||||
Predicate<String> cacheManagerNamePredicate) {
|
||||
return this.cacheManagers.keySet().stream().filter(cacheManagerNamePredicate)
|
||||
.flatMap((cacheManagerName) -> getCacheEntries(cacheManagerName, cacheNamePredicate).stream()).toList();
|
||||
return this.cacheManagers.keySet()
|
||||
.stream()
|
||||
.filter(cacheManagerNamePredicate)
|
||||
.flatMap((cacheManagerName) -> getCacheEntries(cacheManagerName, cacheNamePredicate).stream())
|
||||
.toList();
|
||||
}
|
||||
|
||||
private List<CacheEntryDescriptor> getCacheEntries(String cacheManagerName, Predicate<String> cacheNamePredicate) {
|
||||
CacheManager cacheManager = this.cacheManagers.get(cacheManagerName);
|
||||
return cacheManager.getCacheNames().stream().filter(cacheNamePredicate).map(cacheManager::getCache)
|
||||
.filter(Objects::nonNull).map((cache) -> new CacheEntryDescriptor(cache, cacheManagerName)).toList();
|
||||
return cacheManager.getCacheNames()
|
||||
.stream()
|
||||
.filter(cacheNamePredicate)
|
||||
.map(cacheManager::getCache)
|
||||
.filter(Objects::nonNull)
|
||||
.map((cache) -> new CacheEntryDescriptor(cache, cacheManagerName))
|
||||
.toList();
|
||||
}
|
||||
|
||||
private CacheEntryDescriptor extractUniqueCacheEntry(String cache, List<CacheEntryDescriptor> entries) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -189,8 +189,8 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
|
||||
private void applyConfigurationPropertiesFilter(JsonMapper.Builder builder) {
|
||||
builder.annotationIntrospector(new ConfigurationPropertiesAnnotationIntrospector());
|
||||
builder.filterProvider(
|
||||
new SimpleFilterProvider().setDefaultFilter(new ConfigurationPropertiesPropertyFilter()));
|
||||
builder
|
||||
.filterProvider(new SimpleFilterProvider().setDefaultFilter(new ConfigurationPropertiesPropertyFilter()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,16 +199,18 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
*/
|
||||
private void applySerializationModifier(JsonMapper.Builder builder) {
|
||||
SerializerFactory factory = BeanSerializerFactory.instance
|
||||
.withSerializerModifier(new GenericSerializerModifier());
|
||||
.withSerializerModifier(new GenericSerializerModifier());
|
||||
builder.serializerFactory(factory);
|
||||
}
|
||||
|
||||
private ContextConfigurationPropertiesDescriptor describeBeans(ObjectMapper mapper, ApplicationContext context,
|
||||
Predicate<ConfigurationPropertiesBean> beanFilterPredicate, boolean showUnsanitized) {
|
||||
Map<String, ConfigurationPropertiesBean> beans = ConfigurationPropertiesBean.getAll(context);
|
||||
Map<String, ConfigurationPropertiesBeanDescriptor> descriptors = beans.values().stream()
|
||||
.filter(beanFilterPredicate).collect(Collectors.toMap(ConfigurationPropertiesBean::getName,
|
||||
(bean) -> describeBean(mapper, bean, showUnsanitized)));
|
||||
Map<String, ConfigurationPropertiesBeanDescriptor> descriptors = beans.values()
|
||||
.stream()
|
||||
.filter(beanFilterPredicate)
|
||||
.collect(Collectors.toMap(ConfigurationPropertiesBean::getName,
|
||||
(bean) -> describeBean(mapper, bean, showUnsanitized)));
|
||||
return new ContextConfigurationPropertiesDescriptor(descriptors,
|
||||
(context.getParent() != null) ? context.getParent().getId() : null);
|
||||
}
|
||||
@@ -508,9 +510,10 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
names = new String[parameters.length];
|
||||
}
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
String name = MergedAnnotations.from(parameters[i]).get(Name.class)
|
||||
.getValue(MergedAnnotation.VALUE, String.class)
|
||||
.orElse((names[i] != null) ? names[i] : parameters[i].getName());
|
||||
String name = MergedAnnotations.from(parameters[i])
|
||||
.get(Name.class)
|
||||
.getValue(MergedAnnotation.VALUE, String.class)
|
||||
.orElse((names[i] != null) ? names[i] : parameters[i].getName());
|
||||
if (name.equals(writer.getName())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -61,8 +61,10 @@ public class ConfigurationPropertiesReportEndpointWebExtension {
|
||||
boolean showUnsanitized = this.showValues.isShown(securityContext, this.roles);
|
||||
ConfigurationPropertiesDescriptor configurationProperties = this.delegate.getConfigurationProperties(prefix,
|
||||
showUnsanitized);
|
||||
boolean foundMatchingBeans = configurationProperties.getContexts().values().stream()
|
||||
.anyMatch((context) -> !context.getBeans().isEmpty());
|
||||
boolean foundMatchingBeans = configurationProperties.getContexts()
|
||||
.values()
|
||||
.stream()
|
||||
.anyMatch((context) -> !context.getBeans().isEmpty());
|
||||
return (foundMatchingBeans) ? new WebEndpointResponse<>(configurationProperties, WebEndpointResponse.STATUS_OK)
|
||||
: new WebEndpointResponse<>(WebEndpointResponse.STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,8 +42,13 @@ class CouchbaseHealth {
|
||||
void applyTo(Builder builder) {
|
||||
builder = isCouchbaseUp(this.diagnostics) ? builder.up() : builder.down();
|
||||
builder.withDetail("sdk", this.diagnostics.sdk());
|
||||
builder.withDetail("endpoints", this.diagnostics.endpoints().values().stream().flatMap(Collection::stream)
|
||||
.map(this::describe).toList());
|
||||
builder.withDetail("endpoints",
|
||||
this.diagnostics.endpoints()
|
||||
.values()
|
||||
.stream()
|
||||
.flatMap(Collection::stream)
|
||||
.map(this::describe)
|
||||
.toList());
|
||||
}
|
||||
|
||||
private boolean isCouchbaseUp(DiagnosticsResult diagnostics) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -54,12 +54,12 @@ public class RedisReactiveHealthIndicator extends AbstractReactiveHealthIndicato
|
||||
|
||||
private Mono<ReactiveRedisConnection> getConnection() {
|
||||
return Mono.fromSupplier(this.connectionFactory::getReactiveConnection)
|
||||
.subscribeOn(Schedulers.boundedElastic());
|
||||
.subscribeOn(Schedulers.boundedElastic());
|
||||
}
|
||||
|
||||
private Mono<Health> doHealthCheck(Health.Builder builder, ReactiveRedisConnection connection) {
|
||||
return getHealth(builder, connection).onErrorResume((ex) -> Mono.just(builder.down(ex).build()))
|
||||
.flatMap((health) -> connection.closeLater().thenReturn(health));
|
||||
.flatMap((health) -> connection.closeLater().thenReturn(health));
|
||||
}
|
||||
|
||||
private Mono<Health> getHealth(Health.Builder builder, ReactiveRedisConnection connection) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -70,7 +70,7 @@ public abstract class AbstractDiscoveredEndpoint<O extends Operation> extends Ab
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringCreator creator = new ToStringCreator(this).append("discoverer", this.discoverer.getClass().getName())
|
||||
.append("endpointBean", this.endpointBean.getClass().getName());
|
||||
.append("endpointBean", this.endpointBean.getClass().getName());
|
||||
appendFields(creator);
|
||||
return creator.toString();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -63,7 +63,7 @@ public abstract class AbstractDiscoveredOperation implements Operation {
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringCreator creator = new ToStringCreator(this).append("operationMethod", this.operationMethod)
|
||||
.append("invoker", this.invoker);
|
||||
.append("invoker", this.invoker);
|
||||
appendFields(creator);
|
||||
return creator.toString();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -70,14 +70,17 @@ abstract class DiscoveredOperationsFactory<O extends Operation> {
|
||||
|
||||
Collection<O> createOperations(EndpointId id, Object target) {
|
||||
return MethodIntrospector
|
||||
.selectMethods(target.getClass(), (MetadataLookup<O>) (method) -> createOperation(id, target, method))
|
||||
.values();
|
||||
.selectMethods(target.getClass(), (MetadataLookup<O>) (method) -> createOperation(id, target, method))
|
||||
.values();
|
||||
}
|
||||
|
||||
private O createOperation(EndpointId endpointId, Object target, Method method) {
|
||||
return OPERATION_TYPES.entrySet().stream()
|
||||
.map((entry) -> createOperation(endpointId, target, method, entry.getKey(), entry.getValue()))
|
||||
.filter(Objects::nonNull).findFirst().orElse(null);
|
||||
return OPERATION_TYPES.entrySet()
|
||||
.stream()
|
||||
.map((entry) -> createOperation(endpointId, target, method, entry.getKey(), entry.getValue()))
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private O createOperation(EndpointId endpointId, Object target, Method method, OperationType operationType,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -148,7 +148,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
|
||||
private void addExtensionBeans(Collection<EndpointBean> endpointBeans) {
|
||||
Map<EndpointId, EndpointBean> byId = endpointBeans.stream()
|
||||
.collect(Collectors.toMap(EndpointBean::getId, Function.identity()));
|
||||
.collect(Collectors.toMap(EndpointBean::getId, Function.identity()));
|
||||
String[] beanNames = BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.applicationContext,
|
||||
EndpointExtension.class);
|
||||
for (String beanName : beanNames) {
|
||||
@@ -190,8 +190,10 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
EndpointId id = endpointBean.getId();
|
||||
addOperations(indexed, id, endpointBean.getBean(), false);
|
||||
if (endpointBean.getExtensions().size() > 1) {
|
||||
String extensionBeans = endpointBean.getExtensions().stream().map(ExtensionBean::getBeanName)
|
||||
.collect(Collectors.joining(", "));
|
||||
String extensionBeans = endpointBean.getExtensions()
|
||||
.stream()
|
||||
.map(ExtensionBean::getBeanName)
|
||||
.collect(Collectors.joining(", "));
|
||||
throw new IllegalStateException("Found multiple extensions for the endpoint bean "
|
||||
+ endpointBean.getBeanName() + " (" + extensionBeans + ")");
|
||||
}
|
||||
@@ -222,12 +224,16 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
}
|
||||
|
||||
private void assertNoDuplicateOperations(EndpointBean endpointBean, MultiValueMap<OperationKey, O> indexed) {
|
||||
List<OperationKey> duplicates = indexed.entrySet().stream().filter((entry) -> entry.getValue().size() > 1)
|
||||
.map(Map.Entry::getKey).toList();
|
||||
List<OperationKey> duplicates = indexed.entrySet()
|
||||
.stream()
|
||||
.filter((entry) -> entry.getValue().size() > 1)
|
||||
.map(Map.Entry::getKey)
|
||||
.toList();
|
||||
if (!duplicates.isEmpty()) {
|
||||
Set<ExtensionBean> extensions = endpointBean.getExtensions();
|
||||
String extensionBeanNames = extensions.stream().map(ExtensionBean::getBeanName)
|
||||
.collect(Collectors.joining(", "));
|
||||
String extensionBeanNames = extensions.stream()
|
||||
.map(ExtensionBean::getBeanName)
|
||||
.collect(Collectors.joining(", "));
|
||||
throw new IllegalStateException("Unable to map duplicate endpoint operations: " + duplicates.toString()
|
||||
+ " to " + endpointBean.getBeanName()
|
||||
+ (extensions.isEmpty() ? "" : " (" + extensionBeanNames + ")"));
|
||||
@@ -296,8 +302,10 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean isFilterMatch(EndpointFilter<E> filter, E endpoint) {
|
||||
return LambdaSafe.callback(EndpointFilter.class, filter, endpoint).withLogger(EndpointDiscoverer.class)
|
||||
.invokeAnd((f) -> f.match(endpoint)).get();
|
||||
return LambdaSafe.callback(EndpointFilter.class, filter, endpoint)
|
||||
.withLogger(EndpointDiscoverer.class)
|
||||
.invokeAnd((f) -> f.match(endpoint))
|
||||
.get();
|
||||
}
|
||||
|
||||
private E getFilterEndpoint(EndpointBean endpointBean) {
|
||||
@@ -409,7 +417,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
|
||||
EndpointBean(Environment environment, String beanName, Class<?> beanType, Supplier<Object> beanSupplier) {
|
||||
MergedAnnotation<Endpoint> annotation = MergedAnnotations.from(beanType, SearchStrategy.TYPE_HIERARCHY)
|
||||
.get(Endpoint.class);
|
||||
.get(Endpoint.class);
|
||||
String id = annotation.getString("id");
|
||||
Assert.state(StringUtils.hasText(id),
|
||||
() -> "No @Endpoint id attribute specified for " + beanType.getName());
|
||||
@@ -430,8 +438,10 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
}
|
||||
|
||||
private Class<?> getFilter(Class<?> type) {
|
||||
return MergedAnnotations.from(type, SearchStrategy.TYPE_HIERARCHY).get(FilteredEndpoint.class)
|
||||
.getValue(MergedAnnotation.VALUE, Class.class).orElse(null);
|
||||
return MergedAnnotations.from(type, SearchStrategy.TYPE_HIERARCHY)
|
||||
.get(FilteredEndpoint.class)
|
||||
.getValue(MergedAnnotation.VALUE, Class.class)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
String getBeanName() {
|
||||
@@ -480,10 +490,12 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
this.beanType = beanType;
|
||||
this.beanSupplier = beanSupplier;
|
||||
MergedAnnotation<EndpointExtension> extensionAnnotation = MergedAnnotations
|
||||
.from(beanType, SearchStrategy.TYPE_HIERARCHY).get(EndpointExtension.class);
|
||||
.from(beanType, SearchStrategy.TYPE_HIERARCHY)
|
||||
.get(EndpointExtension.class);
|
||||
Class<?> endpointType = extensionAnnotation.getClass("endpoint");
|
||||
MergedAnnotation<Endpoint> endpointAnnotation = MergedAnnotations
|
||||
.from(endpointType, SearchStrategy.TYPE_HIERARCHY).get(Endpoint.class);
|
||||
.from(endpointType, SearchStrategy.TYPE_HIERARCHY)
|
||||
.get(Endpoint.class);
|
||||
Assert.state(endpointAnnotation.isPresent(),
|
||||
() -> "Extension " + endpointType.getName() + " does not specify an endpoint");
|
||||
this.endpointId = EndpointId.of(environment, endpointAnnotation.getString("id"));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,6 +39,7 @@ import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
||||
* boolean enableByDefault() default true;
|
||||
*
|
||||
* } </pre>
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
* @see DiscovererEndpointFilter
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -75,8 +75,10 @@ public class ReflectiveOperationInvoker implements OperationInvoker {
|
||||
}
|
||||
|
||||
private void validateRequiredParameters(InvocationContext context) {
|
||||
Set<OperationParameter> missing = this.operationMethod.getParameters().stream()
|
||||
.filter((parameter) -> isMissing(context, parameter)).collect(Collectors.toSet());
|
||||
Set<OperationParameter> missing = this.operationMethod.getParameters()
|
||||
.stream()
|
||||
.filter((parameter) -> isMissing(context, parameter))
|
||||
.collect(Collectors.toSet());
|
||||
if (!missing.isEmpty()) {
|
||||
throw new MissingParametersException(missing);
|
||||
}
|
||||
@@ -93,8 +95,10 @@ public class ReflectiveOperationInvoker implements OperationInvoker {
|
||||
}
|
||||
|
||||
private Object[] resolveArguments(InvocationContext context) {
|
||||
return this.operationMethod.getParameters().stream().map((parameter) -> resolveArgument(parameter, context))
|
||||
.toArray();
|
||||
return this.operationMethod.getParameters()
|
||||
.stream()
|
||||
.map((parameter) -> resolveArgument(parameter, context))
|
||||
.toArray();
|
||||
}
|
||||
|
||||
private Object resolveArgument(OperationParameter parameter, InvocationContext context) {
|
||||
@@ -108,8 +112,9 @@ public class ReflectiveOperationInvoker implements OperationInvoker {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringCreator(this).append("target", this.target).append("method", this.operationMethod)
|
||||
.toString();
|
||||
return new ToStringCreator(this).append("target", this.target)
|
||||
.append("method", this.operationMethod)
|
||||
.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -115,8 +115,10 @@ public class EndpointMBean implements DynamicMBean {
|
||||
|
||||
private Object invoke(JmxOperation operation, Object[] params) throws MBeanException, ReflectionException {
|
||||
try {
|
||||
String[] parameterNames = operation.getParameters().stream().map(JmxOperationParameter::getName)
|
||||
.toArray(String[]::new);
|
||||
String[] parameterNames = operation.getParameters()
|
||||
.stream()
|
||||
.map(JmxOperationParameter::getName)
|
||||
.toArray(String[]::new);
|
||||
Map<String, Object> arguments = getArguments(parameterNames, params);
|
||||
InvocationContext context = new InvocationContext(SecurityContext.NONE, arguments);
|
||||
Object result = operation.invoke(context);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,8 +41,8 @@ public class JacksonJmxOperationResponseMapper implements JmxOperationResponseMa
|
||||
public JacksonJmxOperationResponseMapper(ObjectMapper objectMapper) {
|
||||
this.objectMapper = (objectMapper != null) ? objectMapper : new ObjectMapper();
|
||||
this.listType = this.objectMapper.getTypeFactory().constructParametricType(List.class, Object.class);
|
||||
this.mapType = this.objectMapper.getTypeFactory().constructParametricType(Map.class, String.class,
|
||||
Object.class);
|
||||
this.mapType = this.objectMapper.getTypeFactory()
|
||||
.constructParametricType(Map.class, String.class, Object.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -83,8 +83,9 @@ class DiscoveredJmxOperation extends AbstractDiscoveredOperation implements JmxO
|
||||
Method method = operationMethod.getMethod();
|
||||
ManagedOperationParameter[] managed = jmxAttributeSource.getManagedOperationParameters(method);
|
||||
if (managed.length == 0) {
|
||||
Stream<JmxOperationParameter> parameters = operationMethod.getParameters().stream()
|
||||
.map(DiscoveredJmxOperationParameter::new);
|
||||
Stream<JmxOperationParameter> parameters = operationMethod.getParameters()
|
||||
.stream()
|
||||
.map(DiscoveredJmxOperationParameter::new);
|
||||
return parameters.toList();
|
||||
}
|
||||
return mergeParameters(operationMethod.getParameters(), managed);
|
||||
@@ -121,8 +122,10 @@ class DiscoveredJmxOperation extends AbstractDiscoveredOperation implements JmxO
|
||||
|
||||
@Override
|
||||
protected void appendFields(ToStringCreator creator) {
|
||||
creator.append("name", this.name).append("outputType", this.outputType).append("description", this.description)
|
||||
.append("parameters", this.parameters);
|
||||
creator.append("name", this.name)
|
||||
.append("outputType", this.outputType)
|
||||
.append("description", this.description)
|
||||
.append("parameters", this.parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -90,8 +90,8 @@ public class ControllerEndpointDiscoverer extends EndpointDiscoverer<ExposableCo
|
||||
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
|
||||
hints.reflection().registerType(ControllerEndpointFilter.class,
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
hints.reflection()
|
||||
.registerType(ControllerEndpointFilter.class, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -60,8 +60,11 @@ class DiscoveredWebOperation extends AbstractDiscoveredOperation implements WebO
|
||||
}
|
||||
|
||||
private String getId(EndpointId endpointId, OperationMethod method) {
|
||||
return endpointId + method.getParameters().stream().filter(this::hasSelector).map(this::dashName)
|
||||
.collect(Collectors.joining());
|
||||
return endpointId + method.getParameters()
|
||||
.stream()
|
||||
.filter(this::hasSelector)
|
||||
.map(this::dashName)
|
||||
.collect(Collectors.joining());
|
||||
}
|
||||
|
||||
private boolean hasSelector(OperationParameter parameter) {
|
||||
@@ -93,8 +96,9 @@ class DiscoveredWebOperation extends AbstractDiscoveredOperation implements WebO
|
||||
|
||||
@Override
|
||||
protected void appendFields(ToStringCreator creator) {
|
||||
creator.append("id", this.id).append("blocking", this.blocking).append("requestPredicate",
|
||||
this.requestPredicate);
|
||||
creator.append("id", this.id)
|
||||
.append("blocking", this.blocking)
|
||||
.append("requestPredicate", this.requestPredicate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,8 +53,10 @@ class RequestPredicateFactory {
|
||||
|
||||
WebOperationRequestPredicate getRequestPredicate(String rootPath, DiscoveredOperationMethod operationMethod) {
|
||||
Method method = operationMethod.getMethod();
|
||||
OperationParameter[] selectorParameters = operationMethod.getParameters().stream().filter(this::hasSelector)
|
||||
.toArray(OperationParameter[]::new);
|
||||
OperationParameter[] selectorParameters = operationMethod.getParameters()
|
||||
.stream()
|
||||
.filter(this::hasSelector)
|
||||
.toArray(OperationParameter[]::new);
|
||||
OperationParameter allRemainingPathSegmentsParameter = getAllRemainingPathSegmentsParameter(selectorParameters);
|
||||
String path = getPath(rootPath, selectorParameters, allRemainingPathSegmentsParameter != null);
|
||||
WebEndpointHttpMethod httpMethod = determineHttpMethod(operationMethod.getOperationType());
|
||||
@@ -131,7 +133,7 @@ class RequestPredicateFactory {
|
||||
|
||||
private boolean consumesRequestBody(Method method) {
|
||||
return Stream.of(method.getParameters())
|
||||
.anyMatch((parameter) -> parameter.getAnnotation(Selector.class) == null);
|
||||
.anyMatch((parameter) -> parameter.getAnnotation(Selector.class) == null);
|
||||
}
|
||||
|
||||
private WebEndpointHttpMethod determineHttpMethod(OperationType operationType) {
|
||||
|
||||
@@ -84,8 +84,10 @@ public class JerseyEndpointResourceFactory {
|
||||
Collection<ExposableWebEndpoint> endpoints, EndpointMediaTypes endpointMediaTypes,
|
||||
EndpointLinksResolver linksResolver, boolean shouldRegisterLinks) {
|
||||
List<Resource> resources = new ArrayList<>();
|
||||
endpoints.stream().flatMap((endpoint) -> endpoint.getOperations().stream())
|
||||
.map((operation) -> createResource(endpointMapping, operation)).forEach(resources::add);
|
||||
endpoints.stream()
|
||||
.flatMap((endpoint) -> endpoint.getOperations().stream())
|
||||
.map((operation) -> createResource(endpointMapping, operation))
|
||||
.forEach(resources::add);
|
||||
if (shouldRegisterLinks) {
|
||||
Resource resource = createEndpointLinksResource(endpointMapping.getPath(), endpointMediaTypes,
|
||||
linksResolver);
|
||||
@@ -108,21 +110,23 @@ public class JerseyEndpointResourceFactory {
|
||||
protected Resource getResource(EndpointMapping endpointMapping, WebOperation operation,
|
||||
WebOperationRequestPredicate requestPredicate, String path, WebServerNamespace serverNamespace,
|
||||
JerseyRemainingPathSegmentProvider remainingPathSegmentProvider) {
|
||||
Builder resourceBuilder = Resource.builder().path(endpointMapping.getPath())
|
||||
.path(endpointMapping.createSubPath(path));
|
||||
Builder resourceBuilder = Resource.builder()
|
||||
.path(endpointMapping.getPath())
|
||||
.path(endpointMapping.createSubPath(path));
|
||||
resourceBuilder.addMethod(requestPredicate.getHttpMethod().name())
|
||||
.consumes(StringUtils.toStringArray(requestPredicate.getConsumes()))
|
||||
.produces(StringUtils.toStringArray(requestPredicate.getProduces()))
|
||||
.handledBy(new OperationInflector(operation, !requestPredicate.getConsumes().isEmpty(), serverNamespace,
|
||||
remainingPathSegmentProvider));
|
||||
.consumes(StringUtils.toStringArray(requestPredicate.getConsumes()))
|
||||
.produces(StringUtils.toStringArray(requestPredicate.getProduces()))
|
||||
.handledBy(new OperationInflector(operation, !requestPredicate.getConsumes().isEmpty(), serverNamespace,
|
||||
remainingPathSegmentProvider));
|
||||
return resourceBuilder.build();
|
||||
}
|
||||
|
||||
private Resource createEndpointLinksResource(String endpointPath, EndpointMediaTypes endpointMediaTypes,
|
||||
EndpointLinksResolver linksResolver) {
|
||||
Builder resourceBuilder = Resource.builder().path(endpointPath);
|
||||
resourceBuilder.addMethod("GET").produces(StringUtils.toStringArray(endpointMediaTypes.getProduced()))
|
||||
.handledBy(new EndpointLinksInflector(linksResolver));
|
||||
resourceBuilder.addMethod("GET")
|
||||
.produces(StringUtils.toStringArray(endpointMediaTypes.getProduced()))
|
||||
.handledBy(new EndpointLinksInflector(linksResolver));
|
||||
return resourceBuilder.build();
|
||||
}
|
||||
|
||||
@@ -172,7 +176,7 @@ public class JerseyEndpointResourceFactory {
|
||||
try {
|
||||
JerseySecurityContext securityContext = new JerseySecurityContext(data.getSecurityContext());
|
||||
OperationArgumentResolver serverNamespaceArgumentResolver = OperationArgumentResolver
|
||||
.of(WebServerNamespace.class, () -> this.serverNamespace);
|
||||
.of(WebServerNamespace.class, () -> this.serverNamespace);
|
||||
InvocationContext invocationContext = new InvocationContext(securityContext, arguments,
|
||||
serverNamespaceArgumentResolver,
|
||||
new ProducibleOperationArgumentResolver(() -> data.getHeaders().get("Accept")));
|
||||
@@ -193,7 +197,7 @@ public class JerseyEndpointResourceFactory {
|
||||
private Map<String, Object> extractPathParameters(ContainerRequestContext requestContext) {
|
||||
Map<String, Object> pathParameters = extract(requestContext.getUriInfo().getPathParameters());
|
||||
String matchAllRemainingPathSegmentsVariable = this.operation.getRequestPredicate()
|
||||
.getMatchAllRemainingPathSegmentsVariable();
|
||||
.getMatchAllRemainingPathSegmentsVariable();
|
||||
if (matchAllRemainingPathSegmentsVariable != null) {
|
||||
String remainingPathSegments = getRemainingPathSegments(requestContext, pathParameters,
|
||||
matchAllRemainingPathSegmentsVariable);
|
||||
@@ -244,8 +248,9 @@ public class JerseyEndpointResourceFactory {
|
||||
return Response.status(Status.OK).entity(convertIfNecessary(response)).build();
|
||||
}
|
||||
return Response.status(webEndpointResponse.getStatus())
|
||||
.header("Content-Type", webEndpointResponse.getContentType())
|
||||
.entity(convertIfNecessary(webEndpointResponse.getBody())).build();
|
||||
.header("Content-Type", webEndpointResponse.getContentType())
|
||||
.entity(convertIfNecessary(webEndpointResponse.getBody()))
|
||||
.build();
|
||||
}
|
||||
|
||||
private Object convertIfNecessary(Object body) {
|
||||
@@ -322,7 +327,7 @@ public class JerseyEndpointResourceFactory {
|
||||
@Override
|
||||
public Response apply(ContainerRequestContext request) {
|
||||
Map<String, Link> links = this.linksResolver
|
||||
.resolveLinks(request.getUriInfo().getAbsolutePath().toString());
|
||||
.resolveLinks(request.getUriInfo().getAbsolutePath().toString());
|
||||
Map<String, Map<String, Link>> entity = OperationResponseBody.of(Collections.singletonMap("_links", links));
|
||||
return Response.ok(entity).build();
|
||||
}
|
||||
|
||||
@@ -186,8 +186,10 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
|
||||
String path = this.endpointMapping.getPath();
|
||||
String linksPath = StringUtils.hasLength(path) ? path : "/";
|
||||
String[] produces = StringUtils.toStringArray(this.endpointMediaTypes.getProduced());
|
||||
RequestMappingInfo mapping = RequestMappingInfo.paths(linksPath).methods(RequestMethod.GET).produces(produces)
|
||||
.build();
|
||||
RequestMappingInfo mapping = RequestMappingInfo.paths(linksPath)
|
||||
.methods(RequestMethod.GET)
|
||||
.produces(produces)
|
||||
.build();
|
||||
LinksHandler linksHandler = getLinksHandler();
|
||||
registerMapping(mapping, linksHandler,
|
||||
ReflectionUtils.findMethod(linksHandler.getClass(), "links", ServerWebExchange.class));
|
||||
@@ -305,8 +307,8 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
|
||||
|
||||
Mono<? extends SecurityContext> springSecurityContext() {
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map((securityContext) -> new ReactiveSecurityContext(securityContext.getAuthentication()))
|
||||
.switchIfEmpty(Mono.just(new ReactiveSecurityContext(null)));
|
||||
.map((securityContext) -> new ReactiveSecurityContext(securityContext.getAuthentication()))
|
||||
.switchIfEmpty(Mono.just(new ReactiveSecurityContext(null)));
|
||||
}
|
||||
|
||||
Mono<SecurityContext> emptySecurityContext() {
|
||||
@@ -317,29 +319,30 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
|
||||
public Mono<ResponseEntity<Object>> handle(ServerWebExchange exchange, Map<String, String> body) {
|
||||
Map<String, Object> arguments = getArguments(exchange, body);
|
||||
OperationArgumentResolver serverNamespaceArgumentResolver = OperationArgumentResolver
|
||||
.of(WebServerNamespace.class, () -> WebServerNamespace
|
||||
.from(WebServerApplicationContext.getServerNamespace(exchange.getApplicationContext())));
|
||||
.of(WebServerNamespace.class, () -> WebServerNamespace
|
||||
.from(WebServerApplicationContext.getServerNamespace(exchange.getApplicationContext())));
|
||||
return this.securityContextSupplier.get()
|
||||
.map((securityContext) -> new InvocationContext(securityContext, arguments,
|
||||
serverNamespaceArgumentResolver,
|
||||
new ProducibleOperationArgumentResolver(
|
||||
() -> exchange.getRequest().getHeaders().get("Accept"))))
|
||||
.flatMap((invocationContext) -> handleResult((Publisher<?>) this.invoker.invoke(invocationContext),
|
||||
exchange.getRequest().getMethod()));
|
||||
.map((securityContext) -> new InvocationContext(securityContext, arguments,
|
||||
serverNamespaceArgumentResolver,
|
||||
new ProducibleOperationArgumentResolver(
|
||||
() -> exchange.getRequest().getHeaders().get("Accept"))))
|
||||
.flatMap((invocationContext) -> handleResult((Publisher<?>) this.invoker.invoke(invocationContext),
|
||||
exchange.getRequest().getMethod()));
|
||||
}
|
||||
|
||||
private Map<String, Object> getArguments(ServerWebExchange exchange, Map<String, String> body) {
|
||||
Map<String, Object> arguments = new LinkedHashMap<>(getTemplateVariables(exchange));
|
||||
String matchAllRemainingPathSegmentsVariable = this.operation.getRequestPredicate()
|
||||
.getMatchAllRemainingPathSegmentsVariable();
|
||||
.getMatchAllRemainingPathSegmentsVariable();
|
||||
if (matchAllRemainingPathSegmentsVariable != null) {
|
||||
arguments.put(matchAllRemainingPathSegmentsVariable, getRemainingPathSegments(exchange));
|
||||
}
|
||||
if (body != null) {
|
||||
arguments.putAll(body);
|
||||
}
|
||||
exchange.getRequest().getQueryParams()
|
||||
.forEach((name, values) -> arguments.put(name, (values.size() != 1) ? values : values.get(0)));
|
||||
exchange.getRequest()
|
||||
.getQueryParams()
|
||||
.forEach((name, values) -> arguments.put(name, (values.size() != 1) ? values : values.get(0)));
|
||||
return arguments;
|
||||
}
|
||||
|
||||
@@ -347,7 +350,8 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
|
||||
PathPattern pathPattern = exchange.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
||||
if (pathPattern.hasPatternSyntax()) {
|
||||
String remainingSegments = pathPattern
|
||||
.extractPathWithinPattern(exchange.getRequest().getPath().pathWithinApplication()).value();
|
||||
.extractPathWithinPattern(exchange.getRequest().getPath().pathWithinApplication())
|
||||
.value();
|
||||
return tokenizePathSegments(remainingSegments);
|
||||
}
|
||||
return tokenizePathSegments(pathPattern.toString());
|
||||
@@ -371,11 +375,12 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
|
||||
if (result instanceof Flux) {
|
||||
result = ((Flux<?>) result).collectList();
|
||||
}
|
||||
return Mono.from(result).map(this::toResponseEntity)
|
||||
.onErrorMap(InvalidEndpointRequestException.class,
|
||||
(ex) -> new ResponseStatusException(HttpStatus.BAD_REQUEST, ex.getReason()))
|
||||
.defaultIfEmpty(new ResponseEntity<>(
|
||||
(httpMethod != HttpMethod.GET) ? HttpStatus.NO_CONTENT : HttpStatus.NOT_FOUND));
|
||||
return Mono.from(result)
|
||||
.map(this::toResponseEntity)
|
||||
.onErrorMap(InvalidEndpointRequestException.class,
|
||||
(ex) -> new ResponseStatusException(HttpStatus.BAD_REQUEST, ex.getReason()))
|
||||
.defaultIfEmpty(new ResponseEntity<>(
|
||||
(httpMethod != HttpMethod.GET) ? HttpStatus.NO_CONTENT : HttpStatus.NOT_FOUND));
|
||||
}
|
||||
|
||||
private ResponseEntity<Object> toResponseEntity(Object response) {
|
||||
@@ -384,8 +389,9 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
|
||||
}
|
||||
MediaType contentType = (webEndpointResponse.getContentType() != null)
|
||||
? new MediaType(webEndpointResponse.getContentType()) : null;
|
||||
return ResponseEntity.status(webEndpointResponse.getStatus()).contentType(contentType)
|
||||
.body(webEndpointResponse.getBody());
|
||||
return ResponseEntity.status(webEndpointResponse.getStatus())
|
||||
.contentType(contentType)
|
||||
.body(webEndpointResponse.getBody());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -485,8 +491,9 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
|
||||
@Override
|
||||
public boolean isUserInRole(String role) {
|
||||
String authority = (!role.startsWith(ROLE_PREFIX)) ? ROLE_PREFIX + role : role;
|
||||
return AuthorityAuthorizationManager.hasAuthority(authority).check(this::getAuthentication, null)
|
||||
.isGranted();
|
||||
return AuthorityAuthorizationManager.hasAuthority(authority)
|
||||
.check(this::getAuthentication, null)
|
||||
.isGranted();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -92,7 +92,8 @@ public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMappi
|
||||
patterns = Collections.singleton(getPathPatternParser().parse(""));
|
||||
}
|
||||
String[] endpointMappedPatterns = patterns.stream()
|
||||
.map((pattern) -> getEndpointMappedPattern(endpoint, pattern)).toArray(String[]::new);
|
||||
.map((pattern) -> getEndpointMappedPattern(endpoint, pattern))
|
||||
.toArray(String[]::new);
|
||||
return mapping.mutate().paths(endpointMappedPatterns).build();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -86,8 +86,9 @@ public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandle
|
||||
@ResponseBody
|
||||
@Reflective
|
||||
public Map<String, Map<String, Link>> links(ServerWebExchange exchange) {
|
||||
String requestUri = UriComponentsBuilder.fromUri(exchange.getRequest().getURI()).replaceQuery(null)
|
||||
.toUriString();
|
||||
String requestUri = UriComponentsBuilder.fromUri(exchange.getRequest().getURI())
|
||||
.replaceQuery(null)
|
||||
.toUriString();
|
||||
Map<String, Link> links = WebFluxEndpointHandlerMapping.this.linksResolver.resolveLinks(requestUri);
|
||||
return OperationResponseBody.of(Collections.singletonMap("_links", links));
|
||||
}
|
||||
|
||||
@@ -196,18 +196,22 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin
|
||||
}
|
||||
|
||||
private RequestMappingInfo createRequestMappingInfo(WebOperationRequestPredicate predicate, String path) {
|
||||
return RequestMappingInfo.paths(this.endpointMapping.createSubPath(path)).options(this.builderConfig)
|
||||
.methods(RequestMethod.valueOf(predicate.getHttpMethod().name()))
|
||||
.consumes(predicate.getConsumes().toArray(new String[0]))
|
||||
.produces(predicate.getProduces().toArray(new String[0])).build();
|
||||
return RequestMappingInfo.paths(this.endpointMapping.createSubPath(path))
|
||||
.options(this.builderConfig)
|
||||
.methods(RequestMethod.valueOf(predicate.getHttpMethod().name()))
|
||||
.consumes(predicate.getConsumes().toArray(new String[0]))
|
||||
.produces(predicate.getProduces().toArray(new String[0]))
|
||||
.build();
|
||||
}
|
||||
|
||||
private void registerLinksMapping() {
|
||||
String path = this.endpointMapping.getPath();
|
||||
String linksPath = (StringUtils.hasLength(path)) ? this.endpointMapping.createSubPath("/") : "/";
|
||||
RequestMappingInfo mapping = RequestMappingInfo.paths(linksPath).methods(RequestMethod.GET)
|
||||
.produces(this.endpointMediaTypes.getProduced().toArray(new String[0])).options(this.builderConfig)
|
||||
.build();
|
||||
RequestMappingInfo mapping = RequestMappingInfo.paths(linksPath)
|
||||
.methods(RequestMethod.GET)
|
||||
.produces(this.endpointMediaTypes.getProduced().toArray(new String[0]))
|
||||
.options(this.builderConfig)
|
||||
.build();
|
||||
LinksHandler linksHandler = getLinksHandler();
|
||||
registerMapping(mapping, linksHandler, ReflectionUtils.findMethod(linksHandler.getClass(), "links",
|
||||
HttpServletRequest.class, HttpServletResponse.class));
|
||||
@@ -306,12 +310,12 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin
|
||||
ProducibleOperationArgumentResolver producibleOperationArgumentResolver = new ProducibleOperationArgumentResolver(
|
||||
() -> headers.get("Accept"));
|
||||
OperationArgumentResolver serverNamespaceArgumentResolver = OperationArgumentResolver
|
||||
.of(WebServerNamespace.class, () -> {
|
||||
WebApplicationContext applicationContext = WebApplicationContextUtils
|
||||
.getRequiredWebApplicationContext(request.getServletContext());
|
||||
return WebServerNamespace
|
||||
.from(WebServerApplicationContext.getServerNamespace(applicationContext));
|
||||
});
|
||||
.of(WebServerNamespace.class, () -> {
|
||||
WebApplicationContext applicationContext = WebApplicationContextUtils
|
||||
.getRequiredWebApplicationContext(request.getServletContext());
|
||||
return WebServerNamespace
|
||||
.from(WebServerApplicationContext.getServerNamespace(applicationContext));
|
||||
});
|
||||
InvocationContext invocationContext = new InvocationContext(securityContext, arguments,
|
||||
serverNamespaceArgumentResolver, producibleOperationArgumentResolver);
|
||||
return handleResult(this.operation.invoke(invocationContext), HttpMethod.valueOf(request.getMethod()));
|
||||
@@ -329,15 +333,16 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin
|
||||
private Map<String, Object> getArguments(HttpServletRequest request, Map<String, String> body) {
|
||||
Map<String, Object> arguments = new LinkedHashMap<>(getTemplateVariables(request));
|
||||
String matchAllRemainingPathSegmentsVariable = this.operation.getRequestPredicate()
|
||||
.getMatchAllRemainingPathSegmentsVariable();
|
||||
.getMatchAllRemainingPathSegmentsVariable();
|
||||
if (matchAllRemainingPathSegmentsVariable != null) {
|
||||
arguments.put(matchAllRemainingPathSegmentsVariable, getRemainingPathSegments(request));
|
||||
}
|
||||
if (body != null && HttpMethod.POST.name().equals(request.getMethod())) {
|
||||
arguments.putAll(body);
|
||||
}
|
||||
request.getParameterMap().forEach(
|
||||
(name, values) -> arguments.put(name, (values.length != 1) ? Arrays.asList(values) : values[0]));
|
||||
request.getParameterMap()
|
||||
.forEach((name, values) -> arguments.put(name,
|
||||
(values.length != 1) ? Arrays.asList(values) : values[0]));
|
||||
return arguments;
|
||||
}
|
||||
|
||||
@@ -380,8 +385,9 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin
|
||||
}
|
||||
MediaType contentType = (response.getContentType() != null) ? new MediaType(response.getContentType())
|
||||
: null;
|
||||
return ResponseEntity.status(response.getStatus()).contentType(contentType)
|
||||
.body(convertIfNecessary(response.getBody()));
|
||||
return ResponseEntity.status(response.getStatus())
|
||||
.contentType(contentType)
|
||||
.body(convertIfNecessary(response.getBody()));
|
||||
}
|
||||
|
||||
private Object convertIfNecessary(Object body) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -93,7 +93,8 @@ public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMappi
|
||||
patterns = Collections.singleton(getPatternParser().parse(""));
|
||||
}
|
||||
String[] endpointMappedPatterns = patterns.stream()
|
||||
.map((pattern) -> getEndpointMappedPattern(endpoint, pattern)).toArray(String[]::new);
|
||||
.map((pattern) -> getEndpointMappedPattern(endpoint, pattern))
|
||||
.toArray(String[]::new);
|
||||
return mapping.mutate().paths(endpointMappedPatterns).build();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,7 @@ final class SkipPathExtensionContentNegotiation implements HandlerInterceptor {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static final String SKIP_ATTRIBUTE = org.springframework.web.accept.PathExtensionContentNegotiationStrategy.class
|
||||
.getName() + ".SKIP";
|
||||
.getName() + ".SKIP";
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -86,7 +86,7 @@ public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerM
|
||||
@Reflective
|
||||
public Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
|
||||
Map<String, Link> links = WebMvcEndpointHandlerMapping.this.linksResolver
|
||||
.resolveLinks(request.getRequestURL().toString());
|
||||
.resolveLinks(request.getRequestURL().toString());
|
||||
return OperationResponseBody.of(Collections.singletonMap("_links", links));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -144,8 +144,9 @@ public class EnvironmentEndpoint {
|
||||
private PropertySourceDescriptor describeSource(String sourceName, EnumerablePropertySource<?> source,
|
||||
Predicate<String> namePredicate, boolean showUnsanitized) {
|
||||
Map<String, PropertyValueDescriptor> properties = new LinkedHashMap<>();
|
||||
Stream.of(source.getPropertyNames()).filter(namePredicate)
|
||||
.forEach((name) -> properties.put(name, describeValueOf(name, source, showUnsanitized)));
|
||||
Stream.of(source.getPropertyNames())
|
||||
.filter(namePredicate)
|
||||
.forEach((name) -> properties.put(name, describeValueOf(name, source, showUnsanitized)));
|
||||
return new PropertySourceDescriptor(sourceName, properties);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -58,7 +58,7 @@ public class FlywayEndpoint {
|
||||
while (target != null) {
|
||||
Map<String, FlywayDescriptor> flywayBeans = new HashMap<>();
|
||||
target.getBeansOfType(Flyway.class)
|
||||
.forEach((name, flyway) -> flywayBeans.put(name, new FlywayDescriptor(flyway.info().all())));
|
||||
.forEach((name, flyway) -> flywayBeans.put(name, new FlywayDescriptor(flyway.info().all())));
|
||||
ApplicationContext parent = target.getParent();
|
||||
contextFlywayBeans.put(target.getId(),
|
||||
new ContextFlywayBeansDescriptor(flywayBeans, (parent != null) ? parent.getId() : null));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -78,9 +78,10 @@ public interface HealthEndpointGroups {
|
||||
default Set<HealthEndpointGroup> getAllWithAdditionalPath(WebServerNamespace namespace) {
|
||||
Assert.notNull(namespace, "Namespace must not be null");
|
||||
Set<HealthEndpointGroup> filteredGroups = new LinkedHashSet<>();
|
||||
getNames().stream().map(this::get).filter(
|
||||
(group) -> group.getAdditionalPath() != null && group.getAdditionalPath().hasNamespace(namespace))
|
||||
.forEach(filteredGroups::add);
|
||||
getNames().stream()
|
||||
.map(this::get)
|
||||
.filter((group) -> group.getAdditionalPath() != null && group.getAdditionalPath().hasNamespace(namespace))
|
||||
.forEach(filteredGroups::add);
|
||||
return filteredGroups;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -193,7 +193,7 @@ abstract class HealthEndpointSupport<C, T> {
|
||||
protected final CompositeHealth getCompositeHealth(ApiVersion apiVersion, Map<String, HealthComponent> components,
|
||||
StatusAggregator statusAggregator, boolean showComponents, Set<String> groupNames) {
|
||||
Status status = statusAggregator
|
||||
.getAggregateStatus(components.values().stream().map(this::getStatus).collect(Collectors.toSet()));
|
||||
.getAggregateStatus(components.values().stream().map(this::getStatus).collect(Collectors.toSet()));
|
||||
Map<String, HealthComponent> instances = showComponents ? components : null;
|
||||
if (groupNames != null) {
|
||||
return new SystemHealth(apiVersion, status, instances, groupNames);
|
||||
|
||||
@@ -43,8 +43,10 @@ abstract class NamedContributorsMapAdapter<V, C> implements NamedContributors<C>
|
||||
Assert.notNull(map, "Map must not be null");
|
||||
Assert.notNull(valueAdapter, "ValueAdapter must not be null");
|
||||
map.keySet().forEach(this::validateKey);
|
||||
this.map = Collections.unmodifiableMap(map.entrySet().stream().collect(LinkedHashMap::new,
|
||||
(result, entry) -> result.put(entry.getKey(), adapt(entry.getValue(), valueAdapter)), Map::putAll));
|
||||
this.map = Collections.unmodifiableMap(map.entrySet()
|
||||
.stream()
|
||||
.collect(LinkedHashMap::new,
|
||||
(result, entry) -> result.put(entry.getKey(), adapt(entry.getValue(), valueAdapter)), Map::putAll));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -101,9 +101,11 @@ public class ReactiveHealthEndpointWebExtension
|
||||
protected Mono<? extends HealthComponent> aggregateContributions(ApiVersion apiVersion,
|
||||
Map<String, Mono<? extends HealthComponent>> contributions, StatusAggregator statusAggregator,
|
||||
boolean showComponents, Set<String> groupNames) {
|
||||
return Flux.fromIterable(contributions.entrySet()).flatMap(NamedHealthComponent::create)
|
||||
.collectMap(NamedHealthComponent::getName, NamedHealthComponent::getHealth).map((components) -> this
|
||||
.getCompositeHealth(apiVersion, components, statusAggregator, showComponents, groupNames));
|
||||
return Flux.fromIterable(contributions.entrySet())
|
||||
.flatMap(NamedHealthComponent::create)
|
||||
.collectMap(NamedHealthComponent::getName, NamedHealthComponent::getHealth)
|
||||
.map((components) -> this.getCompositeHealth(apiVersion, components, statusAggregator, showComponents,
|
||||
groupNames));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -91,7 +91,7 @@ public abstract class InfoPropertiesInfoContributor<T extends InfoProperties> im
|
||||
*/
|
||||
protected Map<String, Object> extractContent(PropertySource<?> propertySource) {
|
||||
return new Binder(ConfigurationPropertySources.from(propertySource)).bind("", STRING_OBJECT_MAP)
|
||||
.orElseGet(LinkedHashMap::new);
|
||||
.orElseGet(LinkedHashMap::new);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -69,7 +69,7 @@ public class JmsHealthIndicator extends AbstractHealthIndicator {
|
||||
try {
|
||||
if (!this.latch.await(5, TimeUnit.SECONDS)) {
|
||||
JmsHealthIndicator.this.logger
|
||||
.warn("Connection failed to start within 5 seconds and will be closed.");
|
||||
.warn("Connection failed to start within 5 seconds and will be closed.");
|
||||
closeConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -63,7 +63,7 @@ public class LiquibaseEndpoint {
|
||||
Map<String, LiquibaseBeanDescriptor> liquibaseBeans = new HashMap<>();
|
||||
DatabaseFactory factory = DatabaseFactory.getInstance();
|
||||
target.getBeansOfType(SpringLiquibase.class)
|
||||
.forEach((name, liquibase) -> liquibaseBeans.put(name, createReport(liquibase, factory)));
|
||||
.forEach((name, liquibase) -> liquibaseBeans.put(name, createReport(liquibase, factory)));
|
||||
ApplicationContext parent = target.getParent();
|
||||
contextBeans.put(target.getId(),
|
||||
new ContextLiquibaseBeansDescriptor(liquibaseBeans, (parent != null) ? parent.getId() : null));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -154,9 +154,9 @@ public class HeapDumpWebEndpoint {
|
||||
protected HotSpotDiagnosticMXBeanHeapDumper() {
|
||||
try {
|
||||
Class<?> diagnosticMXBeanClass = ClassUtils
|
||||
.resolveClassName("com.sun.management.HotSpotDiagnosticMXBean", null);
|
||||
.resolveClassName("com.sun.management.HotSpotDiagnosticMXBean", null);
|
||||
this.diagnosticMXBean = ManagementFactory
|
||||
.getPlatformMXBean((Class<PlatformManagedObject>) diagnosticMXBeanClass);
|
||||
.getPlatformMXBean((Class<PlatformManagedObject>) diagnosticMXBeanClass);
|
||||
this.dumpHeapMethod = ReflectionUtils.findMethod(diagnosticMXBeanClass, "dumpHeap", String.class,
|
||||
Boolean.TYPE);
|
||||
}
|
||||
@@ -285,7 +285,7 @@ public class HeapDumpWebEndpoint {
|
||||
}
|
||||
catch (IOException ex) {
|
||||
TemporaryFileSystemResource.this.logger
|
||||
.warn("Failed to delete temporary heap dump file '" + getFile() + "'", ex);
|
||||
.warn("Failed to delete temporary heap dump file '" + getFile() + "'", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -114,8 +114,12 @@ public class MetricsEndpoint {
|
||||
|
||||
private Collection<Meter> findFirstMatchingMeters(CompositeMeterRegistry composite, String name,
|
||||
Iterable<Tag> tags) {
|
||||
return composite.getRegistries().stream().map((registry) -> findFirstMatchingMeters(registry, name, tags))
|
||||
.filter((matching) -> !matching.isEmpty()).findFirst().orElse(Collections.emptyList());
|
||||
return composite.getRegistries()
|
||||
.stream()
|
||||
.map((registry) -> findFirstMatchingMeters(registry, name, tags))
|
||||
.filter((matching) -> !matching.isEmpty())
|
||||
.findFirst()
|
||||
.orElse(Collections.emptyList());
|
||||
}
|
||||
|
||||
private Map<Statistic, Double> getSamples(Collection<Meter> meters) {
|
||||
@@ -125,8 +129,9 @@ public class MetricsEndpoint {
|
||||
}
|
||||
|
||||
private void mergeMeasurements(Map<Statistic, Double> samples, Meter meter) {
|
||||
meter.measure().forEach((measurement) -> samples.merge(measurement.getStatistic(), measurement.getValue(),
|
||||
mergeFunction(measurement.getStatistic())));
|
||||
meter.measure()
|
||||
.forEach((measurement) -> samples.merge(measurement.getStatistic(), measurement.getValue(),
|
||||
mergeFunction(measurement.getStatistic())));
|
||||
}
|
||||
|
||||
private BiFunction<Double, Double, Double> mergeFunction(Statistic statistic) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -72,9 +72,11 @@ public class CacheMetricsRegistrar {
|
||||
private MeterBinder getMeterBinder(Cache cache, Tags tags) {
|
||||
Tags cacheTags = tags.and(getAdditionalTags(cache));
|
||||
return LambdaSafe.callbacks(CacheMeterBinderProvider.class, this.binderProviders, cache)
|
||||
.withLogger(CacheMetricsRegistrar.class)
|
||||
.invokeAnd((binderProvider) -> binderProvider.getMeterBinder(cache, cacheTags)).filter(Objects::nonNull)
|
||||
.findFirst().orElse(null);
|
||||
.withLogger(CacheMetricsRegistrar.class)
|
||||
.invokeAnd((binderProvider) -> binderProvider.getMeterBinder(cache, cacheTags))
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -56,8 +56,8 @@ public class HazelcastCacheMeterBinderProvider implements CacheMeterBinderProvid
|
||||
try {
|
||||
Method nativeCacheAccessor = ReflectionUtils.findMethod(HazelcastCache.class, "getNativeCache");
|
||||
Object nativeCache = ReflectionUtils.invokeMethod(nativeCacheAccessor, cache);
|
||||
return HazelcastCacheMetrics.class.getConstructor(Object.class, Iterable.class).newInstance(nativeCache,
|
||||
tags);
|
||||
return HazelcastCacheMetrics.class.getConstructor(Object.class, Iterable.class)
|
||||
.newInstance(nativeCache, tags);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Failed to create MeterBinder for Hazelcast", ex);
|
||||
@@ -72,8 +72,9 @@ public class HazelcastCacheMeterBinderProvider implements CacheMeterBinderProvid
|
||||
Method getNativeCacheMethod = ReflectionUtils.findMethod(HazelcastCache.class, "getNativeCache");
|
||||
Assert.state(getNativeCacheMethod != null, "Unable to find 'getNativeCache' method");
|
||||
Constructor<?> constructor = HazelcastCacheMetrics.class.getConstructor(Object.class, Iterable.class);
|
||||
hints.reflection().registerMethod(getNativeCacheMethod, ExecutableMode.INVOKE)
|
||||
.registerConstructor(constructor, ExecutableMode.INVOKE);
|
||||
hints.reflection()
|
||||
.registerMethod(getNativeCacheMethod, ExecutableMode.INVOKE)
|
||||
.registerConstructor(constructor, ExecutableMode.INVOKE);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -69,15 +69,20 @@ public class RedisCacheMetrics extends CacheMeterBinder<RedisCache> {
|
||||
@Override
|
||||
protected void bindImplementationSpecificMetrics(MeterRegistry registry) {
|
||||
FunctionCounter.builder("cache.removals", this.cache, (cache) -> cache.getStatistics().getDeletes())
|
||||
.tags(getTagsWithCacheName()).description("Cache removals").register(registry);
|
||||
.tags(getTagsWithCacheName())
|
||||
.description("Cache removals")
|
||||
.register(registry);
|
||||
FunctionCounter.builder("cache.gets", this.cache, (cache) -> cache.getStatistics().getPending())
|
||||
.tags(getTagsWithCacheName()).tag("result", "pending").description("The number of pending requests")
|
||||
.register(registry);
|
||||
.tags(getTagsWithCacheName())
|
||||
.tag("result", "pending")
|
||||
.description("The number of pending requests")
|
||||
.register(registry);
|
||||
TimeGauge
|
||||
.builder("cache.lock.duration", this.cache, TimeUnit.NANOSECONDS,
|
||||
(cache) -> cache.getStatistics().getLockWaitDuration(TimeUnit.NANOSECONDS))
|
||||
.tags(getTagsWithCacheName()).description("The time the cache has spent waiting on a lock")
|
||||
.register(registry);
|
||||
.builder("cache.lock.duration", this.cache, TimeUnit.NANOSECONDS,
|
||||
(cache) -> cache.getStatistics().getLockWaitDuration(TimeUnit.NANOSECONDS))
|
||||
.tags(getTagsWithCacheName())
|
||||
.description("The time the cache has spent waiting on a lock")
|
||||
.register(registry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -69,8 +69,10 @@ public class MetricsRepositoryMethodInvocationListener implements RepositoryMeth
|
||||
Iterable<Tag> tags = this.tagsProvider.repositoryTags(invocation);
|
||||
long duration = invocation.getDuration(TimeUnit.NANOSECONDS);
|
||||
AutoTimer.apply(this.autoTimer, this.metricName, annotations,
|
||||
(builder) -> builder.description("Duration of repository invocations").tags(tags)
|
||||
.register(this.registrySupplier.get()).record(duration, TimeUnit.NANOSECONDS));
|
||||
(builder) -> builder.description("Duration of repository invocations")
|
||||
.tags(tags)
|
||||
.register(this.registrySupplier.get())
|
||||
.record(duration, TimeUnit.NANOSECONDS));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -88,7 +88,9 @@ public class DataSourcePoolMetrics implements MeterBinder {
|
||||
Function<DataSource, N> function) {
|
||||
if (function.apply(this.dataSource) != null) {
|
||||
Gauge.builder("jdbc.connections." + metricName, this.dataSource, (m) -> function.apply(m).doubleValue())
|
||||
.tags(this.tags).description(description).register(registry);
|
||||
.tags(this.tags)
|
||||
.description(description)
|
||||
.register(registry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,22 +50,21 @@ public class ConnectionPoolMetrics implements MeterBinder {
|
||||
this.pool.getMetrics().ifPresent((poolMetrics) -> {
|
||||
bindConnectionPoolMetric(registry,
|
||||
Gauge.builder(metricKey("acquired"), poolMetrics, PoolMetrics::acquiredSize)
|
||||
.description("Size of successfully acquired connections which are in active use."));
|
||||
.description("Size of successfully acquired connections which are in active use."));
|
||||
bindConnectionPoolMetric(registry,
|
||||
Gauge.builder(metricKey("allocated"), poolMetrics, PoolMetrics::allocatedSize)
|
||||
.description("Size of allocated connections in the pool which are in active use or idle."));
|
||||
.description("Size of allocated connections in the pool which are in active use or idle."));
|
||||
bindConnectionPoolMetric(registry, Gauge.builder(metricKey("idle"), poolMetrics, PoolMetrics::idleSize)
|
||||
.description("Size of idle connections in the pool."));
|
||||
.description("Size of idle connections in the pool."));
|
||||
bindConnectionPoolMetric(registry,
|
||||
Gauge.builder(metricKey("pending"), poolMetrics, PoolMetrics::pendingAcquireSize).description(
|
||||
"Size of pending to acquire connections from the underlying connection factory."));
|
||||
Gauge.builder(metricKey("pending"), poolMetrics, PoolMetrics::pendingAcquireSize)
|
||||
.description("Size of pending to acquire connections from the underlying connection factory."));
|
||||
bindConnectionPoolMetric(registry,
|
||||
Gauge.builder(metricKey("max.allocated"), poolMetrics, PoolMetrics::getMaxAllocatedSize)
|
||||
.description("Maximum size of allocated connections that this pool allows."));
|
||||
.description("Maximum size of allocated connections that this pool allows."));
|
||||
bindConnectionPoolMetric(registry,
|
||||
Gauge.builder(metricKey("max.pending"), poolMetrics, PoolMetrics::getMaxPendingAcquireSize)
|
||||
.description(
|
||||
"Maximum size of pending state to acquire connections that this pool allows."));
|
||||
.description("Maximum size of pending state to acquire connections that this pool allows."));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -116,8 +116,10 @@ public class StartupTimeMetricsListener implements SmartApplicationListener {
|
||||
SpringApplication springApplication) {
|
||||
if (timeTaken != null) {
|
||||
Iterable<Tag> tags = createTagsFrom(springApplication);
|
||||
TimeGauge.builder(name, timeTaken::toMillis, TimeUnit.MILLISECONDS).tags(tags).description(description)
|
||||
.register(this.meterRegistry);
|
||||
TimeGauge.builder(name, timeTaken::toMillis, TimeUnit.MILLISECONDS)
|
||||
.tags(tags)
|
||||
.description(description)
|
||||
.register(this.meterRegistry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,7 +50,7 @@ public class ObservationWebClientCustomizer implements WebClientCustomizer {
|
||||
@Override
|
||||
public void customize(WebClient.Builder webClientBuilder) {
|
||||
webClientBuilder.observationRegistry(this.observationRegistry)
|
||||
.observationConvention(this.observationConvention);
|
||||
.observationConvention(this.observationConvention);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,8 +38,9 @@ class Neo4jHealthDetailsHandler {
|
||||
void addHealthDetails(Builder builder, Neo4jHealthDetails healthDetails) {
|
||||
ResultSummary summary = healthDetails.getSummary();
|
||||
ServerInfo serverInfo = summary.server();
|
||||
builder.up().withDetail("server", healthDetails.getVersion() + "@" + serverInfo.address()).withDetail("edition",
|
||||
healthDetails.getEdition());
|
||||
builder.up()
|
||||
.withDetail("server", healthDetails.getVersion() + "@" + serverInfo.address())
|
||||
.withDetail("edition", healthDetails.getEdition());
|
||||
DatabaseInfo databaseInfo = summary.database();
|
||||
if (StringUtils.hasText(databaseInfo.name())) {
|
||||
builder.withDetail("database", databaseInfo.name());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,8 +57,9 @@ public class Neo4jHealthIndicator extends AbstractHealthIndicator {
|
||||
/**
|
||||
* The default session config to use while connecting.
|
||||
*/
|
||||
static final SessionConfig DEFAULT_SESSION_CONFIG = SessionConfig.builder().withDefaultAccessMode(AccessMode.WRITE)
|
||||
.build();
|
||||
static final SessionConfig DEFAULT_SESSION_CONFIG = SessionConfig.builder()
|
||||
.withDefaultAccessMode(AccessMode.WRITE)
|
||||
.build();
|
||||
|
||||
private final Driver driver;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,12 +57,12 @@ public final class Neo4jReactiveHealthIndicator extends AbstractReactiveHealthIn
|
||||
@Override
|
||||
protected Mono<Health> doHealthCheck(Health.Builder builder) {
|
||||
return runHealthCheckQuery()
|
||||
.doOnError(SessionExpiredException.class,
|
||||
(ex) -> logger.warn(Neo4jHealthIndicator.MESSAGE_SESSION_EXPIRED))
|
||||
.retryWhen(Retry.max(1).filter(SessionExpiredException.class::isInstance)).map((healthDetails) -> {
|
||||
this.healthDetailsHandler.addHealthDetails(builder, healthDetails);
|
||||
return builder.build();
|
||||
});
|
||||
.doOnError(SessionExpiredException.class, (ex) -> logger.warn(Neo4jHealthIndicator.MESSAGE_SESSION_EXPIRED))
|
||||
.retryWhen(Retry.max(1).filter(SessionExpiredException.class::isInstance))
|
||||
.map((healthDetails) -> {
|
||||
this.healthDetailsHandler.addHealthDetails(builder, healthDetails);
|
||||
return builder.build();
|
||||
});
|
||||
}
|
||||
|
||||
Mono<Neo4jHealthDetails> runHealthCheckQuery() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -66,8 +66,8 @@ import org.springframework.util.Assert;
|
||||
public class QuartzEndpoint {
|
||||
|
||||
private static final Comparator<Trigger> TRIGGER_COMPARATOR = Comparator
|
||||
.comparing(Trigger::getNextFireTime, Comparator.nullsLast(Comparator.naturalOrder()))
|
||||
.thenComparing(Comparator.comparingInt(Trigger::getPriority).reversed());
|
||||
.comparing(Trigger::getNextFireTime, Comparator.nullsLast(Comparator.naturalOrder()))
|
||||
.thenComparing(Comparator.comparingInt(Trigger::getPriority).reversed());
|
||||
|
||||
private final Scheduler scheduler;
|
||||
|
||||
@@ -98,8 +98,10 @@ public class QuartzEndpoint {
|
||||
public QuartzGroupsDescriptor quartzJobGroups() throws SchedulerException {
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
for (String groupName : this.scheduler.getJobGroupNames()) {
|
||||
List<String> jobs = this.scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName)).stream()
|
||||
.map((key) -> key.getName()).toList();
|
||||
List<String> jobs = this.scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))
|
||||
.stream()
|
||||
.map((key) -> key.getName())
|
||||
.toList();
|
||||
result.put(groupName, Collections.singletonMap("jobs", jobs));
|
||||
}
|
||||
return new QuartzGroupsDescriptor(result);
|
||||
@@ -116,8 +118,11 @@ public class QuartzEndpoint {
|
||||
for (String groupName : this.scheduler.getTriggerGroupNames()) {
|
||||
Map<String, Object> groupDetails = new LinkedHashMap<>();
|
||||
groupDetails.put("paused", pausedTriggerGroups.contains(groupName));
|
||||
groupDetails.put("triggers", this.scheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(groupName))
|
||||
.stream().map((key) -> key.getName()).toList());
|
||||
groupDetails.put("triggers",
|
||||
this.scheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(groupName))
|
||||
.stream()
|
||||
.map((key) -> key.getName())
|
||||
.toList());
|
||||
result.put(groupName, groupDetails);
|
||||
}
|
||||
return new QuartzGroupsDescriptor(result);
|
||||
@@ -570,9 +575,12 @@ public class QuartzEndpoint {
|
||||
private final TriggerType type;
|
||||
|
||||
private static TriggerDescriptor of(Trigger trigger) {
|
||||
return DESCRIBERS.entrySet().stream().filter((entry) -> entry.getKey().isInstance(trigger))
|
||||
.map((entry) -> entry.getValue().apply(trigger)).findFirst()
|
||||
.orElse(new CustomTriggerDescriptor(trigger));
|
||||
return DESCRIBERS.entrySet()
|
||||
.stream()
|
||||
.filter((entry) -> entry.getKey().isInstance(trigger))
|
||||
.map((entry) -> entry.getValue().apply(trigger))
|
||||
.findFirst()
|
||||
.orElse(new CustomTriggerDescriptor(trigger));
|
||||
}
|
||||
|
||||
protected TriggerDescriptor(Trigger trigger, TriggerType type) {
|
||||
@@ -721,7 +729,7 @@ public class QuartzEndpoint {
|
||||
protected void appendSummary(Map<String, Object> content) {
|
||||
content.put("interval",
|
||||
getIntervalDuration(this.trigger.getRepeatInterval(), this.trigger.getRepeatIntervalUnit())
|
||||
.toMillis());
|
||||
.toMillis());
|
||||
putIfNoNull(content, "daysOfWeek", this.trigger.getDaysOfWeek());
|
||||
putIfNoNull(content, "startTimeOfDay", getLocalTime(this.trigger.getStartTimeOfDay()));
|
||||
putIfNoNull(content, "endTimeOfDay", getLocalTime(this.trigger.getEndTimeOfDay()));
|
||||
@@ -752,7 +760,7 @@ public class QuartzEndpoint {
|
||||
protected void appendSummary(Map<String, Object> content) {
|
||||
content.put("interval",
|
||||
getIntervalDuration(this.trigger.getRepeatInterval(), this.trigger.getRepeatIntervalUnit())
|
||||
.toMillis());
|
||||
.toMillis());
|
||||
putIfNoNull(content, "timeZone", this.trigger.getTimeZone());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -70,8 +70,8 @@ public class ConnectionFactoryHealthIndicator extends AbstractReactiveHealthIndi
|
||||
|
||||
@Override
|
||||
protected final Mono<Health> doHealthCheck(Builder builder) {
|
||||
return validate(builder).defaultIfEmpty(builder.build()).onErrorResume(Exception.class,
|
||||
(ex) -> Mono.just(builder.down(ex).build()));
|
||||
return validate(builder).defaultIfEmpty(builder.build())
|
||||
.onErrorResume(Exception.class, (ex) -> Mono.just(builder.down(ex).build()));
|
||||
}
|
||||
|
||||
private Mono<Health> validate(Builder builder) {
|
||||
@@ -84,7 +84,8 @@ public class ConnectionFactoryHealthIndicator extends AbstractReactiveHealthIndi
|
||||
builder.withDetail("validationQuery", this.validationQuery);
|
||||
Mono<Object> connectionValidation = Mono.usingWhen(this.connectionFactory.create(),
|
||||
(conn) -> Flux.from(conn.createStatement(this.validationQuery).execute())
|
||||
.flatMap((it) -> it.map(this::extractResult)).next(),
|
||||
.flatMap((it) -> it.map(this::extractResult))
|
||||
.next(),
|
||||
Connection::close, (o, throwable) -> o.close(), Connection::close);
|
||||
return connectionValidation.map((result) -> builder.up().withDetail("result", result).build());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -67,9 +67,11 @@ public class ScheduledTasksEndpoint {
|
||||
@ReadOperation
|
||||
public ScheduledTasksDescriptor scheduledTasks() {
|
||||
Map<TaskType, List<TaskDescriptor>> descriptionsByType = this.scheduledTaskHolders.stream()
|
||||
.flatMap((holder) -> holder.getScheduledTasks().stream()).map(ScheduledTask::getTask)
|
||||
.map(TaskDescriptor::of).filter(Objects::nonNull)
|
||||
.collect(Collectors.groupingBy(TaskDescriptor::getType));
|
||||
.flatMap((holder) -> holder.getScheduledTasks().stream())
|
||||
.map(ScheduledTask::getTask)
|
||||
.map(TaskDescriptor::of)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.groupingBy(TaskDescriptor::getType));
|
||||
return new ScheduledTasksDescriptor(descriptionsByType);
|
||||
}
|
||||
|
||||
@@ -130,8 +132,12 @@ public class ScheduledTasksEndpoint {
|
||||
private final RunnableDescriptor runnable;
|
||||
|
||||
private static TaskDescriptor of(Task task) {
|
||||
return DESCRIBERS.entrySet().stream().filter((entry) -> entry.getKey().isInstance(task))
|
||||
.map((entry) -> entry.getValue().apply(task)).findFirst().orElse(null);
|
||||
return DESCRIBERS.entrySet()
|
||||
.stream()
|
||||
.filter((entry) -> entry.getKey().isInstance(task))
|
||||
.map((entry) -> entry.getValue().apply(task))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private static TaskDescriptor describeTriggerTask(TriggerTask triggerTask) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -93,23 +93,25 @@ public class StartupEndpoint {
|
||||
static class StartupEndpointRuntimeHints implements RuntimeHintsRegistrar {
|
||||
|
||||
private static final TypeReference DEFAULT_TAG = TypeReference
|
||||
.of("org.springframework.boot.context.metrics.buffering.BufferedStartupStep$DefaultTag");
|
||||
.of("org.springframework.boot.context.metrics.buffering.BufferedStartupStep$DefaultTag");
|
||||
|
||||
private static final TypeReference BUFFERED_STARTUP_STEP = TypeReference
|
||||
.of("org.springframework.boot.context.metrics.buffering.BufferedStartupStep");
|
||||
.of("org.springframework.boot.context.metrics.buffering.BufferedStartupStep");
|
||||
|
||||
private static final TypeReference FLIGHT_RECORDER_TAG = TypeReference
|
||||
.of("org.springframework.core.metrics.jfr.FlightRecorderStartupStep$FlightRecorderTag");
|
||||
.of("org.springframework.core.metrics.jfr.FlightRecorderStartupStep$FlightRecorderTag");
|
||||
|
||||
private static final TypeReference FLIGHT_RECORDER_STARTUP_STEP = TypeReference
|
||||
.of("org.springframework.core.metrics.jfr.FlightRecorderStartupStep");
|
||||
.of("org.springframework.core.metrics.jfr.FlightRecorderStartupStep");
|
||||
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
|
||||
hints.reflection().registerType(DEFAULT_TAG, (typeHint) -> typeHint.onReachableType(BUFFERED_STARTUP_STEP)
|
||||
hints.reflection()
|
||||
.registerType(DEFAULT_TAG, (typeHint) -> typeHint.onReachableType(BUFFERED_STARTUP_STEP)
|
||||
.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));
|
||||
hints.reflection()
|
||||
.registerType(FLIGHT_RECORDER_TAG, (typeHint) -> typeHint.onReachableType(FLIGHT_RECORDER_STARTUP_STEP)
|
||||
.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));
|
||||
hints.reflection().registerType(FLIGHT_RECORDER_TAG, (typeHint) -> typeHint
|
||||
.onReachableType(FLIGHT_RECORDER_STARTUP_STEP).withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -68,9 +68,11 @@ public class DiskSpaceHealthIndicator extends AbstractHealthIndicator {
|
||||
this.path.getAbsolutePath(), diskFreeInBytes, this.threshold));
|
||||
builder.down();
|
||||
}
|
||||
builder.withDetail("total", this.path.getTotalSpace()).withDetail("free", diskFreeInBytes)
|
||||
.withDetail("threshold", this.threshold.toBytes()).withDetail("path", this.path.getAbsolutePath())
|
||||
.withDetail("exists", this.path.exists());
|
||||
builder.withDetail("total", this.path.getTotalSpace())
|
||||
.withDetail("free", diskFreeInBytes)
|
||||
.withDetail("threshold", this.threshold.toBytes())
|
||||
.withDetail("path", this.path.getAbsolutePath())
|
||||
.withDetail("exists", this.path.exists());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -73,7 +73,7 @@ public class HttpExchangesWebFilter implements WebFilter, Ordered {
|
||||
Mono<?> principal = exchange.getPrincipal().cast(Object.class).defaultIfEmpty(NONE);
|
||||
Mono<Object> session = exchange.getSession().cast(Object.class).defaultIfEmpty(NONE);
|
||||
return Mono.zip(PrincipalAndSession::new, principal, session)
|
||||
.flatMap((principalAndSession) -> filter(exchange, chain, principalAndSession));
|
||||
.flatMap((principalAndSession) -> filter(exchange, chain, principalAndSession));
|
||||
}
|
||||
|
||||
private Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -61,8 +61,8 @@ import org.springframework.web.util.pattern.PathPattern;
|
||||
public class DispatcherHandlersMappingDescriptionProvider implements MappingDescriptionProvider {
|
||||
|
||||
private static final List<HandlerMappingDescriptionProvider<? extends HandlerMapping>> descriptionProviders = Arrays
|
||||
.asList(new RequestMappingInfoHandlerMappingDescriptionProvider(),
|
||||
new UrlHandlerMappingDescriptionProvider(), new RouterFunctionMappingDescriptionProvider());
|
||||
.asList(new RequestMappingInfoHandlerMappingDescriptionProvider(), new UrlHandlerMappingDescriptionProvider(),
|
||||
new RouterFunctionMappingDescriptionProvider());
|
||||
|
||||
@Override
|
||||
public String getMappingName() {
|
||||
@@ -73,7 +73,7 @@ public class DispatcherHandlersMappingDescriptionProvider implements MappingDesc
|
||||
public Map<String, List<DispatcherHandlerMappingDescription>> describeMappings(ApplicationContext context) {
|
||||
Map<String, List<DispatcherHandlerMappingDescription>> mappings = new HashMap<>();
|
||||
context.getBeansOfType(DispatcherHandler.class)
|
||||
.forEach((name, handler) -> mappings.put(name, describeMappings(handler)));
|
||||
.forEach((name, handler) -> mappings.put(name, describeMappings(handler)));
|
||||
return mappings;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -48,17 +48,32 @@ public class RequestMappingConditionsDescription {
|
||||
private final List<MediaTypeExpressionDescription> produces;
|
||||
|
||||
RequestMappingConditionsDescription(RequestMappingInfo requestMapping) {
|
||||
this.consumes = requestMapping.getConsumesCondition().getExpressions().stream()
|
||||
.map(MediaTypeExpressionDescription::new).toList();
|
||||
this.headers = requestMapping.getHeadersCondition().getExpressions().stream()
|
||||
.map(NameValueExpressionDescription::new).toList();
|
||||
this.consumes = requestMapping.getConsumesCondition()
|
||||
.getExpressions()
|
||||
.stream()
|
||||
.map(MediaTypeExpressionDescription::new)
|
||||
.toList();
|
||||
this.headers = requestMapping.getHeadersCondition()
|
||||
.getExpressions()
|
||||
.stream()
|
||||
.map(NameValueExpressionDescription::new)
|
||||
.toList();
|
||||
this.methods = requestMapping.getMethodsCondition().getMethods();
|
||||
this.params = requestMapping.getParamsCondition().getExpressions().stream()
|
||||
.map(NameValueExpressionDescription::new).toList();
|
||||
this.patterns = requestMapping.getPatternsCondition().getPatterns().stream().map(PathPattern::getPatternString)
|
||||
.collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet));
|
||||
this.produces = requestMapping.getProducesCondition().getExpressions().stream()
|
||||
.map(MediaTypeExpressionDescription::new).toList();
|
||||
this.params = requestMapping.getParamsCondition()
|
||||
.getExpressions()
|
||||
.stream()
|
||||
.map(NameValueExpressionDescription::new)
|
||||
.toList();
|
||||
this.patterns = requestMapping.getPatternsCondition()
|
||||
.getPatterns()
|
||||
.stream()
|
||||
.map(PathPattern::getPatternString)
|
||||
.collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet));
|
||||
this.produces = requestMapping.getProducesCondition()
|
||||
.getExpressions()
|
||||
.stream()
|
||||
.map(MediaTypeExpressionDescription::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
public List<MediaTypeExpressionDescription> getConsumes() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -95,8 +95,10 @@ final class DispatcherServletHandlerMappings {
|
||||
}
|
||||
|
||||
private Optional<Context> findContext() {
|
||||
return Stream.of(this.webServer.getTomcat().getHost().findChildren()).filter(Context.class::isInstance)
|
||||
.map(Context.class::cast).findFirst();
|
||||
return Stream.of(this.webServer.getTomcat().getHost().findChildren())
|
||||
.filter(Context.class::isInstance)
|
||||
.map(Context.class::cast)
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private void initializeServlet(Context context, String name) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -192,8 +192,8 @@ public class DispatcherServletsMappingDescriptionProvider implements MappingDesc
|
||||
public List<DispatcherServletMappingDescription> describe(Iterable handlerMapping) {
|
||||
List<DispatcherServletMappingDescription> descriptions = new ArrayList<>();
|
||||
for (Object delegate : handlerMapping) {
|
||||
descriptions.addAll(
|
||||
DispatcherServletsMappingDescriptionProvider.describe(delegate, this.descriptionProviders));
|
||||
descriptions
|
||||
.addAll(DispatcherServletsMappingDescriptionProvider.describe(delegate, this.descriptionProviders));
|
||||
}
|
||||
return descriptions;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,8 +44,12 @@ public class FiltersMappingDescriptionProvider implements MappingDescriptionProv
|
||||
@Override
|
||||
public List<FilterRegistrationMappingDescription> describeMappings(ApplicationContext context) {
|
||||
if (context instanceof WebApplicationContext webApplicationContext) {
|
||||
return webApplicationContext.getServletContext().getFilterRegistrations().values().stream()
|
||||
.map(FilterRegistrationMappingDescription::new).toList();
|
||||
return webApplicationContext.getServletContext()
|
||||
.getFilterRegistrations()
|
||||
.values()
|
||||
.stream()
|
||||
.map(FilterRegistrationMappingDescription::new)
|
||||
.toList();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,16 +46,28 @@ public class RequestMappingConditionsDescription {
|
||||
private final List<MediaTypeExpressionDescription> produces;
|
||||
|
||||
RequestMappingConditionsDescription(RequestMappingInfo requestMapping) {
|
||||
this.consumes = requestMapping.getConsumesCondition().getExpressions().stream()
|
||||
.map(MediaTypeExpressionDescription::new).toList();
|
||||
this.headers = requestMapping.getHeadersCondition().getExpressions().stream()
|
||||
.map(NameValueExpressionDescription::new).toList();
|
||||
this.consumes = requestMapping.getConsumesCondition()
|
||||
.getExpressions()
|
||||
.stream()
|
||||
.map(MediaTypeExpressionDescription::new)
|
||||
.toList();
|
||||
this.headers = requestMapping.getHeadersCondition()
|
||||
.getExpressions()
|
||||
.stream()
|
||||
.map(NameValueExpressionDescription::new)
|
||||
.toList();
|
||||
this.methods = requestMapping.getMethodsCondition().getMethods();
|
||||
this.params = requestMapping.getParamsCondition().getExpressions().stream()
|
||||
.map(NameValueExpressionDescription::new).toList();
|
||||
this.params = requestMapping.getParamsCondition()
|
||||
.getExpressions()
|
||||
.stream()
|
||||
.map(NameValueExpressionDescription::new)
|
||||
.toList();
|
||||
this.patterns = extractPathPatterns(requestMapping);
|
||||
this.produces = requestMapping.getProducesCondition().getExpressions().stream()
|
||||
.map(MediaTypeExpressionDescription::new).toList();
|
||||
this.produces = requestMapping.getProducesCondition()
|
||||
.getExpressions()
|
||||
.stream()
|
||||
.map(MediaTypeExpressionDescription::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
private Set<String> extractPathPatterns(RequestMappingInfo requestMapping) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,8 +44,12 @@ public class ServletsMappingDescriptionProvider implements MappingDescriptionPro
|
||||
@Override
|
||||
public List<ServletRegistrationMappingDescription> describeMappings(ApplicationContext context) {
|
||||
if (context instanceof WebApplicationContext webApplicationContext) {
|
||||
return webApplicationContext.getServletContext().getServletRegistrations().values().stream()
|
||||
.map(ServletRegistrationMappingDescription::new).toList();
|
||||
return webApplicationContext.getServletContext()
|
||||
.getServletRegistrations()
|
||||
.values()
|
||||
.stream()
|
||||
.map(ServletRegistrationMappingDescription::new)
|
||||
.toList();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -53,7 +53,7 @@ class RabbitHealthIndicatorTests {
|
||||
@Test
|
||||
void createWhenRabbitTemplateIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RabbitHealthIndicator(null))
|
||||
.withMessageContaining("RabbitTemplate must not be null");
|
||||
.withMessageContaining("RabbitTemplate must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -59,15 +59,15 @@ class AuditEventTests {
|
||||
@Test
|
||||
void nullTimestamp() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new AuditEvent(null, "phil", "UNKNOWN", Collections.singletonMap("a", "b")))
|
||||
.withMessageContaining("Timestamp must not be null");
|
||||
.isThrownBy(() -> new AuditEvent(null, "phil", "UNKNOWN", Collections.singletonMap("a", "b")))
|
||||
.withMessageContaining("Timestamp must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullType() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new AuditEvent("phil", null, Collections.singletonMap("a", "b")))
|
||||
.withMessageContaining("Type must not be null");
|
||||
.isThrownBy(() -> new AuditEvent("phil", null, Collections.singletonMap("a", "b")))
|
||||
.withMessageContaining("Type must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,32 +37,54 @@ class AuditEventsEndpointWebIntegrationTests {
|
||||
|
||||
@WebEndpointTest
|
||||
void allEvents(WebTestClient client) {
|
||||
client.get().uri((builder) -> builder.path("/actuator/auditevents").build()).exchange().expectStatus().isOk()
|
||||
.expectBody().jsonPath("events.[*].principal")
|
||||
.isEqualTo(new JSONArray().appendElement("admin").appendElement("admin").appendElement("user"));
|
||||
client.get()
|
||||
.uri((builder) -> builder.path("/actuator/auditevents").build())
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody()
|
||||
.jsonPath("events.[*].principal")
|
||||
.isEqualTo(new JSONArray().appendElement("admin").appendElement("admin").appendElement("user"));
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void eventsAfter(WebTestClient client) {
|
||||
client.get()
|
||||
.uri((builder) -> builder.path("/actuator/auditevents")
|
||||
.queryParam("after", "2016-11-01T13:00:00%2B00:00").build())
|
||||
.exchange().expectStatus().isOk().expectBody().jsonPath("events").isEmpty();
|
||||
.uri((builder) -> builder.path("/actuator/auditevents")
|
||||
.queryParam("after", "2016-11-01T13:00:00%2B00:00")
|
||||
.build())
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody()
|
||||
.jsonPath("events")
|
||||
.isEmpty();
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void eventsWithPrincipal(WebTestClient client) {
|
||||
client.get().uri((builder) -> builder.path("/actuator/auditevents").queryParam("principal", "user").build())
|
||||
.exchange().expectStatus().isOk().expectBody().jsonPath("events.[*].principal")
|
||||
.isEqualTo(new JSONArray().appendElement("user"));
|
||||
client.get()
|
||||
.uri((builder) -> builder.path("/actuator/auditevents").queryParam("principal", "user").build())
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody()
|
||||
.jsonPath("events.[*].principal")
|
||||
.isEqualTo(new JSONArray().appendElement("user"));
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void eventsWithType(WebTestClient client) {
|
||||
client.get().uri((builder) -> builder.path("/actuator/auditevents").queryParam("type", "logout").build())
|
||||
.exchange().expectStatus().isOk().expectBody().jsonPath("events.[*].principal")
|
||||
.isEqualTo(new JSONArray().appendElement("admin")).jsonPath("events.[*].type")
|
||||
.isEqualTo(new JSONArray().appendElement("logout"));
|
||||
client.get()
|
||||
.uri((builder) -> builder.path("/actuator/auditevents").queryParam("type", "logout").build())
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody()
|
||||
.jsonPath("events.[*].principal")
|
||||
.isEqualTo(new JSONArray().appendElement("admin"))
|
||||
.jsonPath("events.[*].type")
|
||||
.isEqualTo(new JSONArray().appendElement("logout"));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
|
||||
@@ -63,7 +63,7 @@ class InMemoryAuditEventRepositoryTests {
|
||||
void addNullAuditEvent() {
|
||||
InMemoryAuditEventRepository repository = new InMemoryAuditEventRepository();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> repository.add(null))
|
||||
.withMessageContaining("AuditEvent must not be null");
|
||||
.withMessageContaining("AuditEvent must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,30 +44,33 @@ class AvailabilityStateHealthIndicatorTests {
|
||||
@Test
|
||||
void createWhenApplicationAvailabilityIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new AvailabilityStateHealthIndicator(null, LivenessState.class, (statusMappings) -> {
|
||||
})).withMessage("ApplicationAvailability must not be null");
|
||||
.isThrownBy(() -> new AvailabilityStateHealthIndicator(null, LivenessState.class, (statusMappings) -> {
|
||||
}))
|
||||
.withMessage("ApplicationAvailability must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenStateTypeIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> new AvailabilityStateHealthIndicator(this.applicationAvailability, null, (statusMappings) -> {
|
||||
})).withMessage("StateType must not be null");
|
||||
}))
|
||||
.withMessage("StateType must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenStatusMappingIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> new AvailabilityStateHealthIndicator(this.applicationAvailability, LivenessState.class, null))
|
||||
.withMessage("StatusMappings must not be null");
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(
|
||||
() -> new AvailabilityStateHealthIndicator(this.applicationAvailability, LivenessState.class, null))
|
||||
.withMessage("StatusMappings must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenStatusMappingDoesNotCoverAllEnumsThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new AvailabilityStateHealthIndicator(this.applicationAvailability,
|
||||
LivenessState.class, (statusMappings) -> statusMappings.add(LivenessState.CORRECT, Status.UP)))
|
||||
.withMessage("StatusMappings does not include BROKEN");
|
||||
.isThrownBy(() -> new AvailabilityStateHealthIndicator(this.applicationAvailability, LivenessState.class,
|
||||
(statusMappings) -> statusMappings.add(LivenessState.CORRECT, Status.UP)))
|
||||
.withMessage("StatusMappings does not include BROKEN");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -46,7 +46,7 @@ class BeansEndpointTests {
|
||||
@Test
|
||||
void beansAreFound() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(EndpointConfiguration.class);
|
||||
.withUserConfiguration(EndpointConfiguration.class);
|
||||
contextRunner.run((context) -> {
|
||||
BeansDescriptor result = context.getBean(BeansEndpoint.class).beans();
|
||||
ContextBeansDescriptor descriptor = result.getContexts().get(context.getId());
|
||||
@@ -60,13 +60,13 @@ class BeansEndpointTests {
|
||||
@Test
|
||||
void infrastructureBeansAreOmitted() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(EndpointConfiguration.class);
|
||||
.withUserConfiguration(EndpointConfiguration.class);
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurableListableBeanFactory factory = (ConfigurableListableBeanFactory) context
|
||||
.getAutowireCapableBeanFactory();
|
||||
.getAutowireCapableBeanFactory();
|
||||
List<String> infrastructureBeans = Stream.of(context.getBeanDefinitionNames())
|
||||
.filter((name) -> BeanDefinition.ROLE_INFRASTRUCTURE == factory.getBeanDefinition(name).getRole())
|
||||
.toList();
|
||||
.filter((name) -> BeanDefinition.ROLE_INFRASTRUCTURE == factory.getBeanDefinition(name).getRole())
|
||||
.toList();
|
||||
BeansDescriptor result = context.getBean(BeansEndpoint.class).beans();
|
||||
ContextBeansDescriptor contextDescriptor = result.getContexts().get(context.getId());
|
||||
Map<String, BeanDescriptor> beans = contextDescriptor.getBeans();
|
||||
@@ -79,7 +79,7 @@ class BeansEndpointTests {
|
||||
@Test
|
||||
void lazyBeansAreOmitted() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(EndpointConfiguration.class, LazyBeanConfiguration.class);
|
||||
.withUserConfiguration(EndpointConfiguration.class, LazyBeanConfiguration.class);
|
||||
contextRunner.run((context) -> {
|
||||
BeansDescriptor result = context.getBean(BeansEndpoint.class).beans();
|
||||
ContextBeansDescriptor contextDescriptor = result.getContexts().get(context.getId());
|
||||
@@ -91,14 +91,15 @@ class BeansEndpointTests {
|
||||
@Test
|
||||
void beansInParentContextAreFound() {
|
||||
ApplicationContextRunner parentRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(BeanConfiguration.class);
|
||||
.withUserConfiguration(BeanConfiguration.class);
|
||||
parentRunner.run((parent) -> {
|
||||
new ApplicationContextRunner().withUserConfiguration(EndpointConfiguration.class).withParent(parent)
|
||||
.run((child) -> {
|
||||
BeansDescriptor result = child.getBean(BeansEndpoint.class).beans();
|
||||
assertThat(result.getContexts().get(parent.getId()).getBeans()).containsKey("bean");
|
||||
assertThat(result.getContexts().get(child.getId()).getBeans()).containsKey("endpoint");
|
||||
});
|
||||
new ApplicationContextRunner().withUserConfiguration(EndpointConfiguration.class)
|
||||
.withParent(parent)
|
||||
.run((child) -> {
|
||||
BeansDescriptor result = child.getBean(BeansEndpoint.class).beans();
|
||||
assertThat(result.getContexts().get(parent.getId()).getBeans()).containsKey("bean");
|
||||
assertThat(result.getContexts().get(child.getId()).getBeans()).containsKey("endpoint");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -87,7 +87,9 @@ class CachesEndpointTests {
|
||||
cacheManagers.put("another", new ConcurrentMapCacheManager("c", "dupe-cache"));
|
||||
CachesEndpoint endpoint = new CachesEndpoint(cacheManagers);
|
||||
assertThatExceptionOfType(NonUniqueCacheException.class).isThrownBy(() -> endpoint.cache("dupe-cache", null))
|
||||
.withMessageContaining("dupe-cache").withMessageContaining("test").withMessageContaining("another");
|
||||
.withMessageContaining("dupe-cache")
|
||||
.withMessageContaining("test")
|
||||
.withMessageContaining("another");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -147,8 +149,10 @@ class CachesEndpointTests {
|
||||
cacheManagers.put("another", cacheManager(mockCache("dupe-cache")));
|
||||
CachesEndpoint endpoint = new CachesEndpoint(cacheManagers);
|
||||
assertThatExceptionOfType(NonUniqueCacheException.class)
|
||||
.isThrownBy(() -> endpoint.clearCache("dupe-cache", null)).withMessageContaining("dupe-cache")
|
||||
.withMessageContaining("test").withMessageContaining("another");
|
||||
.isThrownBy(() -> endpoint.clearCache("dupe-cache", null))
|
||||
.withMessageContaining("dupe-cache")
|
||||
.withMessageContaining("test")
|
||||
.withMessageContaining("another");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,18 +40,36 @@ class CachesEndpointWebIntegrationTests {
|
||||
|
||||
@WebEndpointTest
|
||||
void allCaches(WebTestClient client) {
|
||||
client.get().uri("/actuator/caches").exchange().expectStatus().isOk().expectBody()
|
||||
.jsonPath("cacheManagers.one.caches.a.target").isEqualTo(ConcurrentHashMap.class.getName())
|
||||
.jsonPath("cacheManagers.one.caches.b.target").isEqualTo(ConcurrentHashMap.class.getName())
|
||||
.jsonPath("cacheManagers.two.caches.a.target").isEqualTo(ConcurrentHashMap.class.getName())
|
||||
.jsonPath("cacheManagers.two.caches.c.target").isEqualTo(ConcurrentHashMap.class.getName());
|
||||
client.get()
|
||||
.uri("/actuator/caches")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody()
|
||||
.jsonPath("cacheManagers.one.caches.a.target")
|
||||
.isEqualTo(ConcurrentHashMap.class.getName())
|
||||
.jsonPath("cacheManagers.one.caches.b.target")
|
||||
.isEqualTo(ConcurrentHashMap.class.getName())
|
||||
.jsonPath("cacheManagers.two.caches.a.target")
|
||||
.isEqualTo(ConcurrentHashMap.class.getName())
|
||||
.jsonPath("cacheManagers.two.caches.c.target")
|
||||
.isEqualTo(ConcurrentHashMap.class.getName());
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void namedCache(WebTestClient client) {
|
||||
client.get().uri("/actuator/caches/b").exchange().expectStatus().isOk().expectBody().jsonPath("name")
|
||||
.isEqualTo("b").jsonPath("cacheManager").isEqualTo("one").jsonPath("target")
|
||||
.isEqualTo(ConcurrentHashMap.class.getName());
|
||||
client.get()
|
||||
.uri("/actuator/caches/b")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody()
|
||||
.jsonPath("name")
|
||||
.isEqualTo("b")
|
||||
.jsonPath("cacheManager")
|
||||
.isEqualTo("one")
|
||||
.jsonPath("target")
|
||||
.isEqualTo(ConcurrentHashMap.class.getName());
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
|
||||
@@ -59,8 +59,9 @@ class CassandraDriverReactiveHealthIndicatorTests {
|
||||
CqlSession session = mockCqlSessionWithNodeState(NodeState.UP);
|
||||
CassandraDriverReactiveHealthIndicator healthIndicator = new CassandraDriverReactiveHealthIndicator(session);
|
||||
Mono<Health> health = healthIndicator.health();
|
||||
StepVerifier.create(health).consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.UP))
|
||||
.verifyComplete();
|
||||
StepVerifier.create(health)
|
||||
.consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.UP))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -68,8 +69,9 @@ class CassandraDriverReactiveHealthIndicatorTests {
|
||||
CqlSession session = mockCqlSessionWithNodeState(NodeState.DOWN);
|
||||
CassandraDriverReactiveHealthIndicator healthIndicator = new CassandraDriverReactiveHealthIndicator(session);
|
||||
Mono<Health> health = healthIndicator.health();
|
||||
StepVerifier.create(health).consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.DOWN))
|
||||
.verifyComplete();
|
||||
StepVerifier.create(health)
|
||||
.consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.DOWN))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -77,8 +79,9 @@ class CassandraDriverReactiveHealthIndicatorTests {
|
||||
CqlSession session = mockCqlSessionWithNodeState(NodeState.UNKNOWN);
|
||||
CassandraDriverReactiveHealthIndicator healthIndicator = new CassandraDriverReactiveHealthIndicator(session);
|
||||
Mono<Health> health = healthIndicator.health();
|
||||
StepVerifier.create(health).consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.DOWN))
|
||||
.verifyComplete();
|
||||
StepVerifier.create(health)
|
||||
.consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.DOWN))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -86,8 +89,9 @@ class CassandraDriverReactiveHealthIndicatorTests {
|
||||
CqlSession session = mockCqlSessionWithNodeState(NodeState.FORCED_DOWN);
|
||||
CassandraDriverReactiveHealthIndicator healthIndicator = new CassandraDriverReactiveHealthIndicator(session);
|
||||
Mono<Health> health = healthIndicator.health();
|
||||
StepVerifier.create(health).consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.DOWN))
|
||||
.verifyComplete();
|
||||
StepVerifier.create(health)
|
||||
.consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.DOWN))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -95,8 +99,9 @@ class CassandraDriverReactiveHealthIndicatorTests {
|
||||
CqlSession session = mockCqlSessionWithNodeState(NodeState.UP, NodeState.DOWN);
|
||||
CassandraDriverReactiveHealthIndicator healthIndicator = new CassandraDriverReactiveHealthIndicator(session);
|
||||
Mono<Health> health = healthIndicator.health();
|
||||
StepVerifier.create(health).consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.UP))
|
||||
.verifyComplete();
|
||||
StepVerifier.create(health)
|
||||
.consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.UP))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -104,8 +109,9 @@ class CassandraDriverReactiveHealthIndicatorTests {
|
||||
CqlSession session = mockCqlSessionWithNodeState(NodeState.UP, NodeState.UNKNOWN);
|
||||
CassandraDriverReactiveHealthIndicator healthIndicator = new CassandraDriverReactiveHealthIndicator(session);
|
||||
Mono<Health> health = healthIndicator.health();
|
||||
StepVerifier.create(health).consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.UP))
|
||||
.verifyComplete();
|
||||
StepVerifier.create(health)
|
||||
.consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.UP))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -113,8 +119,9 @@ class CassandraDriverReactiveHealthIndicatorTests {
|
||||
CqlSession session = mockCqlSessionWithNodeState(NodeState.UP, NodeState.FORCED_DOWN);
|
||||
CassandraDriverReactiveHealthIndicator healthIndicator = new CassandraDriverReactiveHealthIndicator(session);
|
||||
Mono<Health> health = healthIndicator.health();
|
||||
StepVerifier.create(health).consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.UP))
|
||||
.verifyComplete();
|
||||
StepVerifier.create(health)
|
||||
.consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.UP))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,7 +47,7 @@ class ShutdownEndpointTests {
|
||||
@Test
|
||||
void shutdown() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(EndpointConfig.class);
|
||||
.withUserConfiguration(EndpointConfig.class);
|
||||
contextRunner.run((context) -> {
|
||||
EndpointConfig config = context.getBean(EndpointConfig.class);
|
||||
ClassLoader previousTccl = Thread.currentThread().getContextClassLoader();
|
||||
@@ -69,7 +69,9 @@ class ShutdownEndpointTests {
|
||||
@Test
|
||||
void shutdownChild() throws Exception {
|
||||
ConfigurableApplicationContext context = new SpringApplicationBuilder(EmptyConfig.class)
|
||||
.child(EndpointConfig.class).web(WebApplicationType.NONE).run();
|
||||
.child(EndpointConfig.class)
|
||||
.web(WebApplicationType.NONE)
|
||||
.run();
|
||||
CountDownLatch latch = context.getBean(EndpointConfig.class).latch;
|
||||
assertThat(context.getBean(ShutdownEndpoint.class).shutdown().getMessage()).startsWith("Shutting down");
|
||||
assertThat(context.isActive()).isTrue();
|
||||
@@ -79,7 +81,9 @@ class ShutdownEndpointTests {
|
||||
@Test
|
||||
void shutdownParent() throws Exception {
|
||||
ConfigurableApplicationContext context = new SpringApplicationBuilder(EndpointConfig.class)
|
||||
.child(EmptyConfig.class).web(WebApplicationType.NONE).run();
|
||||
.child(EmptyConfig.class)
|
||||
.web(WebApplicationType.NONE)
|
||||
.run();
|
||||
CountDownLatch parentLatch = context.getBean(EndpointConfig.class).latch;
|
||||
CountDownLatch childLatch = context.getBean(EmptyConfig.class).latch;
|
||||
assertThat(context.getBean(ShutdownEndpoint.class).shutdown().getMessage()).startsWith("Shutting down");
|
||||
|
||||
@@ -44,22 +44,22 @@ class ConfigurationPropertiesReportEndpointFilteringTests {
|
||||
@Test
|
||||
void filterByPrefixSingleMatch() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner().withUserConfiguration(Config.class)
|
||||
.withPropertyValues("foo.primary.name:foo1", "foo.secondary.name:foo2", "only.bar.name:solo1");
|
||||
.withPropertyValues("foo.primary.name:foo1", "foo.secondary.name:foo2", "only.bar.name:solo1");
|
||||
assertProperties(contextRunner, "solo1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void filterByPrefixMultipleMatches() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner().withUserConfiguration(Config.class)
|
||||
.withPropertyValues("foo.primary.name:foo1", "foo.secondary.name:foo2", "only.bar.name:solo1");
|
||||
.withPropertyValues("foo.primary.name:foo1", "foo.secondary.name:foo2", "only.bar.name:solo1");
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint
|
||||
.configurationPropertiesWithPrefix("foo.");
|
||||
.configurationPropertiesWithPrefix("foo.");
|
||||
assertThat(applicationProperties.getContexts()).containsOnlyKeys(context.getId());
|
||||
ContextConfigurationPropertiesDescriptor contextProperties = applicationProperties.getContexts()
|
||||
.get(context.getId());
|
||||
.get(context.getId());
|
||||
assertThat(contextProperties.getBeans()).containsOnlyKeys("primaryFoo", "secondaryFoo");
|
||||
});
|
||||
}
|
||||
@@ -67,15 +67,15 @@ class ConfigurationPropertiesReportEndpointFilteringTests {
|
||||
@Test
|
||||
void filterByPrefixNoMatches() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner().withUserConfiguration(Config.class)
|
||||
.withPropertyValues("foo.primary.name:foo1", "foo.secondary.name:foo2", "only.bar.name:solo1");
|
||||
.withPropertyValues("foo.primary.name:foo1", "foo.secondary.name:foo2", "only.bar.name:solo1");
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint
|
||||
.configurationPropertiesWithPrefix("foo.third");
|
||||
.configurationPropertiesWithPrefix("foo.third");
|
||||
assertThat(applicationProperties.getContexts()).containsOnlyKeys(context.getId());
|
||||
ContextConfigurationPropertiesDescriptor contextProperties = applicationProperties.getContexts()
|
||||
.get(context.getId());
|
||||
.get(context.getId());
|
||||
assertThat(contextProperties.getBeans()).isEmpty();
|
||||
});
|
||||
}
|
||||
@@ -83,30 +83,33 @@ class ConfigurationPropertiesReportEndpointFilteringTests {
|
||||
@Test
|
||||
void noSanitizationWhenShowAlways() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(ConfigWithAlways.class)
|
||||
.withPropertyValues("foo.primary.name:foo1", "foo.secondary.name:foo2", "only.bar.name:solo1");
|
||||
.withUserConfiguration(ConfigWithAlways.class)
|
||||
.withPropertyValues("foo.primary.name:foo1", "foo.secondary.name:foo2", "only.bar.name:solo1");
|
||||
assertProperties(contextRunner, "solo1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void sanitizationWhenShowNever() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(ConfigWithNever.class)
|
||||
.withPropertyValues("foo.primary.name:foo1", "foo.secondary.name:foo2", "only.bar.name:solo1");
|
||||
.withUserConfiguration(ConfigWithNever.class)
|
||||
.withPropertyValues("foo.primary.name:foo1", "foo.secondary.name:foo2", "only.bar.name:solo1");
|
||||
assertProperties(contextRunner, "******");
|
||||
}
|
||||
|
||||
private void assertProperties(ApplicationContextRunner contextRunner, String value) {
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint
|
||||
.configurationPropertiesWithPrefix("only.bar");
|
||||
.configurationPropertiesWithPrefix("only.bar");
|
||||
assertThat(applicationProperties.getContexts()).containsOnlyKeys(context.getId());
|
||||
ContextConfigurationPropertiesDescriptor contextProperties = applicationProperties.getContexts()
|
||||
.get(context.getId());
|
||||
Optional<String> key = contextProperties.getBeans().keySet().stream()
|
||||
.filter((id) -> findIdFromPrefix("only.bar", id)).findAny();
|
||||
.get(context.getId());
|
||||
Optional<String> key = contextProperties.getBeans()
|
||||
.keySet()
|
||||
.stream()
|
||||
.filter((id) -> findIdFromPrefix("only.bar", id))
|
||||
.findAny();
|
||||
ConfigurationPropertiesBeanDescriptor descriptor = contextProperties.getBeans().get(key.get());
|
||||
assertThat(descriptor.getPrefix()).isEqualTo("only.bar");
|
||||
assertThat(descriptor.getProperties()).containsEntry("name", value);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -43,14 +43,14 @@ class ConfigurationPropertiesReportEndpointMethodAnnotationsTests {
|
||||
@Test
|
||||
void testNaming() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner().withUserConfiguration(Config.class)
|
||||
.withPropertyValues("other.name:foo", "first.name:bar");
|
||||
.withPropertyValues("other.name:foo", "first.name:bar");
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
assertThat(applicationProperties.getContexts()).containsOnlyKeys(context.getId());
|
||||
ContextConfigurationPropertiesDescriptor contextProperties = applicationProperties.getContexts()
|
||||
.get(context.getId());
|
||||
.get(context.getId());
|
||||
ConfigurationPropertiesBeanDescriptor other = contextProperties.getBeans().get("other");
|
||||
assertThat(other).isNotNull();
|
||||
assertThat(other.getPrefix()).isEqualTo("other");
|
||||
@@ -62,14 +62,15 @@ class ConfigurationPropertiesReportEndpointMethodAnnotationsTests {
|
||||
@Test
|
||||
void prefixFromBeanMethodConfigurationPropertiesCanOverridePrefixOnClass() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(OverriddenPrefix.class).withPropertyValues("other.name:foo");
|
||||
.withUserConfiguration(OverriddenPrefix.class)
|
||||
.withPropertyValues("other.name:foo");
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
assertThat(applicationProperties.getContexts()).containsOnlyKeys(context.getId());
|
||||
ContextConfigurationPropertiesDescriptor contextProperties = applicationProperties.getContexts()
|
||||
.get(context.getId());
|
||||
.get(context.getId());
|
||||
ConfigurationPropertiesBeanDescriptor bar = contextProperties.getBeans().get("bar");
|
||||
assertThat(bar).isNotNull();
|
||||
assertThat(bar.getPrefix()).isEqualTo("other");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,17 +42,18 @@ class ConfigurationPropertiesReportEndpointParentTests {
|
||||
@Test
|
||||
void configurationPropertiesClass() {
|
||||
new ApplicationContextRunner().withUserConfiguration(Parent.class).run((parent) -> {
|
||||
new ApplicationContextRunner().withUserConfiguration(ClassConfigurationProperties.class).withParent(parent)
|
||||
.run((child) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = child
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
assertThat(applicationProperties.getContexts()).containsOnlyKeys(child.getId(), parent.getId());
|
||||
assertThat(applicationProperties.getContexts().get(child.getId()).getBeans().keySet())
|
||||
.containsExactly("someProperties");
|
||||
assertThat((applicationProperties.getContexts().get(parent.getId()).getBeans().keySet()))
|
||||
.containsExactly("testProperties");
|
||||
});
|
||||
new ApplicationContextRunner().withUserConfiguration(ClassConfigurationProperties.class)
|
||||
.withParent(parent)
|
||||
.run((child) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = child
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
assertThat(applicationProperties.getContexts()).containsOnlyKeys(child.getId(), parent.getId());
|
||||
assertThat(applicationProperties.getContexts().get(child.getId()).getBeans().keySet())
|
||||
.containsExactly("someProperties");
|
||||
assertThat((applicationProperties.getContexts().get(parent.getId()).getBeans().keySet()))
|
||||
.containsExactly("testProperties");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -60,15 +61,16 @@ class ConfigurationPropertiesReportEndpointParentTests {
|
||||
void configurationPropertiesBeanMethod() {
|
||||
new ApplicationContextRunner().withUserConfiguration(Parent.class).run((parent) -> {
|
||||
new ApplicationContextRunner().withUserConfiguration(BeanMethodConfigurationProperties.class)
|
||||
.withParent(parent).run((child) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = child
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
assertThat(applicationProperties.getContexts().get(child.getId()).getBeans().keySet())
|
||||
.containsExactlyInAnyOrder("otherProperties");
|
||||
assertThat((applicationProperties.getContexts().get(parent.getId()).getBeans().keySet()))
|
||||
.containsExactly("testProperties");
|
||||
});
|
||||
.withParent(parent)
|
||||
.run((child) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = child
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
assertThat(applicationProperties.getContexts().get(child.getId()).getBeans().keySet())
|
||||
.containsExactlyInAnyOrder("otherProperties");
|
||||
assertThat((applicationProperties.getContexts().get(parent.getId()).getBeans().keySet()))
|
||||
.containsExactly("testProperties");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -60,22 +60,36 @@ class ConfigurationPropertiesReportEndpointProxyTests {
|
||||
SqlExecutor.class);
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesDescriptor applicationProperties = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class).configurationProperties();
|
||||
assertThat(applicationProperties.getContexts().get(context.getId()).getBeans().values().stream()
|
||||
.map(ConfigurationPropertiesBeanDescriptor::getPrefix).filter("executor.sql"::equals).findFirst())
|
||||
.isNotEmpty();
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class)
|
||||
.configurationProperties();
|
||||
assertThat(applicationProperties.getContexts()
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.values()
|
||||
.stream()
|
||||
.map(ConfigurationPropertiesBeanDescriptor::getPrefix)
|
||||
.filter("executor.sql"::equals)
|
||||
.findFirst()).isNotEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void proxiedConstructorBoundPropertiesShouldBeAvailableInReport() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(ValidatedConfiguration.class).withPropertyValues("validated.name=baz");
|
||||
.withUserConfiguration(ValidatedConfiguration.class)
|
||||
.withPropertyValues("validated.name=baz");
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesDescriptor applicationProperties = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class).configurationProperties();
|
||||
Map<String, Object> properties = applicationProperties.getContexts().get(context.getId()).getBeans()
|
||||
.values().stream().map(ConfigurationPropertiesBeanDescriptor::getProperties).findFirst().get();
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class)
|
||||
.configurationProperties();
|
||||
Map<String, Object> properties = applicationProperties.getContexts()
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.values()
|
||||
.stream()
|
||||
.map(ConfigurationPropertiesBeanDescriptor::getProperties)
|
||||
.findFirst()
|
||||
.get();
|
||||
assertThat(properties).containsEntry("name", "baz");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -59,13 +59,15 @@ class ConfigurationPropertiesReportEndpointSerializationTests {
|
||||
@Test
|
||||
void testNaming() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner().withUserConfiguration(FooConfig.class)
|
||||
.withPropertyValues("foo.name:foo");
|
||||
.withPropertyValues("foo.name:foo");
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts().get(context.getId())
|
||||
.getBeans().get("foo");
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts()
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.get("foo");
|
||||
assertThat(foo).isNotNull();
|
||||
assertThat(foo.getPrefix()).isEqualTo("foo");
|
||||
Map<String, Object> map = foo.getProperties();
|
||||
@@ -79,13 +81,15 @@ class ConfigurationPropertiesReportEndpointSerializationTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
void testNestedNaming() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner().withUserConfiguration(FooConfig.class)
|
||||
.withPropertyValues("foo.bar.name:foo");
|
||||
.withPropertyValues("foo.bar.name:foo");
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts().get(context.getId())
|
||||
.getBeans().get("foo");
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts()
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.get("foo");
|
||||
assertThat(foo).isNotNull();
|
||||
Map<String, Object> map = foo.getProperties();
|
||||
assertThat(map).isNotNull();
|
||||
@@ -98,13 +102,16 @@ class ConfigurationPropertiesReportEndpointSerializationTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
void testSelfReferentialProperty() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(SelfReferentialConfig.class).withPropertyValues("foo.name:foo");
|
||||
.withUserConfiguration(SelfReferentialConfig.class)
|
||||
.withPropertyValues("foo.name:foo");
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts().get(context.getId())
|
||||
.getBeans().get("foo");
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts()
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.get("foo");
|
||||
assertThat(foo.getPrefix()).isEqualTo("foo");
|
||||
Map<String, Object> map = foo.getProperties();
|
||||
assertThat(map).isNotNull();
|
||||
@@ -119,13 +126,15 @@ class ConfigurationPropertiesReportEndpointSerializationTests {
|
||||
@Test
|
||||
void testCycle() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(CycleConfig.class);
|
||||
.withUserConfiguration(CycleConfig.class);
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
ConfigurationPropertiesBeanDescriptor cycle = applicationProperties.getContexts().get(context.getId())
|
||||
.getBeans().get("cycle");
|
||||
ConfigurationPropertiesBeanDescriptor cycle = applicationProperties.getContexts()
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.get("cycle");
|
||||
assertThat(cycle.getPrefix()).isEqualTo("cycle");
|
||||
Map<String, Object> map = cycle.getProperties();
|
||||
assertThat(map).isNotNull();
|
||||
@@ -138,13 +147,15 @@ class ConfigurationPropertiesReportEndpointSerializationTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
void testMap() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner().withUserConfiguration(MapConfig.class)
|
||||
.withPropertyValues("foo.map.name:foo");
|
||||
.withPropertyValues("foo.map.name:foo");
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
ConfigurationPropertiesBeanDescriptor fooProperties = applicationProperties.getContexts()
|
||||
.get(context.getId()).getBeans().get("foo");
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.get("foo");
|
||||
assertThat(fooProperties).isNotNull();
|
||||
assertThat(fooProperties.getPrefix()).isEqualTo("foo");
|
||||
Map<String, Object> map = fooProperties.getProperties();
|
||||
@@ -159,10 +170,12 @@ class ConfigurationPropertiesReportEndpointSerializationTests {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner().withUserConfiguration(MapConfig.class);
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts().get(context.getId())
|
||||
.getBeans().get("foo");
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts()
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.get("foo");
|
||||
assertThat(foo).isNotNull();
|
||||
assertThat(foo.getPrefix()).isEqualTo("foo");
|
||||
Map<String, Object> map = foo.getProperties();
|
||||
@@ -176,13 +189,15 @@ class ConfigurationPropertiesReportEndpointSerializationTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
void testList() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner().withUserConfiguration(ListConfig.class)
|
||||
.withPropertyValues("foo.list[0]:foo");
|
||||
.withPropertyValues("foo.list[0]:foo");
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts().get(context.getId())
|
||||
.getBeans().get("foo");
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts()
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.get("foo");
|
||||
assertThat(foo).isNotNull();
|
||||
assertThat(foo.getPrefix()).isEqualTo("foo");
|
||||
Map<String, Object> map = foo.getProperties();
|
||||
@@ -195,13 +210,16 @@ class ConfigurationPropertiesReportEndpointSerializationTests {
|
||||
@Test
|
||||
void testInetAddress() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(AddressedConfig.class).withPropertyValues("foo.address:192.168.1.10");
|
||||
.withUserConfiguration(AddressedConfig.class)
|
||||
.withPropertyValues("foo.address:192.168.1.10");
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts().get(context.getId())
|
||||
.getBeans().get("foo");
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts()
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.get("foo");
|
||||
assertThat(foo).isNotNull();
|
||||
assertThat(foo.getPrefix()).isEqualTo("foo");
|
||||
Map<String, Object> map = foo.getProperties();
|
||||
@@ -215,14 +233,16 @@ class ConfigurationPropertiesReportEndpointSerializationTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
void testInitializedMapAndList() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(InitializedMapAndListPropertiesConfig.class)
|
||||
.withPropertyValues("foo.map.entryOne:true", "foo.list[0]:abc");
|
||||
.withUserConfiguration(InitializedMapAndListPropertiesConfig.class)
|
||||
.withPropertyValues("foo.map.entryOne:true", "foo.list[0]:abc");
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts().get(context.getId())
|
||||
.getBeans().get("foo");
|
||||
ConfigurationPropertiesBeanDescriptor foo = applicationProperties.getContexts()
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.get("foo");
|
||||
assertThat(foo.getPrefix()).isEqualTo("foo");
|
||||
Map<String, Object> propertiesMap = foo.getProperties();
|
||||
assertThat(propertiesMap).containsOnlyKeys("bar", "name", "map", "list");
|
||||
@@ -236,13 +256,15 @@ class ConfigurationPropertiesReportEndpointSerializationTests {
|
||||
@Test
|
||||
void hikariDataSourceConfigurationPropertiesBeanCanBeSerialized() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(HikariDataSourceConfig.class);
|
||||
.withUserConfiguration(HikariDataSourceConfig.class);
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
ConfigurationPropertiesBeanDescriptor hikariDataSource = applicationProperties.getContexts()
|
||||
.get(context.getId()).getBeans().get("hikariDataSource");
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.get("hikariDataSource");
|
||||
Map<String, Object> nestedProperties = hikariDataSource.getProperties();
|
||||
assertThat(nestedProperties).doesNotContainKey("error");
|
||||
});
|
||||
@@ -253,15 +275,18 @@ class ConfigurationPropertiesReportEndpointSerializationTests {
|
||||
void endpointResponseUsesToStringOfCharSequenceAsPropertyValue() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner().withInitializer((context) -> {
|
||||
ConfigurableEnvironment environment = context.getEnvironment();
|
||||
environment.getPropertySources().addFirst(new MapPropertySource("test",
|
||||
Collections.singletonMap("foo.name", new CharSequenceProperty("Spring Boot"))));
|
||||
environment.getPropertySources()
|
||||
.addFirst(new MapPropertySource("test",
|
||||
Collections.singletonMap("foo.name", new CharSequenceProperty("Spring Boot"))));
|
||||
}).withUserConfiguration(FooConfig.class);
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
ConfigurationPropertiesBeanDescriptor descriptor = applicationProperties.getContexts().get(context.getId())
|
||||
.getBeans().get("foo");
|
||||
ConfigurationPropertiesBeanDescriptor descriptor = applicationProperties.getContexts()
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.get("foo");
|
||||
assertThat((Map<String, Object>) descriptor.getInputs().get("name")).containsEntry("value", "Spring Boot");
|
||||
});
|
||||
}
|
||||
@@ -271,15 +296,18 @@ class ConfigurationPropertiesReportEndpointSerializationTests {
|
||||
void endpointResponseUsesPlaceholderForComplexValueAsPropertyValue() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner().withInitializer((context) -> {
|
||||
ConfigurableEnvironment environment = context.getEnvironment();
|
||||
environment.getPropertySources().addFirst(new MapPropertySource("test",
|
||||
Collections.singletonMap("foo.name", new ComplexProperty("Spring Boot"))));
|
||||
environment.getPropertySources()
|
||||
.addFirst(new MapPropertySource("test",
|
||||
Collections.singletonMap("foo.name", new ComplexProperty("Spring Boot"))));
|
||||
}).withUserConfiguration(ComplexPropertyToStringConverter.class, FooConfig.class);
|
||||
contextRunner.run((context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesDescriptor applicationProperties = endpoint.configurationProperties();
|
||||
ConfigurationPropertiesBeanDescriptor descriptor = applicationProperties.getContexts().get(context.getId())
|
||||
.getBeans().get("foo");
|
||||
ConfigurationPropertiesBeanDescriptor descriptor = applicationProperties.getContexts()
|
||||
.get(context.getId())
|
||||
.getBeans()
|
||||
.get("foo");
|
||||
assertThat((Map<String, Object>) descriptor.getInputs().get("name")).containsEntry("value",
|
||||
"Complex property value " + ComplexProperty.class.getName());
|
||||
});
|
||||
|
||||
@@ -66,114 +66,122 @@ import static org.assertj.core.api.Assertions.entry;
|
||||
class ConfigurationPropertiesReportEndpointTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(EndpointConfig.class);
|
||||
.withUserConfiguration(EndpointConfig.class);
|
||||
|
||||
@Test
|
||||
void descriptorWithJavaBeanBindMethodDetectsRelevantProperties() {
|
||||
this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class).run(assertProperties("test",
|
||||
(properties) -> assertThat(properties).containsOnlyKeys("dbPassword", "myTestProperty", "duration")));
|
||||
this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class)
|
||||
.run(assertProperties("test", (properties) -> assertThat(properties).containsOnlyKeys("dbPassword",
|
||||
"myTestProperty", "duration")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void descriptorWithAutowiredConstructorBindMethodDetectsRelevantProperties() {
|
||||
this.contextRunner.withUserConfiguration(AutowiredPropertiesConfiguration.class)
|
||||
.run(assertProperties("autowired", (properties) -> assertThat(properties).containsOnlyKeys("counter")));
|
||||
.run(assertProperties("autowired", (properties) -> assertThat(properties).containsOnlyKeys("counter")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void descriptorWithValueObjectBindMethodDetectsRelevantProperties() {
|
||||
this.contextRunner.withUserConfiguration(ImmutablePropertiesConfiguration.class).run(assertProperties(
|
||||
"immutable",
|
||||
(properties) -> assertThat(properties).containsOnlyKeys("dbPassword", "myTestProperty", "for")));
|
||||
this.contextRunner.withUserConfiguration(ImmutablePropertiesConfiguration.class)
|
||||
.run(assertProperties("immutable",
|
||||
(properties) -> assertThat(properties).containsOnlyKeys("dbPassword", "myTestProperty", "for")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void descriptorWithValueObjectBindMethodUseDedicatedConstructor() {
|
||||
this.contextRunner.withUserConfiguration(MultiConstructorPropertiesConfiguration.class).run(assertProperties(
|
||||
"multiconstructor", (properties) -> assertThat(properties).containsOnly(entry("name", "test"))));
|
||||
this.contextRunner.withUserConfiguration(MultiConstructorPropertiesConfiguration.class)
|
||||
.run(assertProperties("multiconstructor",
|
||||
(properties) -> assertThat(properties).containsOnly(entry("name", "test"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void descriptorWithValueObjectBindMethodHandleNestedType() {
|
||||
this.contextRunner.withPropertyValues("immutablenested.nested.name=nested", "immutablenested.nested.counter=42")
|
||||
.withUserConfiguration(ImmutableNestedPropertiesConfiguration.class)
|
||||
.run(assertProperties("immutablenested", (properties) -> {
|
||||
assertThat(properties).containsOnlyKeys("name", "nested");
|
||||
Map<String, Object> nested = (Map<String, Object>) properties.get("nested");
|
||||
assertThat(nested).containsOnly(entry("name", "nested"), entry("counter", 42));
|
||||
}, (inputs) -> {
|
||||
Map<String, Object> nested = (Map<String, Object>) inputs.get("nested");
|
||||
Map<String, Object> name = (Map<String, Object>) nested.get("name");
|
||||
Map<String, Object> counter = (Map<String, Object>) nested.get("counter");
|
||||
assertThat(name).containsEntry("value", "nested");
|
||||
assertThat(name).containsEntry("origin",
|
||||
"\"immutablenested.nested.name\" from property source \"test\"");
|
||||
assertThat(counter).containsEntry("origin",
|
||||
"\"immutablenested.nested.counter\" from property source \"test\"");
|
||||
assertThat(counter).containsEntry("value", "42");
|
||||
}));
|
||||
.withUserConfiguration(ImmutableNestedPropertiesConfiguration.class)
|
||||
.run(assertProperties("immutablenested", (properties) -> {
|
||||
assertThat(properties).containsOnlyKeys("name", "nested");
|
||||
Map<String, Object> nested = (Map<String, Object>) properties.get("nested");
|
||||
assertThat(nested).containsOnly(entry("name", "nested"), entry("counter", 42));
|
||||
}, (inputs) -> {
|
||||
Map<String, Object> nested = (Map<String, Object>) inputs.get("nested");
|
||||
Map<String, Object> name = (Map<String, Object>) nested.get("name");
|
||||
Map<String, Object> counter = (Map<String, Object>) nested.get("counter");
|
||||
assertThat(name).containsEntry("value", "nested");
|
||||
assertThat(name).containsEntry("origin",
|
||||
"\"immutablenested.nested.name\" from property source \"test\"");
|
||||
assertThat(counter).containsEntry("origin",
|
||||
"\"immutablenested.nested.counter\" from property source \"test\"");
|
||||
assertThat(counter).containsEntry("value", "42");
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void descriptorWithSimpleList() {
|
||||
this.contextRunner.withUserConfiguration(SensiblePropertiesConfiguration.class)
|
||||
.withPropertyValues("sensible.simpleList=a,b").run(assertProperties("sensible", (properties) -> {
|
||||
assertThat(properties.get("simpleList")).isInstanceOf(List.class);
|
||||
List<String> list = (List<String>) properties.get("simpleList");
|
||||
assertThat(list).hasSize(2);
|
||||
assertThat(list.get(0)).isEqualTo("a");
|
||||
assertThat(list.get(1)).isEqualTo("b");
|
||||
}, (inputs) -> {
|
||||
List<Object> list = (List<Object>) inputs.get("simpleList");
|
||||
assertThat(list).hasSize(2);
|
||||
Map<String, String> item = (Map<String, String>) list.get(0);
|
||||
String origin = item.get("origin");
|
||||
String value = item.get("value");
|
||||
assertThat(value).isEqualTo("a,b");
|
||||
assertThat(origin).isEqualTo("\"sensible.simpleList\" from property source \"test\"");
|
||||
}));
|
||||
.withPropertyValues("sensible.simpleList=a,b")
|
||||
.run(assertProperties("sensible", (properties) -> {
|
||||
assertThat(properties.get("simpleList")).isInstanceOf(List.class);
|
||||
List<String> list = (List<String>) properties.get("simpleList");
|
||||
assertThat(list).hasSize(2);
|
||||
assertThat(list.get(0)).isEqualTo("a");
|
||||
assertThat(list.get(1)).isEqualTo("b");
|
||||
}, (inputs) -> {
|
||||
List<Object> list = (List<Object>) inputs.get("simpleList");
|
||||
assertThat(list).hasSize(2);
|
||||
Map<String, String> item = (Map<String, String>) list.get(0);
|
||||
String origin = item.get("origin");
|
||||
String value = item.get("value");
|
||||
assertThat(value).isEqualTo("a,b");
|
||||
assertThat(origin).isEqualTo("\"sensible.simpleList\" from property source \"test\"");
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void descriptorDoesNotIncludePropertyWithNullValue() {
|
||||
this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class)
|
||||
.run(assertProperties("test", (properties) -> assertThat(properties).doesNotContainKey("nullValue")));
|
||||
.run(assertProperties("test", (properties) -> assertThat(properties).doesNotContainKey("nullValue")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void descriptorWithDurationProperty() {
|
||||
this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class).run(assertProperties("test",
|
||||
(properties) -> assertThat(properties.get("duration")).isEqualTo(Duration.ofSeconds(10).toString())));
|
||||
this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class)
|
||||
.run(assertProperties("test", (properties) -> assertThat(properties.get("duration"))
|
||||
.isEqualTo(Duration.ofSeconds(10).toString())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void descriptorWithNonCamelCaseProperty() {
|
||||
this.contextRunner.withUserConfiguration(MixedCasePropertiesConfiguration.class).run(assertProperties(
|
||||
"mixedcase", (properties) -> assertThat(properties.get("myURL")).isEqualTo("https://example.com")));
|
||||
this.contextRunner.withUserConfiguration(MixedCasePropertiesConfiguration.class)
|
||||
.run(assertProperties("mixedcase",
|
||||
(properties) -> assertThat(properties.get("myURL")).isEqualTo("https://example.com")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void descriptorWithMixedCaseProperty() {
|
||||
this.contextRunner.withUserConfiguration(MixedCasePropertiesConfiguration.class).run(assertProperties(
|
||||
"mixedcase", (properties) -> assertThat(properties.get("mIxedCase")).isEqualTo("mixed")));
|
||||
this.contextRunner.withUserConfiguration(MixedCasePropertiesConfiguration.class)
|
||||
.run(assertProperties("mixedcase",
|
||||
(properties) -> assertThat(properties.get("mIxedCase")).isEqualTo("mixed")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void descriptorWithSingleLetterProperty() {
|
||||
this.contextRunner.withUserConfiguration(MixedCasePropertiesConfiguration.class)
|
||||
.run(assertProperties("mixedcase", (properties) -> assertThat(properties.get("z")).isEqualTo("zzz")));
|
||||
.run(assertProperties("mixedcase", (properties) -> assertThat(properties.get("z")).isEqualTo("zzz")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void descriptorWithSimpleBooleanProperty() {
|
||||
this.contextRunner.withUserConfiguration(BooleanPropertiesConfiguration.class).run(assertProperties("boolean",
|
||||
(properties) -> assertThat(properties.get("simpleBoolean")).isEqualTo(true)));
|
||||
this.contextRunner.withUserConfiguration(BooleanPropertiesConfiguration.class)
|
||||
.run(assertProperties("boolean",
|
||||
(properties) -> assertThat(properties.get("simpleBoolean")).isEqualTo(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void descriptorWithMixedBooleanProperty() {
|
||||
this.contextRunner.withUserConfiguration(BooleanPropertiesConfiguration.class).run(assertProperties("boolean",
|
||||
(properties) -> assertThat(properties.get("mixedBoolean")).isEqualTo(true)));
|
||||
this.contextRunner.withUserConfiguration(BooleanPropertiesConfiguration.class)
|
||||
.run(assertProperties("boolean",
|
||||
(properties) -> assertThat(properties.get("mixedBoolean")).isEqualTo(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -181,136 +189,140 @@ class ConfigurationPropertiesReportEndpointTests {
|
||||
String configSize = "1MB";
|
||||
String stringifySize = DataSize.parse(configSize).toString();
|
||||
this.contextRunner.withUserConfiguration(DataSizePropertiesConfiguration.class)
|
||||
.withPropertyValues(String.format("data.size=%s", configSize)).run(assertProperties("data",
|
||||
(properties) -> assertThat(properties.get("size")).isEqualTo(stringifySize), (inputs) -> {
|
||||
Map<String, Object> size = (Map<String, Object>) inputs.get("size");
|
||||
assertThat(size).containsEntry("value", configSize);
|
||||
assertThat(size).containsEntry("origin", "\"data.size\" from property source \"test\"");
|
||||
}));
|
||||
.withPropertyValues(String.format("data.size=%s", configSize))
|
||||
.run(assertProperties("data", (properties) -> assertThat(properties.get("size")).isEqualTo(stringifySize),
|
||||
(inputs) -> {
|
||||
Map<String, Object> size = (Map<String, Object>) inputs.get("size");
|
||||
assertThat(size).containsEntry("value", configSize);
|
||||
assertThat(size).containsEntry("origin", "\"data.size\" from property source \"test\"");
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void sanitizeLists() {
|
||||
new ApplicationContextRunner()
|
||||
.withUserConfiguration(EndpointConfigWithShowNever.class, SensiblePropertiesConfiguration.class)
|
||||
.withPropertyValues("sensible.listItems[0].some-password=password")
|
||||
.run(assertProperties("sensible", (properties) -> {
|
||||
assertThat(properties.get("listItems")).isInstanceOf(List.class);
|
||||
List<Object> list = (List<Object>) properties.get("listItems");
|
||||
assertThat(list).hasSize(1);
|
||||
Map<String, Object> item = (Map<String, Object>) list.get(0);
|
||||
assertThat(item).containsEntry("somePassword", "******");
|
||||
}, (inputs) -> {
|
||||
List<Object> list = (List<Object>) inputs.get("listItems");
|
||||
assertThat(list).hasSize(1);
|
||||
Map<String, Object> item = (Map<String, Object>) list.get(0);
|
||||
Map<String, Object> somePassword = (Map<String, Object>) item.get("somePassword");
|
||||
assertThat(somePassword).containsEntry("value", "******");
|
||||
assertThat(somePassword).containsEntry("origin",
|
||||
"\"sensible.listItems[0].some-password\" from property source \"test\"");
|
||||
}));
|
||||
.withUserConfiguration(EndpointConfigWithShowNever.class, SensiblePropertiesConfiguration.class)
|
||||
.withPropertyValues("sensible.listItems[0].some-password=password")
|
||||
.run(assertProperties("sensible", (properties) -> {
|
||||
assertThat(properties.get("listItems")).isInstanceOf(List.class);
|
||||
List<Object> list = (List<Object>) properties.get("listItems");
|
||||
assertThat(list).hasSize(1);
|
||||
Map<String, Object> item = (Map<String, Object>) list.get(0);
|
||||
assertThat(item).containsEntry("somePassword", "******");
|
||||
}, (inputs) -> {
|
||||
List<Object> list = (List<Object>) inputs.get("listItems");
|
||||
assertThat(list).hasSize(1);
|
||||
Map<String, Object> item = (Map<String, Object>) list.get(0);
|
||||
Map<String, Object> somePassword = (Map<String, Object>) item.get("somePassword");
|
||||
assertThat(somePassword).containsEntry("value", "******");
|
||||
assertThat(somePassword).containsEntry("origin",
|
||||
"\"sensible.listItems[0].some-password\" from property source \"test\"");
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void listsOfListsAreSanitized() {
|
||||
new ApplicationContextRunner()
|
||||
.withUserConfiguration(EndpointConfigWithShowNever.class, SensiblePropertiesConfiguration.class)
|
||||
.withPropertyValues("sensible.listOfListItems[0][0].some-password=password")
|
||||
.run(assertProperties("sensible", (properties) -> {
|
||||
assertThat(properties.get("listOfListItems")).isInstanceOf(List.class);
|
||||
List<List<Object>> listOfLists = (List<List<Object>>) properties.get("listOfListItems");
|
||||
assertThat(listOfLists).hasSize(1);
|
||||
List<Object> list = listOfLists.get(0);
|
||||
assertThat(list).hasSize(1);
|
||||
Map<String, Object> item = (Map<String, Object>) list.get(0);
|
||||
assertThat(item).containsEntry("somePassword", "******");
|
||||
}, (inputs) -> {
|
||||
assertThat(inputs.get("listOfListItems")).isInstanceOf(List.class);
|
||||
List<List<Object>> listOfLists = (List<List<Object>>) inputs.get("listOfListItems");
|
||||
assertThat(listOfLists).hasSize(1);
|
||||
List<Object> list = listOfLists.get(0);
|
||||
assertThat(list).hasSize(1);
|
||||
Map<String, Object> item = (Map<String, Object>) list.get(0);
|
||||
Map<String, Object> somePassword = (Map<String, Object>) item.get("somePassword");
|
||||
assertThat(somePassword).containsEntry("value", "******");
|
||||
assertThat(somePassword).containsEntry("origin",
|
||||
"\"sensible.listOfListItems[0][0].some-password\" from property source \"test\"");
|
||||
}));
|
||||
.withUserConfiguration(EndpointConfigWithShowNever.class, SensiblePropertiesConfiguration.class)
|
||||
.withPropertyValues("sensible.listOfListItems[0][0].some-password=password")
|
||||
.run(assertProperties("sensible", (properties) -> {
|
||||
assertThat(properties.get("listOfListItems")).isInstanceOf(List.class);
|
||||
List<List<Object>> listOfLists = (List<List<Object>>) properties.get("listOfListItems");
|
||||
assertThat(listOfLists).hasSize(1);
|
||||
List<Object> list = listOfLists.get(0);
|
||||
assertThat(list).hasSize(1);
|
||||
Map<String, Object> item = (Map<String, Object>) list.get(0);
|
||||
assertThat(item).containsEntry("somePassword", "******");
|
||||
}, (inputs) -> {
|
||||
assertThat(inputs.get("listOfListItems")).isInstanceOf(List.class);
|
||||
List<List<Object>> listOfLists = (List<List<Object>>) inputs.get("listOfListItems");
|
||||
assertThat(listOfLists).hasSize(1);
|
||||
List<Object> list = listOfLists.get(0);
|
||||
assertThat(list).hasSize(1);
|
||||
Map<String, Object> item = (Map<String, Object>) list.get(0);
|
||||
Map<String, Object> somePassword = (Map<String, Object>) item.get("somePassword");
|
||||
assertThat(somePassword).containsEntry("value", "******");
|
||||
assertThat(somePassword).containsEntry("origin",
|
||||
"\"sensible.listOfListItems[0][0].some-password\" from property source \"test\"");
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void sanitizeWithCustomSanitizingFunction() {
|
||||
new ApplicationContextRunner().withUserConfiguration(CustomSanitizingEndpointConfig.class,
|
||||
SanitizingFunctionConfiguration.class, TestPropertiesConfiguration.class)
|
||||
.run(assertProperties("test", (properties) -> {
|
||||
assertThat(properties).containsEntry("dbPassword", "$$$");
|
||||
assertThat(properties).containsEntry("myTestProperty", "$$$");
|
||||
}));
|
||||
new ApplicationContextRunner()
|
||||
.withUserConfiguration(CustomSanitizingEndpointConfig.class, SanitizingFunctionConfiguration.class,
|
||||
TestPropertiesConfiguration.class)
|
||||
.run(assertProperties("test", (properties) -> {
|
||||
assertThat(properties).containsEntry("dbPassword", "$$$");
|
||||
assertThat(properties).containsEntry("myTestProperty", "$$$");
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void sanitizeWithCustomPropertySourceBasedSanitizingFunction() {
|
||||
new ApplicationContextRunner()
|
||||
.withUserConfiguration(CustomSanitizingEndpointConfig.class,
|
||||
PropertySourceBasedSanitizingFunctionConfiguration.class, TestPropertiesConfiguration.class)
|
||||
.withPropertyValues("test.my-test-property=abcde").run(assertProperties("test", (properties) -> {
|
||||
assertThat(properties).containsEntry("dbPassword", "123456");
|
||||
assertThat(properties).containsEntry("myTestProperty", "$$$");
|
||||
}));
|
||||
.withUserConfiguration(CustomSanitizingEndpointConfig.class,
|
||||
PropertySourceBasedSanitizingFunctionConfiguration.class, TestPropertiesConfiguration.class)
|
||||
.withPropertyValues("test.my-test-property=abcde")
|
||||
.run(assertProperties("test", (properties) -> {
|
||||
assertThat(properties).containsEntry("dbPassword", "123456");
|
||||
assertThat(properties).containsEntry("myTestProperty", "$$$");
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void sanitizeListsWithCustomSanitizingFunction() {
|
||||
new ApplicationContextRunner()
|
||||
.withUserConfiguration(CustomSanitizingEndpointConfig.class, SanitizingFunctionConfiguration.class,
|
||||
SensiblePropertiesConfiguration.class)
|
||||
.withPropertyValues("sensible.listItems[0].custom=my-value")
|
||||
.run(assertProperties("sensible", (properties) -> {
|
||||
assertThat(properties.get("listItems")).isInstanceOf(List.class);
|
||||
List<Object> list = (List<Object>) properties.get("listItems");
|
||||
assertThat(list).hasSize(1);
|
||||
Map<String, Object> item = (Map<String, Object>) list.get(0);
|
||||
assertThat(item).containsEntry("custom", "$$$");
|
||||
}, (inputs) -> {
|
||||
List<Object> list = (List<Object>) inputs.get("listItems");
|
||||
assertThat(list).hasSize(1);
|
||||
Map<String, Object> item = (Map<String, Object>) list.get(0);
|
||||
Map<String, Object> somePassword = (Map<String, Object>) item.get("custom");
|
||||
assertThat(somePassword).containsEntry("value", "$$$");
|
||||
assertThat(somePassword).containsEntry("origin",
|
||||
"\"sensible.listItems[0].custom\" from property source \"test\"");
|
||||
}));
|
||||
.withUserConfiguration(CustomSanitizingEndpointConfig.class, SanitizingFunctionConfiguration.class,
|
||||
SensiblePropertiesConfiguration.class)
|
||||
.withPropertyValues("sensible.listItems[0].custom=my-value")
|
||||
.run(assertProperties("sensible", (properties) -> {
|
||||
assertThat(properties.get("listItems")).isInstanceOf(List.class);
|
||||
List<Object> list = (List<Object>) properties.get("listItems");
|
||||
assertThat(list).hasSize(1);
|
||||
Map<String, Object> item = (Map<String, Object>) list.get(0);
|
||||
assertThat(item).containsEntry("custom", "$$$");
|
||||
}, (inputs) -> {
|
||||
List<Object> list = (List<Object>) inputs.get("listItems");
|
||||
assertThat(list).hasSize(1);
|
||||
Map<String, Object> item = (Map<String, Object>) list.get(0);
|
||||
Map<String, Object> somePassword = (Map<String, Object>) item.get("custom");
|
||||
assertThat(somePassword).containsEntry("value", "$$$");
|
||||
assertThat(somePassword).containsEntry("origin",
|
||||
"\"sensible.listItems[0].custom\" from property source \"test\"");
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void noSanitizationWhenShowAlways() {
|
||||
new ApplicationContextRunner()
|
||||
.withUserConfiguration(EndpointConfigWithShowAlways.class, TestPropertiesConfiguration.class)
|
||||
.run(assertProperties("test", (properties) -> {
|
||||
assertThat(properties).containsEntry("dbPassword", "123456");
|
||||
assertThat(properties).containsEntry("myTestProperty", "654321");
|
||||
}));
|
||||
.withUserConfiguration(EndpointConfigWithShowAlways.class, TestPropertiesConfiguration.class)
|
||||
.run(assertProperties("test", (properties) -> {
|
||||
assertThat(properties).containsEntry("dbPassword", "123456");
|
||||
assertThat(properties).containsEntry("myTestProperty", "654321");
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void sanitizationWhenShowNever() {
|
||||
new ApplicationContextRunner()
|
||||
.withUserConfiguration(EndpointConfigWithShowNever.class, TestPropertiesConfiguration.class)
|
||||
.run(assertProperties("test", (properties) -> {
|
||||
assertThat(properties).containsEntry("dbPassword", "******");
|
||||
assertThat(properties).containsEntry("myTestProperty", "******");
|
||||
}));
|
||||
.withUserConfiguration(EndpointConfigWithShowNever.class, TestPropertiesConfiguration.class)
|
||||
.run(assertProperties("test", (properties) -> {
|
||||
assertThat(properties).containsEntry("dbPassword", "******");
|
||||
assertThat(properties).containsEntry("myTestProperty", "******");
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void originParents() {
|
||||
this.contextRunner.withUserConfiguration(SensiblePropertiesConfiguration.class)
|
||||
.withInitializer(this::initializeOriginParents).run(assertProperties("sensible", (properties) -> {
|
||||
}, (inputs) -> {
|
||||
Map<String, Object> stringInputs = (Map<String, Object>) inputs.get("string");
|
||||
String[] originParents = (String[]) stringInputs.get("originParents");
|
||||
assertThat(originParents).containsExactly("spring", "boot");
|
||||
}));
|
||||
.withInitializer(this::initializeOriginParents)
|
||||
.run(assertProperties("sensible", (properties) -> {
|
||||
}, (inputs) -> {
|
||||
Map<String, Object> stringInputs = (Map<String, Object>) inputs.get("string");
|
||||
String[] originParents = (String[]) stringInputs.get("originParents");
|
||||
assertThat(originParents).containsExactly("spring", "boot");
|
||||
}));
|
||||
}
|
||||
|
||||
private void initializeOriginParents(ConfigurableApplicationContext context) {
|
||||
@@ -329,13 +341,16 @@ class ConfigurationPropertiesReportEndpointTests {
|
||||
Consumer<Map<String, Object>> properties, Consumer<Map<String, Object>> inputs) {
|
||||
return (context) -> {
|
||||
ConfigurationPropertiesReportEndpoint endpoint = context
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
.getBean(ConfigurationPropertiesReportEndpoint.class);
|
||||
ConfigurationPropertiesReportEndpoint.ConfigurationPropertiesDescriptor configurationProperties = endpoint
|
||||
.configurationProperties();
|
||||
.configurationProperties();
|
||||
ContextConfigurationPropertiesDescriptor allProperties = configurationProperties.getContexts()
|
||||
.get(context.getId());
|
||||
Optional<String> key = allProperties.getBeans().keySet().stream()
|
||||
.filter((id) -> findIdFromPrefix(prefix, id)).findAny();
|
||||
.get(context.getId());
|
||||
Optional<String> key = allProperties.getBeans()
|
||||
.keySet()
|
||||
.stream()
|
||||
.filter((id) -> findIdFromPrefix(prefix, id))
|
||||
.findAny();
|
||||
assertThat(key).describedAs("No configuration properties with prefix '%s' found", prefix).isPresent();
|
||||
ConfigurationPropertiesBeanDescriptor descriptor = allProperties.getBeans().get(key.get());
|
||||
assertThat(descriptor.getPrefix()).isEqualTo(prefix);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -88,7 +88,7 @@ class ConfigurationPropertiesReportEndpointWebExtensionTests {
|
||||
|
||||
private void verifyPrefixed(SecurityContext securityContext, boolean showUnsanitized) {
|
||||
given(this.delegate.getConfigurationProperties("test", showUnsanitized))
|
||||
.willReturn(new ConfigurationPropertiesDescriptor(Collections.emptyMap()));
|
||||
.willReturn(new ConfigurationPropertiesDescriptor(Collections.emptyMap()));
|
||||
this.webExtension.configurationPropertiesWithPrefix(securityContext, "test");
|
||||
then(this.delegate).should().getConfigurationProperties("test", showUnsanitized);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -51,22 +51,48 @@ class ConfigurationPropertiesReportEndpointWebIntegrationTests {
|
||||
|
||||
@WebEndpointTest
|
||||
void noFilters() {
|
||||
this.client.get().uri("/actuator/configprops").exchange().expectStatus().isOk().expectBody()
|
||||
.jsonPath("$..beans[*]").value(hasSize(greaterThanOrEqualTo(2))).jsonPath("$..beans['fooDotCom']")
|
||||
.exists().jsonPath("$..beans['barDotCom']").exists();
|
||||
this.client.get()
|
||||
.uri("/actuator/configprops")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody()
|
||||
.jsonPath("$..beans[*]")
|
||||
.value(hasSize(greaterThanOrEqualTo(2)))
|
||||
.jsonPath("$..beans['fooDotCom']")
|
||||
.exists()
|
||||
.jsonPath("$..beans['barDotCom']")
|
||||
.exists();
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void filterByExactPrefix() {
|
||||
this.client.get().uri("/actuator/configprops/com.foo").exchange().expectStatus().isOk().expectBody()
|
||||
.jsonPath("$..beans[*]").value(hasSize(1)).jsonPath("$..beans['fooDotCom']").exists();
|
||||
this.client.get()
|
||||
.uri("/actuator/configprops/com.foo")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody()
|
||||
.jsonPath("$..beans[*]")
|
||||
.value(hasSize(1))
|
||||
.jsonPath("$..beans['fooDotCom']")
|
||||
.exists();
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void filterByGeneralPrefix() {
|
||||
this.client.get().uri("/actuator/configprops/com.").exchange().expectStatus().isOk().expectBody()
|
||||
.jsonPath("$..beans[*]").value(hasSize(2)).jsonPath("$..beans['fooDotCom']").exists()
|
||||
.jsonPath("$..beans['barDotCom']").exists();
|
||||
this.client.get()
|
||||
.uri("/actuator/configprops/com.")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody()
|
||||
.jsonPath("$..beans[*]")
|
||||
.value(hasSize(2))
|
||||
.jsonPath("$..beans['fooDotCom']")
|
||||
.exists()
|
||||
.jsonPath("$..beans['barDotCom']")
|
||||
.exists();
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -121,8 +121,8 @@ class ElasticsearchReactiveHealthIndicatorTests {
|
||||
|
||||
private void setupMockResponse(int responseCode, String status) {
|
||||
MockResponse mockResponse = new MockResponse().setBody(createJsonResult(status))
|
||||
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
|
||||
.setHeader("X-Elastic-Product", "Elasticsearch");
|
||||
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
|
||||
.setHeader("X-Elastic-Product", "Elasticsearch");
|
||||
this.server.enqueue(mockResponse);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class EndpointIdTests {
|
||||
@Test
|
||||
void ofWhenNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> EndpointId.of(null))
|
||||
.withMessage("Value must not be empty");
|
||||
.withMessage("Value must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -48,31 +48,31 @@ class EndpointIdTests {
|
||||
@Test
|
||||
void ofWhenContainsSlashThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> EndpointId.of("foo/bar"))
|
||||
.withMessage("Value must only contain valid chars");
|
||||
.withMessage("Value must only contain valid chars");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenContainsBackslashThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> EndpointId.of("foo\\bar"))
|
||||
.withMessage("Value must only contain valid chars");
|
||||
.withMessage("Value must only contain valid chars");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenHasBadCharThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> EndpointId.of("foo!bar"))
|
||||
.withMessage("Value must only contain valid chars");
|
||||
.withMessage("Value must only contain valid chars");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenStartsWithNumberThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> EndpointId.of("1foo"))
|
||||
.withMessage("Value must not start with a number");
|
||||
.withMessage("Value must not start with a number");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenStartsWithUppercaseLetterThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> EndpointId.of("Foo"))
|
||||
.withMessage("Value must not start with an uppercase letter");
|
||||
.withMessage("Value must not start with an uppercase letter");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -96,7 +96,7 @@ class EndpointIdTests {
|
||||
EndpointId.resetLoggedWarnings();
|
||||
EndpointId.of("foo-bar");
|
||||
assertThat(output)
|
||||
.contains("Endpoint ID 'foo-bar' contains invalid characters, please migrate to a valid format");
|
||||
.contains("Endpoint ID 'foo-bar' contains invalid characters, please migrate to a valid format");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -136,8 +136,12 @@ class EndpointIdTests {
|
||||
EndpointId five = EndpointId.of("barfoo1");
|
||||
EndpointId six = EndpointId.of("foobar2");
|
||||
assertThat(one).hasSameHashCodeAs(two);
|
||||
assertThat(one).isEqualTo(one).isEqualTo(two).isEqualTo(three).isEqualTo(four).isNotEqualTo(five)
|
||||
.isNotEqualTo(six);
|
||||
assertThat(one).isEqualTo(one)
|
||||
.isEqualTo(two)
|
||||
.isEqualTo(three)
|
||||
.isEqualTo(four)
|
||||
.isNotEqualTo(five)
|
||||
.isNotEqualTo(six);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,13 +45,13 @@ class InvocationContextTests {
|
||||
@Test
|
||||
void createWhenSecurityContextIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new InvocationContext(null, this.arguments))
|
||||
.withMessage("SecurityContext must not be null");
|
||||
.withMessage("SecurityContext must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenArgumentsIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new InvocationContext(this.securityContext, null))
|
||||
.withMessage("Arguments must not be null");
|
||||
.withMessage("Arguments must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -67,9 +67,9 @@ class ProducibleOperationArgumentResolverTests {
|
||||
@Test
|
||||
void whenSingleValueIsAcceptableThenMatchingEnumValueIsReturned() {
|
||||
assertThat(new ProducibleOperationArgumentResolver(acceptHeader(V2_JSON)).resolve(ApiVersion.class))
|
||||
.isEqualTo(ApiVersion.V2);
|
||||
.isEqualTo(ApiVersion.V2);
|
||||
assertThat(new ProducibleOperationArgumentResolver(acceptHeader(V3_JSON)).resolve(ApiVersion.class))
|
||||
.isEqualTo(ApiVersion.V3);
|
||||
.isEqualTo(ApiVersion.V3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,7 +90,7 @@ class ProducibleOperationArgumentResolverTests {
|
||||
@Test
|
||||
void whenMultipleDefaultsThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> resolve(acceptHeader("one/one"), WithMultipleDefaults.class))
|
||||
.withMessageContaining("Multiple default values");
|
||||
.withMessageContaining("Multiple default values");
|
||||
}
|
||||
|
||||
private Supplier<List<String>> acceptHeader(String... types) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -91,7 +91,7 @@ class ShowTests {
|
||||
Authentication authentication = mock(Authentication.class);
|
||||
given(securityContext.getPrincipal()).willReturn(authentication);
|
||||
given(authentication.getAuthorities())
|
||||
.willAnswer((invocation) -> Collections.singleton(new SimpleGrantedAuthority("other")));
|
||||
.willAnswer((invocation) -> Collections.singleton(new SimpleGrantedAuthority("other")));
|
||||
assertThat(Show.WHEN_AUTHORIZED.isShown(securityContext, Collections.singleton("admin"))).isFalse();
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ class ShowTests {
|
||||
Authentication authentication = mock(Authentication.class);
|
||||
given(securityContext.getPrincipal()).willReturn(authentication);
|
||||
given(authentication.getAuthorities())
|
||||
.willAnswer((invocation) -> Collections.singleton(new SimpleGrantedAuthority("admin")));
|
||||
.willAnswer((invocation) -> Collections.singleton(new SimpleGrantedAuthority("admin")));
|
||||
assertThat(Show.WHEN_AUTHORIZED.isShown(securityContext, Collections.singleton("admin"))).isTrue();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,8 +40,8 @@ class DiscoveredOperationMethodTests {
|
||||
void createWhenAnnotationAttributesIsNullShouldThrowException() {
|
||||
Method method = ReflectionUtils.findMethod(getClass(), "example");
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new DiscoveredOperationMethod(method, OperationType.READ, null))
|
||||
.withMessageContaining("AnnotationAttributes must not be null");
|
||||
.isThrownBy(() -> new DiscoveredOperationMethod(method, OperationType.READ, null))
|
||||
.withMessageContaining("AnnotationAttributes must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,7 +42,7 @@ class DiscovererEndpointFilterTests {
|
||||
@Test
|
||||
void createWhenDiscovererIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new TestDiscovererEndpointFilter(null))
|
||||
.withMessageContaining("Discoverer must not be null");
|
||||
.withMessageContaining("Discoverer must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -71,33 +71,33 @@ class EndpointDiscovererTests {
|
||||
@Test
|
||||
void createWhenApplicationContextIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new TestEndpointDiscoverer(null, mock(ParameterValueMapper.class),
|
||||
Collections.emptyList(), Collections.emptyList()))
|
||||
.withMessageContaining("ApplicationContext must not be null");
|
||||
.isThrownBy(() -> new TestEndpointDiscoverer(null, mock(ParameterValueMapper.class),
|
||||
Collections.emptyList(), Collections.emptyList()))
|
||||
.withMessageContaining("ApplicationContext must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenParameterValueMapperIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new TestEndpointDiscoverer(mock(ApplicationContext.class), null,
|
||||
Collections.emptyList(), Collections.emptyList()))
|
||||
.withMessageContaining("ParameterValueMapper must not be null");
|
||||
.isThrownBy(() -> new TestEndpointDiscoverer(mock(ApplicationContext.class), null, Collections.emptyList(),
|
||||
Collections.emptyList()))
|
||||
.withMessageContaining("ParameterValueMapper must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenInvokerAdvisorsIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new TestEndpointDiscoverer(mock(ApplicationContext.class),
|
||||
mock(ParameterValueMapper.class), null, Collections.emptyList()))
|
||||
.withMessageContaining("InvokerAdvisors must not be null");
|
||||
.isThrownBy(() -> new TestEndpointDiscoverer(mock(ApplicationContext.class),
|
||||
mock(ParameterValueMapper.class), null, Collections.emptyList()))
|
||||
.withMessageContaining("InvokerAdvisors must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenFiltersIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new TestEndpointDiscoverer(mock(ApplicationContext.class),
|
||||
mock(ParameterValueMapper.class), Collections.emptyList(), null))
|
||||
.withMessageContaining("Filters must not be null");
|
||||
.isThrownBy(() -> new TestEndpointDiscoverer(mock(ApplicationContext.class),
|
||||
mock(ParameterValueMapper.class), Collections.emptyList(), null))
|
||||
.withMessageContaining("Filters must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -139,8 +139,8 @@ class EndpointDiscovererTests {
|
||||
void getEndpointsWhenTwoEndpointsHaveTheSameIdShouldThrowException() {
|
||||
load(ClashingEndpointConfiguration.class,
|
||||
(context) -> assertThatIllegalStateException()
|
||||
.isThrownBy(new TestEndpointDiscoverer(context)::getEndpoints)
|
||||
.withMessageContaining("Found two endpoints with the id 'test': "));
|
||||
.isThrownBy(new TestEndpointDiscoverer(context)::getEndpoints)
|
||||
.withMessageContaining("Found two endpoints with the id 'test': "));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -159,8 +159,9 @@ class EndpointDiscovererTests {
|
||||
Map<EndpointId, TestExposableEndpoint> endpoints = mapEndpoints(discoverer.getEndpoints());
|
||||
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||
Map<Method, TestOperation> operations = mapOperations(endpoints.get(EndpointId.of("test")));
|
||||
operations.values().forEach(
|
||||
(operation) -> assertThat(operation.getInvoker()).isNotInstanceOf(CachingOperationInvoker.class));
|
||||
operations.values()
|
||||
.forEach((operation) -> assertThat(operation.getInvoker())
|
||||
.isNotInstanceOf(CachingOperationInvoker.class));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -172,8 +173,9 @@ class EndpointDiscovererTests {
|
||||
Map<EndpointId, TestExposableEndpoint> endpoints = mapEndpoints(discoverer.getEndpoints());
|
||||
assertThat(endpoints).containsOnlyKeys(EndpointId.of("test"));
|
||||
Map<Method, TestOperation> operations = mapOperations(endpoints.get(EndpointId.of("test")));
|
||||
operations.values().forEach(
|
||||
(operation) -> assertThat(operation.getInvoker()).isNotInstanceOf(CachingOperationInvoker.class));
|
||||
operations.values()
|
||||
.forEach((operation) -> assertThat(operation.getInvoker())
|
||||
.isNotInstanceOf(CachingOperationInvoker.class));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -188,7 +190,7 @@ class EndpointDiscovererTests {
|
||||
TestOperation getAll = operations.get(findTestEndpointMethod("getAll"));
|
||||
TestOperation getOne = operations.get(findTestEndpointMethod("getOne", String.class));
|
||||
TestOperation update = operations
|
||||
.get(ReflectionUtils.findMethod(TestEndpoint.class, "update", String.class, String.class));
|
||||
.get(ReflectionUtils.findMethod(TestEndpoint.class, "update", String.class, String.class));
|
||||
assertThat(((CachingOperationInvoker) getAll.getInvoker()).getTimeToLive()).isEqualTo(500);
|
||||
assertThat(getOne.getInvoker()).isNotInstanceOf(CachingOperationInvoker.class);
|
||||
assertThat(update.getInvoker()).isNotInstanceOf(CachingOperationInvoker.class);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -80,12 +80,14 @@ class OperationReflectiveProcessorTests {
|
||||
}
|
||||
|
||||
private void assertHintsForDto() {
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(Dto.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS))
|
||||
.accepts(this.runtimeHints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(NestedDto.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS))
|
||||
.accepts(this.runtimeHints);
|
||||
assertThat(RuntimeHintsPredicates.reflection()
|
||||
.onType(Dto.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS))
|
||||
.accepts(this.runtimeHints);
|
||||
assertThat(RuntimeHintsPredicates.reflection()
|
||||
.onType(NestedDto.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS))
|
||||
.accepts(this.runtimeHints);
|
||||
}
|
||||
|
||||
private void runProcessor(Method method) {
|
||||
|
||||
@@ -58,12 +58,12 @@ class ConversionServiceParameterValueMapperTests {
|
||||
given(conversionService.convert(any(), any())).willThrow(error);
|
||||
ConversionServiceParameterValueMapper mapper = new ConversionServiceParameterValueMapper(conversionService);
|
||||
assertThatExceptionOfType(ParameterMappingException.class)
|
||||
.isThrownBy(() -> mapper.mapParameterValue(new TestOperationParameter(Integer.class), "123"))
|
||||
.satisfies((ex) -> {
|
||||
assertThat(ex.getValue()).isEqualTo("123");
|
||||
assertThat(ex.getParameter().getType()).isEqualTo(Integer.class);
|
||||
assertThat(ex.getCause()).isEqualTo(error);
|
||||
});
|
||||
.isThrownBy(() -> mapper.mapParameterValue(new TestOperationParameter(Integer.class), "123"))
|
||||
.satisfies((ex) -> {
|
||||
assertThat(ex.getValue()).isEqualTo("123");
|
||||
assertThat(ex.getParameter().getType()).isEqualTo(Integer.class);
|
||||
assertThat(ex.getCause()).isEqualTo(error);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -79,7 +79,7 @@ class ConversionServiceParameterValueMapperTests {
|
||||
ConversionService conversionService = new DefaultConversionService();
|
||||
ConversionServiceParameterValueMapper mapper = new ConversionServiceParameterValueMapper(conversionService);
|
||||
assertThatExceptionOfType(ParameterMappingException.class).isThrownBy(() -> mapper
|
||||
.mapParameterValue(new TestOperationParameter(OffsetDateTime.class), "2011-12-03T10:15:30+01:00"));
|
||||
.mapParameterValue(new TestOperationParameter(OffsetDateTime.class), "2011-12-03T10:15:30+01:00"));
|
||||
}
|
||||
|
||||
static class TestOperationParameter implements OperationParameter {
|
||||
|
||||
@@ -50,22 +50,21 @@ class OperationMethodParametersTests {
|
||||
@Test
|
||||
void createWhenMethodIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new OperationMethodParameters(null, mock(ParameterNameDiscoverer.class)))
|
||||
.withMessageContaining("Method must not be null");
|
||||
.isThrownBy(() -> new OperationMethodParameters(null, mock(ParameterNameDiscoverer.class)))
|
||||
.withMessageContaining("Method must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenParameterNameDiscovererIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new OperationMethodParameters(this.exampleMethod, null))
|
||||
.withMessageContaining("ParameterNameDiscoverer must not be null");
|
||||
.withMessageContaining("ParameterNameDiscoverer must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenParameterNameDiscovererReturnsNullShouldThrowException() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(
|
||||
() -> new OperationMethodParameters(this.exampleMethod, mock(ParameterNameDiscoverer.class)))
|
||||
.withMessageContaining("Failed to extract parameter names");
|
||||
.isThrownBy(() -> new OperationMethodParameters(this.exampleMethod, mock(ParameterNameDiscoverer.class)))
|
||||
.withMessageContaining("Failed to extract parameter names");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -39,13 +39,13 @@ class OperationMethodTests {
|
||||
@Test
|
||||
void createWhenMethodIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new OperationMethod(null, OperationType.READ))
|
||||
.withMessageContaining("Method must not be null");
|
||||
.withMessageContaining("Method must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenOperationTypeIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new OperationMethod(this.exampleMethod, null))
|
||||
.withMessageContaining("OperationType must not be null");
|
||||
.withMessageContaining("OperationType must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -59,22 +59,22 @@ class ReflectiveOperationInvokerTests {
|
||||
@Test
|
||||
void createWhenTargetIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ReflectiveOperationInvoker(null, this.operationMethod, this.parameterValueMapper))
|
||||
.withMessageContaining("Target must not be null");
|
||||
.isThrownBy(() -> new ReflectiveOperationInvoker(null, this.operationMethod, this.parameterValueMapper))
|
||||
.withMessageContaining("Target must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenOperationMethodIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ReflectiveOperationInvoker(this.target, null, this.parameterValueMapper))
|
||||
.withMessageContaining("OperationMethod must not be null");
|
||||
.isThrownBy(() -> new ReflectiveOperationInvoker(this.target, null, this.parameterValueMapper))
|
||||
.withMessageContaining("OperationMethod must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenParameterValueMapperIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ReflectiveOperationInvoker(this.target, this.operationMethod, null))
|
||||
.withMessageContaining("ParameterValueMapper must not be null");
|
||||
.isThrownBy(() -> new ReflectiveOperationInvoker(this.target, this.operationMethod, null))
|
||||
.withMessageContaining("ParameterValueMapper must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -82,7 +82,7 @@ class ReflectiveOperationInvokerTests {
|
||||
ReflectiveOperationInvoker invoker = new ReflectiveOperationInvoker(this.target, this.operationMethod,
|
||||
this.parameterValueMapper);
|
||||
Object result = invoker
|
||||
.invoke(new InvocationContext(mock(SecurityContext.class), Collections.singletonMap("name", "boot")));
|
||||
.invoke(new InvocationContext(mock(SecurityContext.class), Collections.singletonMap("name", "boot")));
|
||||
assertThat(result).isEqualTo("toob");
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ class ReflectiveOperationInvokerTests {
|
||||
ReflectiveOperationInvoker invoker = new ReflectiveOperationInvoker(this.target, this.operationMethod,
|
||||
this.parameterValueMapper);
|
||||
assertThatExceptionOfType(MissingParametersException.class).isThrownBy(() -> invoker
|
||||
.invoke(new InvocationContext(mock(SecurityContext.class), Collections.singletonMap("name", null))));
|
||||
.invoke(new InvocationContext(mock(SecurityContext.class), Collections.singletonMap("name", null))));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -101,7 +101,7 @@ class ReflectiveOperationInvokerTests {
|
||||
ReflectiveOperationInvoker invoker = new ReflectiveOperationInvoker(this.target, operationMethod,
|
||||
this.parameterValueMapper);
|
||||
Object result = invoker
|
||||
.invoke(new InvocationContext(mock(SecurityContext.class), Collections.singletonMap("name", null)));
|
||||
.invoke(new InvocationContext(mock(SecurityContext.class), Collections.singletonMap("name", null)));
|
||||
assertThat(result).isEqualTo("llun");
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ class ReflectiveOperationInvokerTests {
|
||||
ReflectiveOperationInvoker invoker = new ReflectiveOperationInvoker(this.target, this.operationMethod,
|
||||
this.parameterValueMapper);
|
||||
Object result = invoker
|
||||
.invoke(new InvocationContext(mock(SecurityContext.class), Collections.singletonMap("name", 1234)));
|
||||
.invoke(new InvocationContext(mock(SecurityContext.class), Collections.singletonMap("name", 1234)));
|
||||
assertThat(result).isEqualTo("4321");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,8 +57,8 @@ class CachingOperationInvokerTests {
|
||||
@Test
|
||||
void createInstanceWithTtlSetToZero() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new CachingOperationInvoker(mock(OperationInvoker.class), 0))
|
||||
.withMessageContaining("TimeToLive");
|
||||
.isThrownBy(() -> new CachingOperationInvoker(mock(OperationInvoker.class), 0))
|
||||
.withMessageContaining("TimeToLive");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -61,15 +61,15 @@ class EndpointMBeanTests {
|
||||
@Test
|
||||
void createWhenResponseMapperIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new EndpointMBean(null, null, mock(ExposableJmxEndpoint.class)))
|
||||
.withMessageContaining("ResponseMapper must not be null");
|
||||
.isThrownBy(() -> new EndpointMBean(null, null, mock(ExposableJmxEndpoint.class)))
|
||||
.withMessageContaining("ResponseMapper must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenEndpointIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new EndpointMBean(mock(JmxOperationResponseMapper.class), null, null))
|
||||
.withMessageContaining("Endpoint must not be null");
|
||||
.isThrownBy(() -> new EndpointMBean(mock(JmxOperationResponseMapper.class), null, null))
|
||||
.withMessageContaining("Endpoint must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -93,8 +93,9 @@ class EndpointMBeanTests {
|
||||
}));
|
||||
EndpointMBean bean = new EndpointMBean(this.responseMapper, null, endpoint);
|
||||
assertThatExceptionOfType(MBeanException.class)
|
||||
.isThrownBy(() -> bean.invoke("testOperation", NO_PARAMS, NO_SIGNATURE))
|
||||
.withCauseInstanceOf(IllegalStateException.class).withMessageContaining("test failure");
|
||||
.isThrownBy(() -> bean.invoke("testOperation", NO_PARAMS, NO_SIGNATURE))
|
||||
.withCauseInstanceOf(IllegalStateException.class)
|
||||
.withMessageContaining("test failure");
|
||||
|
||||
}
|
||||
|
||||
@@ -105,17 +106,18 @@ class EndpointMBeanTests {
|
||||
}));
|
||||
EndpointMBean bean = new EndpointMBean(this.responseMapper, null, endpoint);
|
||||
assertThatExceptionOfType(MBeanException.class)
|
||||
.isThrownBy(() -> bean.invoke("testOperation", NO_PARAMS, NO_SIGNATURE))
|
||||
.withCauseInstanceOf(UnsupportedOperationException.class).withMessageContaining("test failure");
|
||||
.isThrownBy(() -> bean.invoke("testOperation", NO_PARAMS, NO_SIGNATURE))
|
||||
.withCauseInstanceOf(UnsupportedOperationException.class)
|
||||
.withMessageContaining("test failure");
|
||||
}
|
||||
|
||||
@Test
|
||||
void invokeWhenActionNameIsNotAnOperationShouldThrowException() {
|
||||
EndpointMBean bean = createEndpointMBean();
|
||||
assertThatExceptionOfType(ReflectionException.class)
|
||||
.isThrownBy(() -> bean.invoke("missingOperation", NO_PARAMS, NO_SIGNATURE))
|
||||
.withCauseInstanceOf(IllegalArgumentException.class)
|
||||
.withMessageContaining("no operation named missingOperation");
|
||||
.isThrownBy(() -> bean.invoke("missingOperation", NO_PARAMS, NO_SIGNATURE))
|
||||
.withCauseInstanceOf(IllegalArgumentException.class)
|
||||
.withMessageContaining("no operation named missingOperation");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -143,8 +145,9 @@ class EndpointMBeanTests {
|
||||
TestExposableJmxEndpoint endpoint = new TestExposableJmxEndpoint(operation);
|
||||
EndpointMBean bean = new EndpointMBean(this.responseMapper, null, endpoint);
|
||||
assertThatExceptionOfType(ReflectionException.class)
|
||||
.isThrownBy(() -> bean.invoke("testOperation", NO_PARAMS, NO_SIGNATURE))
|
||||
.withRootCauseInstanceOf(IllegalArgumentException.class).withMessageContaining("test failure");
|
||||
.isThrownBy(() -> bean.invoke("testOperation", NO_PARAMS, NO_SIGNATURE))
|
||||
.withRootCauseInstanceOf(IllegalArgumentException.class)
|
||||
.withMessageContaining("test failure");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -178,15 +181,15 @@ class EndpointMBeanTests {
|
||||
void getAttributeShouldThrowException() {
|
||||
EndpointMBean bean = createEndpointMBean();
|
||||
assertThatExceptionOfType(AttributeNotFoundException.class).isThrownBy(() -> bean.getAttribute("test"))
|
||||
.withMessageContaining("EndpointMBeans do not support attributes");
|
||||
.withMessageContaining("EndpointMBeans do not support attributes");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setAttributeShouldThrowException() {
|
||||
EndpointMBean bean = createEndpointMBean();
|
||||
assertThatExceptionOfType(AttributeNotFoundException.class)
|
||||
.isThrownBy(() -> bean.setAttribute(new Attribute("test", "test")))
|
||||
.withMessageContaining("EndpointMBeans do not support attributes");
|
||||
.isThrownBy(() -> bean.setAttribute(new Attribute("test", "test")))
|
||||
.withMessageContaining("EndpointMBeans do not support attributes");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -81,31 +81,32 @@ class JmxEndpointExporterTests {
|
||||
|
||||
@Test
|
||||
void createWhenMBeanServerIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> new JmxEndpointExporter(null, this.objectNameFactory, this.responseMapper, this.endpoints))
|
||||
.withMessageContaining("MBeanServer must not be null");
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(
|
||||
() -> new JmxEndpointExporter(null, this.objectNameFactory, this.responseMapper, this.endpoints))
|
||||
.withMessageContaining("MBeanServer must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenObjectNameFactoryIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new JmxEndpointExporter(this.mBeanServer, null, this.responseMapper, this.endpoints))
|
||||
.withMessageContaining("ObjectNameFactory must not be null");
|
||||
.isThrownBy(() -> new JmxEndpointExporter(this.mBeanServer, null, this.responseMapper, this.endpoints))
|
||||
.withMessageContaining("ObjectNameFactory must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenResponseMapperIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(
|
||||
() -> new JmxEndpointExporter(this.mBeanServer, this.objectNameFactory, null, this.endpoints))
|
||||
.withMessageContaining("ResponseMapper must not be null");
|
||||
.isThrownBy(() -> new JmxEndpointExporter(this.mBeanServer, this.objectNameFactory, null, this.endpoints))
|
||||
.withMessageContaining("ResponseMapper must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenEndpointsIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> new JmxEndpointExporter(this.mBeanServer, this.objectNameFactory, this.responseMapper, null))
|
||||
.withMessageContaining("Endpoints must not be null");
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(
|
||||
() -> new JmxEndpointExporter(this.mBeanServer, this.objectNameFactory, this.responseMapper, null))
|
||||
.withMessageContaining("Endpoints must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -127,19 +128,19 @@ class JmxEndpointExporterTests {
|
||||
@Test
|
||||
void registerWhenObjectNameIsMalformedShouldThrowException() throws Exception {
|
||||
given(this.objectNameFactory.getObjectName(any(ExposableJmxEndpoint.class)))
|
||||
.willThrow(MalformedObjectNameException.class);
|
||||
.willThrow(MalformedObjectNameException.class);
|
||||
this.endpoints.add(new TestExposableJmxEndpoint(new TestJmxOperation()));
|
||||
assertThatIllegalStateException().isThrownBy(this.exporter::afterPropertiesSet)
|
||||
.withMessageContaining("Invalid ObjectName for endpoint 'test'");
|
||||
.withMessageContaining("Invalid ObjectName for endpoint 'test'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerWhenRegistrationFailsShouldThrowException() throws Exception {
|
||||
given(this.mBeanServer.registerMBean(any(), any(ObjectName.class)))
|
||||
.willThrow(new MBeanRegistrationException(new RuntimeException()));
|
||||
.willThrow(new MBeanRegistrationException(new RuntimeException()));
|
||||
this.endpoints.add(new TestExposableJmxEndpoint(new TestJmxOperation()));
|
||||
assertThatExceptionOfType(MBeanExportException.class).isThrownBy(this.exporter::afterPropertiesSet)
|
||||
.withMessageContaining("Failed to register MBean for endpoint 'test");
|
||||
.withMessageContaining("Failed to register MBean for endpoint 'test");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -164,9 +165,9 @@ class JmxEndpointExporterTests {
|
||||
this.endpoints.add(new TestExposableJmxEndpoint(new TestJmxOperation()));
|
||||
this.exporter.afterPropertiesSet();
|
||||
willThrow(new MBeanRegistrationException(new RuntimeException())).given(this.mBeanServer)
|
||||
.unregisterMBean(any(ObjectName.class));
|
||||
.unregisterMBean(any(ObjectName.class));
|
||||
assertThatExceptionOfType(JmxException.class).isThrownBy(() -> this.exporter.destroy())
|
||||
.withMessageContaining("Failed to unregister MBean with ObjectName 'boot");
|
||||
.withMessageContaining("Failed to unregister MBean with ObjectName 'boot");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,21 +61,21 @@ class MBeanInfoFactoryTests {
|
||||
@Test
|
||||
void getMBeanInfoWhenReadOperationShouldHaveInfoImpact() {
|
||||
MBeanInfo info = this.factory
|
||||
.getMBeanInfo(new TestExposableJmxEndpoint(new TestJmxOperation(OperationType.READ)));
|
||||
.getMBeanInfo(new TestExposableJmxEndpoint(new TestJmxOperation(OperationType.READ)));
|
||||
assertThat(info.getOperations()[0].getImpact()).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMBeanInfoWhenWriteOperationShouldHaveActionImpact() {
|
||||
MBeanInfo info = this.factory
|
||||
.getMBeanInfo(new TestExposableJmxEndpoint(new TestJmxOperation(OperationType.WRITE)));
|
||||
.getMBeanInfo(new TestExposableJmxEndpoint(new TestJmxOperation(OperationType.WRITE)));
|
||||
assertThat(info.getOperations()[0].getImpact()).isOne();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMBeanInfoWhenDeleteOperationShouldHaveActionImpact() {
|
||||
MBeanInfo info = this.factory
|
||||
.getMBeanInfo(new TestExposableJmxEndpoint(new TestJmxOperation(OperationType.DELETE)));
|
||||
.getMBeanInfo(new TestExposableJmxEndpoint(new TestJmxOperation(OperationType.DELETE)));
|
||||
assertThat(info.getOperations()[0].getImpact()).isOne();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -110,8 +110,9 @@ class JmxEndpointDiscovererTests {
|
||||
@Test
|
||||
void getEndpointsWhenJmxExtensionIsMissingEndpointShouldThrowException() {
|
||||
load(TestJmxEndpointExtension.class, (discoverer) -> assertThatIllegalStateException()
|
||||
.isThrownBy(discoverer::getEndpoints).withMessageContaining(
|
||||
"Invalid extension 'jmxEndpointDiscovererTests.TestJmxEndpointExtension': no endpoint found with id 'test'"));
|
||||
.isThrownBy(discoverer::getEndpoints)
|
||||
.withMessageContaining(
|
||||
"Invalid extension 'jmxEndpointDiscovererTests.TestJmxEndpointExtension': no endpoint found with id 'test'"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -174,44 +175,49 @@ class JmxEndpointDiscovererTests {
|
||||
@Test
|
||||
void getEndpointsWhenTwoExtensionsHaveTheSameEndpointTypeShouldThrowException() {
|
||||
load(ClashingJmxEndpointConfiguration.class, (discoverer) -> assertThatIllegalStateException()
|
||||
.isThrownBy(discoverer::getEndpoints).withMessageContaining(
|
||||
"Found multiple extensions for the endpoint bean testEndpoint (testExtensionOne, testExtensionTwo)"));
|
||||
.isThrownBy(discoverer::getEndpoints)
|
||||
.withMessageContaining(
|
||||
"Found multiple extensions for the endpoint bean testEndpoint (testExtensionOne, testExtensionTwo)"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getEndpointsWhenTwoStandardEndpointsHaveTheSameIdShouldThrowException() {
|
||||
load(ClashingStandardEndpointConfiguration.class,
|
||||
(discoverer) -> assertThatIllegalStateException().isThrownBy(discoverer::getEndpoints)
|
||||
.withMessageContaining("Found two endpoints with the id 'test': "));
|
||||
.withMessageContaining("Found two endpoints with the id 'test': "));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getEndpointsWhenWhenEndpointHasTwoOperationsWithTheSameNameShouldThrowException() {
|
||||
load(ClashingOperationsEndpoint.class, (discoverer) -> assertThatIllegalStateException()
|
||||
.isThrownBy(discoverer::getEndpoints).withMessageContaining(
|
||||
"Unable to map duplicate endpoint operations: [MBean call 'getAll'] to jmxEndpointDiscovererTests.ClashingOperationsEndpoint"));
|
||||
.isThrownBy(discoverer::getEndpoints)
|
||||
.withMessageContaining(
|
||||
"Unable to map duplicate endpoint operations: [MBean call 'getAll'] to jmxEndpointDiscovererTests.ClashingOperationsEndpoint"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getEndpointsWhenWhenExtensionHasTwoOperationsWithTheSameNameShouldThrowException() {
|
||||
load(AdditionalClashingOperationsConfiguration.class, (discoverer) -> assertThatIllegalStateException()
|
||||
.isThrownBy(discoverer::getEndpoints).withMessageContaining(
|
||||
"Unable to map duplicate endpoint operations: [MBean call 'getAll'] to testEndpoint (clashingOperationsJmxEndpointExtension)"));
|
||||
.isThrownBy(discoverer::getEndpoints)
|
||||
.withMessageContaining(
|
||||
"Unable to map duplicate endpoint operations: [MBean call 'getAll'] to testEndpoint (clashingOperationsJmxEndpointExtension)"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getEndpointsWhenExtensionIsNotCompatibleWithTheEndpointTypeShouldThrowException() {
|
||||
load(InvalidJmxExtensionConfiguration.class, (discoverer) -> assertThatIllegalStateException()
|
||||
.isThrownBy(discoverer::getEndpoints).withMessageContaining(
|
||||
"Endpoint bean 'nonJmxEndpoint' cannot support the extension bean 'nonJmxJmxEndpointExtension'"));
|
||||
.isThrownBy(discoverer::getEndpoints)
|
||||
.withMessageContaining(
|
||||
"Endpoint bean 'nonJmxEndpoint' cannot support the extension bean 'nonJmxJmxEndpointExtension'"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRegisterHints() {
|
||||
RuntimeHints runtimeHints = new RuntimeHints();
|
||||
new JmxEndpointDiscovererRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader());
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(JmxEndpointFilter.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints);
|
||||
assertThat(RuntimeHintsPredicates.reflection()
|
||||
.onType(JmxEndpointFilter.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints);
|
||||
}
|
||||
|
||||
private Object getInvoker(JmxOperation operation) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,7 +42,7 @@ class EndpointLinksResolverTests {
|
||||
@Test
|
||||
void linkResolutionWithTrailingSlashStripsSlashOnSelfLink() {
|
||||
Map<String, Link> links = new EndpointLinksResolver(Collections.emptyList())
|
||||
.resolveLinks("https://api.example.com/actuator/");
|
||||
.resolveLinks("https://api.example.com/actuator/");
|
||||
assertThat(links).hasSize(1);
|
||||
assertThat(links).hasEntrySatisfying("self", linkWithHref("https://api.example.com/actuator"));
|
||||
}
|
||||
@@ -50,7 +50,7 @@ class EndpointLinksResolverTests {
|
||||
@Test
|
||||
void linkResolutionWithoutTrailingSlash() {
|
||||
Map<String, Link> links = new EndpointLinksResolver(Collections.emptyList())
|
||||
.resolveLinks("https://api.example.com/actuator");
|
||||
.resolveLinks("https://api.example.com/actuator");
|
||||
assertThat(links).hasSize(1);
|
||||
assertThat(links).hasEntrySatisfying("self", linkWithHref("https://api.example.com/actuator"));
|
||||
}
|
||||
@@ -66,7 +66,7 @@ class EndpointLinksResolverTests {
|
||||
given(endpoint.getOperations()).willReturn(operations);
|
||||
String requestUrl = "https://api.example.com/actuator";
|
||||
Map<String, Link> links = new EndpointLinksResolver(Collections.singletonList(endpoint))
|
||||
.resolveLinks(requestUrl);
|
||||
.resolveLinks(requestUrl);
|
||||
assertThat(links).hasSize(3);
|
||||
assertThat(links).hasEntrySatisfying("self", linkWithHref("https://api.example.com/actuator"));
|
||||
assertThat(links).hasEntrySatisfying("alpha", linkWithHref("https://api.example.com/actuator/alpha"));
|
||||
@@ -82,7 +82,7 @@ class EndpointLinksResolverTests {
|
||||
given(servletEndpoint.getRootPath()).willReturn("alpha");
|
||||
String requestUrl = "https://api.example.com/actuator";
|
||||
Map<String, Link> links = new EndpointLinksResolver(Collections.singletonList(servletEndpoint))
|
||||
.resolveLinks(requestUrl);
|
||||
.resolveLinks(requestUrl);
|
||||
assertThat(links).hasSize(2);
|
||||
assertThat(links).hasEntrySatisfying("self", linkWithHref("https://api.example.com/actuator"));
|
||||
assertThat(links).hasEntrySatisfying("alpha", linkWithHref("https://api.example.com/actuator/alpha"));
|
||||
@@ -96,7 +96,7 @@ class EndpointLinksResolverTests {
|
||||
given(controllerEndpoint.getRootPath()).willReturn("alpha");
|
||||
String requestUrl = "https://api.example.com/actuator";
|
||||
Map<String, Link> links = new EndpointLinksResolver(Collections.singletonList(controllerEndpoint))
|
||||
.resolveLinks(requestUrl);
|
||||
.resolveLinks(requestUrl);
|
||||
assertThat(links).hasSize(2);
|
||||
assertThat(links).hasEntrySatisfying("self", linkWithHref("https://api.example.com/actuator"));
|
||||
assertThat(links).hasEntrySatisfying("alpha", linkWithHref("https://api.example.com/actuator/alpha"));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,13 +47,13 @@ class EndpointMediaTypesTests {
|
||||
@Test
|
||||
void createWhenProducedIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new EndpointMediaTypes(null, Collections.emptyList()))
|
||||
.withMessageContaining("Produced must not be null");
|
||||
.withMessageContaining("Produced must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenConsumedIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new EndpointMediaTypes(Collections.emptyList(), null))
|
||||
.withMessageContaining("Consumed must not be null");
|
||||
.withMessageContaining("Consumed must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,13 +41,13 @@ class EndpointServletTests {
|
||||
@Test
|
||||
void createWhenServletClassIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new EndpointServlet((Class<Servlet>) null))
|
||||
.withMessageContaining("Servlet must not be null");
|
||||
.withMessageContaining("Servlet must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenServletIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new EndpointServlet((Servlet) null))
|
||||
.withMessageContaining("Servlet must not be null");
|
||||
.withMessageContaining("Servlet must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -84,36 +84,36 @@ class EndpointServletTests {
|
||||
@Test
|
||||
void withInitParameterWhenHasExistingShouldMergeParameters() {
|
||||
EndpointServlet endpointServlet = new EndpointServlet(TestServlet.class).withInitParameter("a", "b")
|
||||
.withInitParameter("c", "d");
|
||||
.withInitParameter("c", "d");
|
||||
assertThat(endpointServlet.withInitParameter("a", "b1").withInitParameter("e", "f").getInitParameters())
|
||||
.containsExactly(entry("a", "b1"), entry("c", "d"), entry("e", "f"));
|
||||
.containsExactly(entry("a", "b1"), entry("c", "d"), entry("e", "f"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void withInitParametersNullName() {
|
||||
EndpointServlet endpointServlet = new EndpointServlet(TestServlet.class);
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> endpointServlet.withInitParameters(Collections.singletonMap(null, "value")));
|
||||
.isThrownBy(() -> endpointServlet.withInitParameters(Collections.singletonMap(null, "value")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void withInitParametersEmptyName() {
|
||||
EndpointServlet endpointServlet = new EndpointServlet(TestServlet.class);
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> endpointServlet.withInitParameters(Collections.singletonMap(" ", "value")));
|
||||
.isThrownBy(() -> endpointServlet.withInitParameters(Collections.singletonMap(" ", "value")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void withInitParametersShouldCreateNewInstance() {
|
||||
EndpointServlet endpointServlet = new EndpointServlet(TestServlet.class);
|
||||
assertThat(endpointServlet.withInitParameters(Collections.singletonMap("spring", "boot")))
|
||||
.isNotSameAs(endpointServlet);
|
||||
.isNotSameAs(endpointServlet);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withInitParametersWhenHasExistingShouldMergeParameters() {
|
||||
EndpointServlet endpointServlet = new EndpointServlet(TestServlet.class).withInitParameter("a", "b")
|
||||
.withInitParameter("c", "d");
|
||||
.withInitParameter("c", "d");
|
||||
Map<String, String> extra = new LinkedHashMap<>();
|
||||
extra.put("a", "b1");
|
||||
extra.put("e", "f");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user