Merge branch '1.5.x' into 2.0.x
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,8 +45,8 @@ public class RabbitHealthIndicator extends AbstractHealthIndicator {
|
||||
}
|
||||
|
||||
private String getVersion() {
|
||||
return this.rabbitTemplate.execute((channel) -> channel.getConnection()
|
||||
.getServerProperties().get("version").toString());
|
||||
return this.rabbitTemplate
|
||||
.execute((channel) -> channel.getConnection().getServerProperties().get("version").toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -81,8 +81,7 @@ public class AuditEvent implements Serializable {
|
||||
* @param type the event type
|
||||
* @param data the event data
|
||||
*/
|
||||
public AuditEvent(Instant timestamp, String principal, String type,
|
||||
Map<String, Object> data) {
|
||||
public AuditEvent(Instant timestamp, String principal, String type, Map<String, Object> data) {
|
||||
Assert.notNull(timestamp, "Timestamp must not be null");
|
||||
Assert.notNull(type, "Type must not be null");
|
||||
this.timestamp = timestamp;
|
||||
@@ -140,8 +139,8 @@ public class AuditEvent implements Serializable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AuditEvent [timestamp=" + this.timestamp + ", principal=" + this.principal
|
||||
+ ", type=" + this.type + ", data=" + this.data + "]";
|
||||
return "AuditEvent [timestamp=" + this.timestamp + ", principal=" + this.principal + ", type=" + this.type
|
||||
+ ", data=" + this.data + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,10 +42,9 @@ public class AuditEventsEndpoint {
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
public AuditEventsDescriptor events(@Nullable String principal,
|
||||
@Nullable OffsetDateTime after, @Nullable String type) {
|
||||
List<AuditEvent> events = this.auditEventRepository.find(principal,
|
||||
getInstant(after), type);
|
||||
public AuditEventsDescriptor events(@Nullable String principal, @Nullable OffsetDateTime after,
|
||||
@Nullable String type) {
|
||||
List<AuditEvent> events = this.auditEventRepository.find(principal, getInstant(after), type);
|
||||
return new AuditEventsDescriptor(events);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -83,8 +83,7 @@ public class InMemoryAuditEventRepository implements AuditEventRepository {
|
||||
return events;
|
||||
}
|
||||
|
||||
private boolean isMatch(String principal, Instant after, String type,
|
||||
AuditEvent event) {
|
||||
private boolean isMatch(String principal, Instant after, String type, AuditEvent event) {
|
||||
boolean match = true;
|
||||
match = match && (principal == null || event.getPrincipal().equals(principal));
|
||||
match = match && (after == null || event.getTimestamp().isAfter(after));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,8 +25,7 @@ import org.springframework.context.ApplicationListener;
|
||||
* @author Vedran Pavic
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public abstract class AbstractAuditListener
|
||||
implements ApplicationListener<AuditApplicationEvent> {
|
||||
public abstract class AbstractAuditListener implements ApplicationListener<AuditApplicationEvent> {
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(AuditApplicationEvent event) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,8 +40,7 @@ public class AuditApplicationEvent extends ApplicationEvent {
|
||||
* @param data the event data
|
||||
* @see AuditEvent#AuditEvent(String, String, Map)
|
||||
*/
|
||||
public AuditApplicationEvent(String principal, String type,
|
||||
Map<String, Object> data) {
|
||||
public AuditApplicationEvent(String principal, String type, Map<String, Object> data) {
|
||||
this(new AuditEvent(principal, type, data));
|
||||
}
|
||||
|
||||
@@ -66,8 +65,7 @@ public class AuditApplicationEvent extends ApplicationEvent {
|
||||
* @param data the event data
|
||||
* @see AuditEvent#AuditEvent(Instant, String, String, Map)
|
||||
*/
|
||||
public AuditApplicationEvent(Instant timestamp, String principal, String type,
|
||||
Map<String, Object> data) {
|
||||
public AuditApplicationEvent(Instant timestamp, String principal, String type, Map<String, Object> data) {
|
||||
this(new AuditEvent(timestamp, principal, type, data));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -62,8 +62,7 @@ public class BeansEndpoint {
|
||||
return new ApplicationBeans(contexts);
|
||||
}
|
||||
|
||||
private static ConfigurableApplicationContext getConfigurableParent(
|
||||
ConfigurableApplicationContext context) {
|
||||
private static ConfigurableApplicationContext getConfigurableParent(ConfigurableApplicationContext context) {
|
||||
ApplicationContext parent = context.getParent();
|
||||
if (parent instanceof ConfigurableApplicationContext) {
|
||||
return (ConfigurableApplicationContext) parent;
|
||||
@@ -117,12 +116,10 @@ public class BeansEndpoint {
|
||||
return null;
|
||||
}
|
||||
ConfigurableApplicationContext parent = getConfigurableParent(context);
|
||||
return new ContextBeans(describeBeans(context.getBeanFactory()),
|
||||
(parent != null) ? parent.getId() : null);
|
||||
return new ContextBeans(describeBeans(context.getBeanFactory()), (parent != null) ? parent.getId() : null);
|
||||
}
|
||||
|
||||
private static Map<String, BeanDescriptor> describeBeans(
|
||||
ConfigurableListableBeanFactory beanFactory) {
|
||||
private static Map<String, BeanDescriptor> describeBeans(ConfigurableListableBeanFactory beanFactory) {
|
||||
Map<String, BeanDescriptor> beans = new HashMap<>();
|
||||
for (String beanName : beanFactory.getBeanDefinitionNames()) {
|
||||
BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
|
||||
@@ -135,13 +132,11 @@ public class BeansEndpoint {
|
||||
|
||||
private static BeanDescriptor describeBean(String name, BeanDefinition definition,
|
||||
ConfigurableListableBeanFactory factory) {
|
||||
return new BeanDescriptor(factory.getAliases(name), definition.getScope(),
|
||||
factory.getType(name), definition.getResourceDescription(),
|
||||
factory.getDependenciesForBean(name));
|
||||
return new BeanDescriptor(factory.getAliases(name), definition.getScope(), factory.getType(name),
|
||||
definition.getResourceDescription(), factory.getDependenciesForBean(name));
|
||||
}
|
||||
|
||||
private static boolean isBeanEligible(String beanName, BeanDefinition bd,
|
||||
ConfigurableBeanFactory bf) {
|
||||
private static boolean isBeanEligible(String beanName, BeanDefinition bd, ConfigurableBeanFactory bf) {
|
||||
return (bd.getRole() != BeanDefinition.ROLE_INFRASTRUCTURE
|
||||
&& (!bd.isLazyInit() || bf.containsSingleton(beanName)));
|
||||
}
|
||||
@@ -164,11 +159,9 @@ public class BeansEndpoint {
|
||||
|
||||
private final String[] dependencies;
|
||||
|
||||
private BeanDescriptor(String[] aliases, String scope, Class<?> type,
|
||||
String resource, String[] dependencies) {
|
||||
private BeanDescriptor(String[] aliases, String scope, Class<?> type, String resource, String[] dependencies) {
|
||||
this.aliases = aliases;
|
||||
this.scope = (StringUtils.hasText(scope) ? scope
|
||||
: BeanDefinition.SCOPE_SINGLETON);
|
||||
this.scope = (StringUtils.hasText(scope) ? scope : BeanDefinition.SCOPE_SINGLETON);
|
||||
this.type = type;
|
||||
this.resource = resource;
|
||||
this.dependencies = dependencies;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -54,8 +54,7 @@ public class CassandraHealthIndicator extends AbstractHealthIndicator {
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
Select select = QueryBuilder.select("release_version").from("system", "local");
|
||||
ResultSet results = this.cassandraOperations.getCqlOperations()
|
||||
.queryForResultSet(select);
|
||||
ResultSet results = this.cassandraOperations.getCqlOperations().queryForResultSet(select);
|
||||
if (results.isExhausted()) {
|
||||
builder.up();
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,12 +38,10 @@ import org.springframework.context.ConfigurableApplicationContext;
|
||||
public class ShutdownEndpoint implements ApplicationContextAware {
|
||||
|
||||
private static final Map<String, String> NO_CONTEXT_MESSAGE = Collections
|
||||
.unmodifiableMap(
|
||||
Collections.singletonMap("message", "No context to shutdown."));
|
||||
.unmodifiableMap(Collections.singletonMap("message", "No context to shutdown."));
|
||||
|
||||
private static final Map<String, String> SHUTDOWN_MESSAGE = Collections
|
||||
.unmodifiableMap(
|
||||
Collections.singletonMap("message", "Shutting down, bye..."));
|
||||
.unmodifiableMap(Collections.singletonMap("message", "Shutting down, bye..."));
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -99,31 +99,27 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
Map<String, ContextConfigurationProperties> contextProperties = new HashMap<>();
|
||||
ApplicationContext target = context;
|
||||
while (target != null) {
|
||||
contextProperties.put(target.getId(),
|
||||
describeConfigurationProperties(target, mapper));
|
||||
contextProperties.put(target.getId(), describeConfigurationProperties(target, mapper));
|
||||
target = target.getParent();
|
||||
}
|
||||
return new ApplicationConfigurationProperties(contextProperties);
|
||||
}
|
||||
|
||||
private ContextConfigurationProperties describeConfigurationProperties(
|
||||
ApplicationContext context, ObjectMapper mapper) {
|
||||
ConfigurationBeanFactoryMetadata beanFactoryMetadata = getBeanFactoryMetadata(
|
||||
context);
|
||||
Map<String, Object> beans = getConfigurationPropertiesBeans(context,
|
||||
beanFactoryMetadata);
|
||||
private ContextConfigurationProperties describeConfigurationProperties(ApplicationContext context,
|
||||
ObjectMapper mapper) {
|
||||
ConfigurationBeanFactoryMetadata beanFactoryMetadata = getBeanFactoryMetadata(context);
|
||||
Map<String, Object> beans = getConfigurationPropertiesBeans(context, beanFactoryMetadata);
|
||||
Map<String, ConfigurationPropertiesBeanDescriptor> beanDescriptors = new HashMap<>();
|
||||
beans.forEach((beanName, bean) -> {
|
||||
String prefix = extractPrefix(context, beanFactoryMetadata, beanName);
|
||||
beanDescriptors.put(beanName, new ConfigurationPropertiesBeanDescriptor(
|
||||
prefix, sanitize(prefix, safeSerialize(mapper, bean, prefix))));
|
||||
beanDescriptors.put(beanName, new ConfigurationPropertiesBeanDescriptor(prefix,
|
||||
sanitize(prefix, safeSerialize(mapper, bean, prefix))));
|
||||
});
|
||||
return new ContextConfigurationProperties(beanDescriptors,
|
||||
(context.getParent() != null) ? context.getParent().getId() : null);
|
||||
}
|
||||
|
||||
private ConfigurationBeanFactoryMetadata getBeanFactoryMetadata(
|
||||
ApplicationContext context) {
|
||||
private ConfigurationBeanFactoryMetadata getBeanFactoryMetadata(ApplicationContext context) {
|
||||
Map<String, ConfigurationBeanFactoryMetadata> beans = context
|
||||
.getBeansOfType(ConfigurationBeanFactoryMetadata.class);
|
||||
if (beans.size() == 1) {
|
||||
@@ -132,14 +128,12 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<String, Object> getConfigurationPropertiesBeans(
|
||||
ApplicationContext context,
|
||||
private Map<String, Object> getConfigurationPropertiesBeans(ApplicationContext context,
|
||||
ConfigurationBeanFactoryMetadata beanFactoryMetadata) {
|
||||
Map<String, Object> beans = new HashMap<>();
|
||||
beans.putAll(context.getBeansWithAnnotation(ConfigurationProperties.class));
|
||||
if (beanFactoryMetadata != null) {
|
||||
beans.putAll(beanFactoryMetadata
|
||||
.getBeansWithFactoryAnnotation(ConfigurationProperties.class));
|
||||
beans.putAll(beanFactoryMetadata.getBeansWithFactoryAnnotation(ConfigurationProperties.class));
|
||||
}
|
||||
return beans;
|
||||
}
|
||||
@@ -153,14 +147,12 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
* @return the serialized instance
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> safeSerialize(ObjectMapper mapper, Object bean,
|
||||
String prefix) {
|
||||
private Map<String, Object> safeSerialize(ObjectMapper mapper, Object bean, String prefix) {
|
||||
try {
|
||||
return new HashMap<>(mapper.convertValue(bean, Map.class));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return new HashMap<>(Collections.singletonMap("error",
|
||||
"Cannot serialize '" + prefix + "'"));
|
||||
return new HashMap<>(Collections.singletonMap("error", "Cannot serialize '" + prefix + "'"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,10 +180,9 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
}
|
||||
|
||||
private void applyConfigurationPropertiesFilter(ObjectMapper mapper) {
|
||||
mapper.setAnnotationIntrospector(
|
||||
new ConfigurationPropertiesAnnotationIntrospector());
|
||||
mapper.setFilterProvider(new SimpleFilterProvider()
|
||||
.setDefaultFilter(new ConfigurationPropertiesPropertyFilter()));
|
||||
mapper.setAnnotationIntrospector(new ConfigurationPropertiesAnnotationIntrospector());
|
||||
mapper.setFilterProvider(
|
||||
new SimpleFilterProvider().setDefaultFilter(new ConfigurationPropertiesPropertyFilter()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,13 +192,12 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
* @param beanName the bean name
|
||||
* @return the prefix
|
||||
*/
|
||||
private String extractPrefix(ApplicationContext context,
|
||||
ConfigurationBeanFactoryMetadata beanFactoryMetaData, String beanName) {
|
||||
ConfigurationProperties annotation = context.findAnnotationOnBean(beanName,
|
||||
ConfigurationProperties.class);
|
||||
private String extractPrefix(ApplicationContext context, ConfigurationBeanFactoryMetadata beanFactoryMetaData,
|
||||
String beanName) {
|
||||
ConfigurationProperties annotation = context.findAnnotationOnBean(beanName, ConfigurationProperties.class);
|
||||
if (beanFactoryMetaData != null) {
|
||||
ConfigurationProperties override = beanFactoryMetaData
|
||||
.findFactoryAnnotation(beanName, ConfigurationProperties.class);
|
||||
ConfigurationProperties override = beanFactoryMetaData.findFactoryAnnotation(beanName,
|
||||
ConfigurationProperties.class);
|
||||
if (override != null) {
|
||||
// The @Bean-level @ConfigurationProperties overrides the one at type
|
||||
// level when binding. Arguably we should render them both, but this one
|
||||
@@ -266,8 +256,7 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
* properties.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
private static class ConfigurationPropertiesAnnotationIntrospector
|
||||
extends JacksonAnnotationIntrospector {
|
||||
private static class ConfigurationPropertiesAnnotationIntrospector extends JacksonAnnotationIntrospector {
|
||||
|
||||
@Override
|
||||
public Object findFilterId(Annotated a) {
|
||||
@@ -290,11 +279,9 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
* <li>Properties that throw an exception when retrieving their value.
|
||||
* </ul>
|
||||
*/
|
||||
private static class ConfigurationPropertiesPropertyFilter
|
||||
extends SimpleBeanPropertyFilter {
|
||||
private static class ConfigurationPropertiesPropertyFilter extends SimpleBeanPropertyFilter {
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(ConfigurationPropertiesPropertyFilter.class);
|
||||
private static final Log logger = LogFactory.getLog(ConfigurationPropertiesPropertyFilter.class);
|
||||
|
||||
@Override
|
||||
protected boolean include(BeanPropertyWriter writer) {
|
||||
@@ -311,14 +298,13 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeAsField(Object pojo, JsonGenerator jgen,
|
||||
SerializerProvider provider, PropertyWriter writer) throws Exception {
|
||||
public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider,
|
||||
PropertyWriter writer) throws Exception {
|
||||
if (writer instanceof BeanPropertyWriter) {
|
||||
try {
|
||||
if (pojo == ((BeanPropertyWriter) writer).get(pojo)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Skipping '" + writer.getFullName() + "' on '"
|
||||
+ pojo.getClass().getName()
|
||||
logger.debug("Skipping '" + writer.getFullName() + "' on '" + pojo.getClass().getName()
|
||||
+ "' as it is self-referential");
|
||||
}
|
||||
return;
|
||||
@@ -326,9 +312,8 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
}
|
||||
catch (Exception ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Skipping '" + writer.getFullName() + "' on '"
|
||||
+ pojo.getClass().getName() + "' as an exception "
|
||||
+ "was thrown when retrieving its value", ex);
|
||||
logger.debug("Skipping '" + writer.getFullName() + "' on '" + pojo.getClass().getName()
|
||||
+ "' as an exception " + "was thrown when retrieving its value", ex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -344,8 +329,8 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
protected static class GenericSerializerModifier extends BeanSerializerModifier {
|
||||
|
||||
@Override
|
||||
public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
|
||||
BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
|
||||
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
|
||||
List<BeanPropertyWriter> beanProperties) {
|
||||
List<BeanPropertyWriter> result = new ArrayList<>();
|
||||
for (BeanPropertyWriter writer : beanProperties) {
|
||||
boolean readable = isReadable(beanDesc, writer);
|
||||
@@ -366,15 +351,11 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
// should be kosher. Lists and Maps are also auto-detected by default since
|
||||
// that's what the metadata generator does. This filter is not used if there
|
||||
// is JSON metadata for the property, so it's mainly for user-defined beans.
|
||||
return (setter != null)
|
||||
|| ClassUtils.getPackageName(parentType)
|
||||
.equals(ClassUtils.getPackageName(type))
|
||||
|| Map.class.isAssignableFrom(type)
|
||||
|| Collection.class.isAssignableFrom(type);
|
||||
return (setter != null) || ClassUtils.getPackageName(parentType).equals(ClassUtils.getPackageName(type))
|
||||
|| Map.class.isAssignableFrom(type) || Collection.class.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
private AnnotatedMethod findSetter(BeanDescription beanDesc,
|
||||
BeanPropertyWriter writer) {
|
||||
private AnnotatedMethod findSetter(BeanDescription beanDesc, BeanPropertyWriter writer) {
|
||||
String name = "set" + determineAccessorSuffix(writer.getName());
|
||||
Class<?> type = writer.getType().getRawClass();
|
||||
AnnotatedMethod setter = beanDesc.findMethod(name, new Class<?>[] { type });
|
||||
@@ -394,8 +375,7 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
* @return the accessor suffix for {@code propertyName}
|
||||
*/
|
||||
private String determineAccessorSuffix(String propertyName) {
|
||||
if (propertyName.length() > 1
|
||||
&& Character.isUpperCase(propertyName.charAt(1))) {
|
||||
if (propertyName.length() > 1 && Character.isUpperCase(propertyName.charAt(1))) {
|
||||
return propertyName;
|
||||
}
|
||||
return StringUtils.capitalize(propertyName);
|
||||
@@ -411,8 +391,7 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
|
||||
private final Map<String, ContextConfigurationProperties> contexts;
|
||||
|
||||
private ApplicationConfigurationProperties(
|
||||
Map<String, ContextConfigurationProperties> contexts) {
|
||||
private ApplicationConfigurationProperties(Map<String, ContextConfigurationProperties> contexts) {
|
||||
this.contexts = contexts;
|
||||
}
|
||||
|
||||
@@ -432,8 +411,7 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
|
||||
private final String parentId;
|
||||
|
||||
private ContextConfigurationProperties(
|
||||
Map<String, ConfigurationPropertiesBeanDescriptor> beans,
|
||||
private ContextConfigurationProperties(Map<String, ConfigurationPropertiesBeanDescriptor> beans,
|
||||
String parentId) {
|
||||
this.beans = beans;
|
||||
this.parentId = parentId;
|
||||
@@ -459,8 +437,7 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
|
||||
|
||||
private final Map<String, Object> properties;
|
||||
|
||||
private ConfigurationPropertiesBeanDescriptor(String prefix,
|
||||
Map<String, Object> properties) {
|
||||
private ConfigurationPropertiesBeanDescriptor(String prefix, Map<String, Object> properties) {
|
||||
this.prefix = prefix;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,13 +57,11 @@ public class CouchbaseHealthIndicator extends AbstractHealthIndicator {
|
||||
* @deprecated since 2.0.6 in favour of {@link #CouchbaseHealthIndicator(Cluster)}
|
||||
*/
|
||||
@Deprecated
|
||||
public CouchbaseHealthIndicator(CouchbaseOperations couchbaseOperations,
|
||||
Duration timeout) {
|
||||
public CouchbaseHealthIndicator(CouchbaseOperations couchbaseOperations, Duration timeout) {
|
||||
super("Couchbase health check failed");
|
||||
Assert.notNull(couchbaseOperations, "CouchbaseOperations must not be null");
|
||||
Assert.notNull(timeout, "Timeout must not be null");
|
||||
this.healthCheck = new OperationsHealthCheck(couchbaseOperations,
|
||||
timeout.toMillis());
|
||||
this.healthCheck = new OperationsHealthCheck(couchbaseOperations, timeout.toMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,17 +112,14 @@ public class CouchbaseHealthIndicator extends AbstractHealthIndicator {
|
||||
public void checkHealth(Builder builder) throws Exception {
|
||||
ClusterInfo cluster = this.operations.getCouchbaseClusterInfo();
|
||||
BucketInfo bucket = getBucketInfo();
|
||||
String versions = StringUtils
|
||||
.collectionToCommaDelimitedString(cluster.getAllVersions());
|
||||
String nodes = StringUtils
|
||||
.collectionToCommaDelimitedString(bucket.nodeList());
|
||||
String versions = StringUtils.collectionToCommaDelimitedString(cluster.getAllVersions());
|
||||
String nodes = StringUtils.collectionToCommaDelimitedString(bucket.nodeList());
|
||||
builder.up().withDetail("versions", versions).withDetail("nodes", nodes);
|
||||
}
|
||||
|
||||
private BucketInfo getBucketInfo() throws Exception {
|
||||
try {
|
||||
return this.operations.getCouchbaseBucket().bucketManager()
|
||||
.info(this.timeout, TimeUnit.MILLISECONDS);
|
||||
return this.operations.getCouchbaseBucket().bucketManager().info(this.timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
if (ex.getCause() instanceof TimeoutException) {
|
||||
@@ -149,8 +144,8 @@ public class CouchbaseHealthIndicator extends AbstractHealthIndicator {
|
||||
DiagnosticsReport diagnostics = this.cluster.diagnostics();
|
||||
builder = isCouchbaseUp(diagnostics) ? builder.up() : builder.down();
|
||||
builder.withDetail("sdk", diagnostics.sdk());
|
||||
builder.withDetail("endpoints", diagnostics.endpoints().stream()
|
||||
.map(this::describe).collect(Collectors.toList()));
|
||||
builder.withDetail("endpoints",
|
||||
diagnostics.endpoints().stream().map(this::describe).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private boolean isCouchbaseUp(DiagnosticsReport diagnostics) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -52,10 +52,8 @@ public class ElasticsearchHealthIndicator extends AbstractHealthIndicator {
|
||||
* @param responseTimeout the request timeout in milliseconds
|
||||
* @param indices the indices to check
|
||||
*/
|
||||
public ElasticsearchHealthIndicator(Client client, long responseTimeout,
|
||||
List<String> indices) {
|
||||
this(client, responseTimeout,
|
||||
(indices != null) ? StringUtils.toStringArray(indices) : null);
|
||||
public ElasticsearchHealthIndicator(Client client, long responseTimeout, List<String> indices) {
|
||||
this(client, responseTimeout, (indices != null) ? StringUtils.toStringArray(indices) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,8 +62,7 @@ public class ElasticsearchHealthIndicator extends AbstractHealthIndicator {
|
||||
* @param responseTimeout the request timeout in milliseconds
|
||||
* @param indices the indices to check
|
||||
*/
|
||||
public ElasticsearchHealthIndicator(Client client, long responseTimeout,
|
||||
String... indices) {
|
||||
public ElasticsearchHealthIndicator(Client client, long responseTimeout, String... indices) {
|
||||
super("Elasticsearch health check failed");
|
||||
this.client = client;
|
||||
this.responseTimeout = responseTimeout;
|
||||
@@ -74,10 +71,9 @@ public class ElasticsearchHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
ClusterHealthRequest request = Requests.clusterHealthRequest(
|
||||
ObjectUtils.isEmpty(this.indices) ? ALL_INDICES : this.indices);
|
||||
ClusterHealthResponse response = this.client.admin().cluster().health(request)
|
||||
.actionGet(this.responseTimeout);
|
||||
ClusterHealthRequest request = Requests
|
||||
.clusterHealthRequest(ObjectUtils.isEmpty(this.indices) ? ALL_INDICES : this.indices);
|
||||
ClusterHealthResponse response = this.client.admin().cluster().health(request).actionGet(this.responseTimeout);
|
||||
switch (response.getStatus()) {
|
||||
case GREEN:
|
||||
case YELLOW:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,8 +30,7 @@ import org.springframework.util.Assert;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public abstract class AbstractExposableEndpoint<O extends Operation>
|
||||
implements ExposableEndpoint<O> {
|
||||
public abstract class AbstractExposableEndpoint<O extends Operation> implements ExposableEndpoint<O> {
|
||||
|
||||
private final EndpointId id;
|
||||
|
||||
@@ -48,8 +47,7 @@ public abstract class AbstractExposableEndpoint<O extends Operation>
|
||||
* {@link #AbstractExposableEndpoint(EndpointId, boolean, Collection)}
|
||||
*/
|
||||
@Deprecated
|
||||
public AbstractExposableEndpoint(String id, boolean enabledByDefault,
|
||||
Collection<? extends O> operations) {
|
||||
public AbstractExposableEndpoint(String id, boolean enabledByDefault, Collection<? extends O> operations) {
|
||||
this(EndpointId.of(id), enabledByDefault, operations);
|
||||
}
|
||||
|
||||
@@ -60,8 +58,7 @@ public abstract class AbstractExposableEndpoint<O extends Operation>
|
||||
* @param operations the endpoint operations
|
||||
* @since 2.0.6
|
||||
*/
|
||||
public AbstractExposableEndpoint(EndpointId id, boolean enabledByDefault,
|
||||
Collection<? extends O> operations) {
|
||||
public AbstractExposableEndpoint(EndpointId id, boolean enabledByDefault, Collection<? extends O> operations) {
|
||||
Assert.notNull(id, "ID must not be null");
|
||||
Assert.notNull(operations, "Operations must not be null");
|
||||
this.id = id;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,12 +41,9 @@ public final class EndpointId {
|
||||
|
||||
private EndpointId(String value) {
|
||||
Assert.hasText(value, "Value must not be empty");
|
||||
Assert.isTrue(VALID_CHARS.matcher(value).matches(),
|
||||
"Value must only contain valid chars");
|
||||
Assert.isTrue(!Character.isDigit(value.charAt(0)),
|
||||
"Value must not start with a number");
|
||||
Assert.isTrue(!Character.isUpperCase(value.charAt(0)),
|
||||
"Value must not start with an uppercase letter");
|
||||
Assert.isTrue(VALID_CHARS.matcher(value).matches(), "Value must only contain valid chars");
|
||||
Assert.isTrue(!Character.isDigit(value.charAt(0)), "Value must not start with a number");
|
||||
Assert.isTrue(!Character.isUpperCase(value.charAt(0)), "Value must not start with an uppercase letter");
|
||||
this.value = value;
|
||||
this.lowerCaseValue = value.toLowerCase(Locale.ENGLISH);
|
||||
this.lowerCaseAlphaNumeric = getAlphaNumerics(this.lowerCaseValue);
|
||||
@@ -71,8 +68,7 @@ public final class EndpointId {
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
return this.lowerCaseAlphaNumeric
|
||||
.equals(((EndpointId) obj).lowerCaseAlphaNumeric);
|
||||
return this.lowerCaseAlphaNumeric.equals(((EndpointId) obj).lowerCaseAlphaNumeric);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,8 +31,7 @@ public class InvalidEndpointRequestException extends RuntimeException {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public InvalidEndpointRequestException(String message, String reason,
|
||||
Throwable cause) {
|
||||
public InvalidEndpointRequestException(String message, String reason, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,8 +39,7 @@ public class InvocationContext {
|
||||
* @param securityContext the current security context. Never {@code null}
|
||||
* @param arguments the arguments available to the operation. Never {@code null}
|
||||
*/
|
||||
public InvocationContext(SecurityContext securityContext,
|
||||
Map<String, Object> arguments) {
|
||||
public InvocationContext(SecurityContext securityContext, Map<String, Object> arguments) {
|
||||
Assert.notNull(securityContext, "SecurityContext must not be null");
|
||||
Assert.notNull(arguments, "Arguments must not be null");
|
||||
this.securityContext = securityContext;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,8 +38,7 @@ public class Sanitizer {
|
||||
private Pattern[] keysToSanitize;
|
||||
|
||||
public Sanitizer() {
|
||||
this("password", "secret", "key", "token", ".*credentials.*", "vcap_services",
|
||||
"sun.java.command");
|
||||
this("password", "secret", "key", "token", ".*credentials.*", "vcap_services", "sun.java.command");
|
||||
}
|
||||
|
||||
public Sanitizer(String... keysToSanitize) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,8 +33,8 @@ import org.springframework.util.Assert;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public abstract class AbstractDiscoveredEndpoint<O extends Operation>
|
||||
extends AbstractExposableEndpoint<O> implements DiscoveredEndpoint<O> {
|
||||
public abstract class AbstractDiscoveredEndpoint<O extends Operation> extends AbstractExposableEndpoint<O>
|
||||
implements DiscoveredEndpoint<O> {
|
||||
|
||||
private final EndpointDiscoverer<?, ?> discoverer;
|
||||
|
||||
@@ -51,9 +51,8 @@ public abstract class AbstractDiscoveredEndpoint<O extends Operation>
|
||||
* {@link #AbstractDiscoveredEndpoint(EndpointDiscoverer, Object, EndpointId, boolean, Collection)}
|
||||
*/
|
||||
@Deprecated
|
||||
public AbstractDiscoveredEndpoint(EndpointDiscoverer<?, ?> discoverer,
|
||||
Object endpointBean, String id, boolean enabledByDefault,
|
||||
Collection<? extends O> operations) {
|
||||
public AbstractDiscoveredEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean, String id,
|
||||
boolean enabledByDefault, Collection<? extends O> operations) {
|
||||
this(discoverer, endpointBean, EndpointId.of(id), enabledByDefault, operations);
|
||||
}
|
||||
|
||||
@@ -66,9 +65,8 @@ public abstract class AbstractDiscoveredEndpoint<O extends Operation>
|
||||
* @param operations the endpoint operations
|
||||
* @since 2.0.6
|
||||
*/
|
||||
public AbstractDiscoveredEndpoint(EndpointDiscoverer<?, ?> discoverer,
|
||||
Object endpointBean, EndpointId id, boolean enabledByDefault,
|
||||
Collection<? extends O> operations) {
|
||||
public AbstractDiscoveredEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean, EndpointId id,
|
||||
boolean enabledByDefault, Collection<? extends O> operations) {
|
||||
super(id, enabledByDefault, operations);
|
||||
Assert.notNull(discoverer, "Discoverer must not be null");
|
||||
Assert.notNull(endpointBean, "EndpointBean must not be null");
|
||||
@@ -88,8 +86,7 @@ public abstract class AbstractDiscoveredEndpoint<O extends Operation>
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringCreator creator = new ToStringCreator(this)
|
||||
.append("discoverer", this.discoverer.getClass().getName())
|
||||
ToStringCreator creator = new ToStringCreator(this).append("discoverer", this.discoverer.getClass().getName())
|
||||
.append("endpointBean", this.endpointBean.getClass().getName());
|
||||
appendFields(creator);
|
||||
return creator.toString();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,8 +41,7 @@ public abstract class AbstractDiscoveredOperation implements Operation {
|
||||
* @param operationMethod the method backing the operation
|
||||
* @param invoker the operation invoker to use
|
||||
*/
|
||||
public AbstractDiscoveredOperation(DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker) {
|
||||
public AbstractDiscoveredOperation(DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
this.operationMethod = operationMethod;
|
||||
this.invoker = invoker;
|
||||
}
|
||||
@@ -63,8 +62,7 @@ public abstract class AbstractDiscoveredOperation implements Operation {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringCreator creator = new ToStringCreator(this)
|
||||
.append("operationMethod", this.operationMethod)
|
||||
ToStringCreator creator = new ToStringCreator(this).append("operationMethod", this.operationMethod)
|
||||
.append("invoker", this.invoker);
|
||||
appendFields(creator);
|
||||
return creator.toString();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -51,8 +51,7 @@ abstract class DiscoveredOperationsFactory<O extends Operation> {
|
||||
private static final Map<OperationType, Class<? extends Annotation>> OPERATION_TYPES;
|
||||
|
||||
static {
|
||||
Map<OperationType, Class<? extends Annotation>> operationTypes = new EnumMap<>(
|
||||
OperationType.class);
|
||||
Map<OperationType, Class<? extends Annotation>> operationTypes = new EnumMap<>(OperationType.class);
|
||||
operationTypes.put(OperationType.READ, ReadOperation.class);
|
||||
operationTypes.put(OperationType.WRITE, WriteOperation.class);
|
||||
operationTypes.put(OperationType.DELETE, DeleteOperation.class);
|
||||
@@ -70,45 +69,43 @@ abstract class DiscoveredOperationsFactory<O extends Operation> {
|
||||
}
|
||||
|
||||
public Collection<O> createOperations(EndpointId id, Object target) {
|
||||
return MethodIntrospector.selectMethods(target.getClass(),
|
||||
(MetadataLookup<O>) (method) -> createOperation(id, target, method))
|
||||
return MethodIntrospector
|
||||
.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()))
|
||||
.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, Class<? extends Annotation> annotationType) {
|
||||
AnnotationAttributes annotationAttributes = AnnotatedElementUtils
|
||||
.getMergedAnnotationAttributes(method, annotationType);
|
||||
private O createOperation(EndpointId endpointId, Object target, Method method, OperationType operationType,
|
||||
Class<? extends Annotation> annotationType) {
|
||||
AnnotationAttributes annotationAttributes = AnnotatedElementUtils.getMergedAnnotationAttributes(method,
|
||||
annotationType);
|
||||
if (annotationAttributes == null) {
|
||||
return null;
|
||||
}
|
||||
DiscoveredOperationMethod operationMethod = new DiscoveredOperationMethod(method,
|
||||
operationType, annotationAttributes);
|
||||
OperationInvoker invoker = new ReflectiveOperationInvoker(target, operationMethod,
|
||||
this.parameterValueMapper);
|
||||
DiscoveredOperationMethod operationMethod = new DiscoveredOperationMethod(method, operationType,
|
||||
annotationAttributes);
|
||||
OperationInvoker invoker = new ReflectiveOperationInvoker(target, operationMethod, this.parameterValueMapper);
|
||||
invoker = applyAdvisors(endpointId, operationMethod, invoker);
|
||||
return createOperation(endpointId, operationMethod, invoker);
|
||||
}
|
||||
|
||||
private OperationInvoker applyAdvisors(EndpointId endpointId,
|
||||
OperationMethod operationMethod, OperationInvoker invoker) {
|
||||
private OperationInvoker applyAdvisors(EndpointId endpointId, OperationMethod operationMethod,
|
||||
OperationInvoker invoker) {
|
||||
if (this.invokerAdvisors != null) {
|
||||
for (OperationInvokerAdvisor advisor : this.invokerAdvisors) {
|
||||
invoker = advisor.apply(endpointId, operationMethod.getOperationType(),
|
||||
operationMethod.getParameters(), invoker);
|
||||
invoker = advisor.apply(endpointId, operationMethod.getOperationType(), operationMethod.getParameters(),
|
||||
invoker);
|
||||
}
|
||||
}
|
||||
return invoker;
|
||||
}
|
||||
|
||||
protected abstract O createOperation(EndpointId endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker);
|
||||
protected abstract O createOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,8 +25,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public abstract class DiscovererEndpointFilter
|
||||
implements EndpointFilter<DiscoveredEndpoint<?>> {
|
||||
public abstract class DiscovererEndpointFilter implements EndpointFilter<DiscoveredEndpoint<?>> {
|
||||
|
||||
private final Class<? extends EndpointDiscoverer<?, ?>> discoverer;
|
||||
|
||||
@@ -34,8 +33,7 @@ public abstract class DiscovererEndpointFilter
|
||||
* Create a new {@link DiscovererEndpointFilter} instance.
|
||||
* @param discoverer the required discoverer
|
||||
*/
|
||||
protected DiscovererEndpointFilter(
|
||||
Class<? extends EndpointDiscoverer<?, ?>> discoverer) {
|
||||
protected DiscovererEndpointFilter(Class<? extends EndpointDiscoverer<?, ?>> discoverer) {
|
||||
Assert.notNull(discoverer, "Discoverer must not be null");
|
||||
this.discoverer = discoverer;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -83,30 +83,25 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
* @param invokerAdvisors invoker advisors to apply
|
||||
* @param filters filters to apply
|
||||
*/
|
||||
public EndpointDiscoverer(ApplicationContext applicationContext,
|
||||
ParameterValueMapper parameterValueMapper,
|
||||
Collection<OperationInvokerAdvisor> invokerAdvisors,
|
||||
Collection<EndpointFilter<E>> filters) {
|
||||
public EndpointDiscoverer(ApplicationContext applicationContext, ParameterValueMapper parameterValueMapper,
|
||||
Collection<OperationInvokerAdvisor> invokerAdvisors, Collection<EndpointFilter<E>> filters) {
|
||||
Assert.notNull(applicationContext, "ApplicationContext must not be null");
|
||||
Assert.notNull(parameterValueMapper, "ParameterValueMapper must not be null");
|
||||
Assert.notNull(invokerAdvisors, "InvokerAdvisors must not be null");
|
||||
Assert.notNull(filters, "Filters must not be null");
|
||||
this.applicationContext = applicationContext;
|
||||
this.filters = Collections.unmodifiableCollection(filters);
|
||||
this.operationsFactory = getOperationsFactory(parameterValueMapper,
|
||||
invokerAdvisors);
|
||||
this.operationsFactory = getOperationsFactory(parameterValueMapper, invokerAdvisors);
|
||||
}
|
||||
|
||||
private DiscoveredOperationsFactory<O> getOperationsFactory(
|
||||
ParameterValueMapper parameterValueMapper,
|
||||
private DiscoveredOperationsFactory<O> getOperationsFactory(ParameterValueMapper parameterValueMapper,
|
||||
Collection<OperationInvokerAdvisor> invokerAdvisors) {
|
||||
return new DiscoveredOperationsFactory<O>(parameterValueMapper, invokerAdvisors) {
|
||||
|
||||
@Override
|
||||
protected O createOperation(EndpointId endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
return EndpointDiscoverer.this.createOperation(endpointId,
|
||||
operationMethod, invoker);
|
||||
protected O createOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker) {
|
||||
return EndpointDiscoverer.this.createOperation(endpointId, operationMethod, invoker);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -128,17 +123,14 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
|
||||
private Collection<EndpointBean> createEndpointBeans() {
|
||||
Map<EndpointId, EndpointBean> byId = new LinkedHashMap<>();
|
||||
String[] beanNames = BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(
|
||||
this.applicationContext, Endpoint.class);
|
||||
String[] beanNames = BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.applicationContext,
|
||||
Endpoint.class);
|
||||
for (String beanName : beanNames) {
|
||||
if (!ScopedProxyUtils.isScopedTarget(beanName)) {
|
||||
EndpointBean endpointBean = createEndpointBean(beanName);
|
||||
EndpointBean previous = byId.putIfAbsent(endpointBean.getId(),
|
||||
endpointBean);
|
||||
Assert.state(previous == null,
|
||||
() -> "Found two endpoints with the id '" + endpointBean.getId()
|
||||
+ "': '" + endpointBean.getBeanName() + "' and '"
|
||||
+ previous.getBeanName() + "'");
|
||||
EndpointBean previous = byId.putIfAbsent(endpointBean.getId(), endpointBean);
|
||||
Assert.state(previous == null, () -> "Found two endpoints with the id '" + endpointBean.getId() + "': '"
|
||||
+ endpointBean.getBeanName() + "' and '" + previous.getBeanName() + "'");
|
||||
}
|
||||
}
|
||||
return byId.values();
|
||||
@@ -152,15 +144,13 @@ 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, (bean) -> bean));
|
||||
String[] beanNames = BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(
|
||||
this.applicationContext, EndpointExtension.class);
|
||||
String[] beanNames = BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.applicationContext,
|
||||
EndpointExtension.class);
|
||||
for (String beanName : beanNames) {
|
||||
ExtensionBean extensionBean = createExtensionBean(beanName);
|
||||
EndpointBean endpointBean = byId.get(extensionBean.getEndpointId());
|
||||
Assert.state(endpointBean != null,
|
||||
() -> ("Invalid extension '" + extensionBean.getBeanName()
|
||||
+ "': no endpoint found with id '"
|
||||
+ extensionBean.getEndpointId() + "'"));
|
||||
Assert.state(endpointBean != null, () -> ("Invalid extension '" + extensionBean.getBeanName()
|
||||
+ "': no endpoint found with id '" + extensionBean.getEndpointId() + "'"));
|
||||
addExtensionBean(endpointBean, extensionBean);
|
||||
}
|
||||
}
|
||||
@@ -170,13 +160,10 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
return new ExtensionBean(beanName, bean);
|
||||
}
|
||||
|
||||
private void addExtensionBean(EndpointBean endpointBean,
|
||||
ExtensionBean extensionBean) {
|
||||
private void addExtensionBean(EndpointBean endpointBean, ExtensionBean extensionBean) {
|
||||
if (isExtensionExposed(endpointBean, extensionBean)) {
|
||||
Assert.state(
|
||||
isEndpointExposed(endpointBean) || isEndpointFiltered(endpointBean),
|
||||
() -> "Endpoint bean '" + endpointBean.getBeanName()
|
||||
+ "' cannot support the extension bean '"
|
||||
Assert.state(isEndpointExposed(endpointBean) || isEndpointFiltered(endpointBean),
|
||||
() -> "Endpoint bean '" + endpointBean.getBeanName() + "' cannot support the extension bean '"
|
||||
+ extensionBean.getBeanName() + "'");
|
||||
endpointBean.addExtension(extensionBean);
|
||||
}
|
||||
@@ -197,25 +184,22 @@ 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(", "));
|
||||
throw new IllegalStateException(
|
||||
"Found multiple extensions for the endpoint bean "
|
||||
+ endpointBean.getBeanName() + " (" + extensionBeans + ")");
|
||||
String extensionBeans = endpointBean.getExtensions().stream().map(ExtensionBean::getBeanName)
|
||||
.collect(Collectors.joining(", "));
|
||||
throw new IllegalStateException("Found multiple extensions for the endpoint bean "
|
||||
+ endpointBean.getBeanName() + " (" + extensionBeans + ")");
|
||||
}
|
||||
for (ExtensionBean extensionBean : endpointBean.getExtensions()) {
|
||||
addOperations(indexed, id, extensionBean.getBean(), true);
|
||||
}
|
||||
assertNoDuplicateOperations(endpointBean, indexed);
|
||||
List<O> operations = indexed.values().stream().map(this::getLast)
|
||||
.filter(Objects::nonNull).collect(Collectors.collectingAndThen(
|
||||
Collectors.toList(), Collections::unmodifiableList));
|
||||
return createEndpoint(endpointBean.getBean(), id,
|
||||
endpointBean.isEnabledByDefault(), operations);
|
||||
List<O> operations = indexed.values().stream().map(this::getLast).filter(Objects::nonNull)
|
||||
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
|
||||
return createEndpoint(endpointBean.getBean(), id, endpointBean.isEnabledByDefault(), operations);
|
||||
}
|
||||
|
||||
private void addOperations(MultiValueMap<OperationKey, O> indexed, EndpointId id,
|
||||
Object target, boolean replaceLast) {
|
||||
private void addOperations(MultiValueMap<OperationKey, O> indexed, EndpointId id, Object target,
|
||||
boolean replaceLast) {
|
||||
Set<OperationKey> replacedLast = new HashSet<>();
|
||||
Collection<O> operations = this.operationsFactory.createOperations(id, target);
|
||||
for (O operation : operations) {
|
||||
@@ -232,27 +216,21 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
return CollectionUtils.isEmpty(list) ? null : list.get(list.size() - 1);
|
||||
}
|
||||
|
||||
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)
|
||||
.collect(Collectors.toList());
|
||||
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).collect(Collectors.toList());
|
||||
if (!duplicates.isEmpty()) {
|
||||
Set<ExtensionBean> extensions = endpointBean.getExtensions();
|
||||
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 + ")"));
|
||||
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 + ")"));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isExtensionExposed(EndpointBean endpointBean,
|
||||
ExtensionBean extensionBean) {
|
||||
return isFilterMatch(extensionBean.getFilter(), endpointBean)
|
||||
&& isExtensionExposed(extensionBean.getBean());
|
||||
private boolean isExtensionExposed(EndpointBean endpointBean, ExtensionBean extensionBean) {
|
||||
return isFilterMatch(extensionBean.getFilter(), endpointBean) && isExtensionExposed(extensionBean.getBean());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,8 +244,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
}
|
||||
|
||||
private boolean isEndpointExposed(EndpointBean endpointBean) {
|
||||
return isFilterMatch(endpointBean.getFilter(), endpointBean)
|
||||
&& !isEndpointFiltered(endpointBean)
|
||||
return isFilterMatch(endpointBean.getFilter(), endpointBean) && !isEndpointFiltered(endpointBean)
|
||||
&& isEndpointExposed(endpointBean.getBean());
|
||||
}
|
||||
|
||||
@@ -299,11 +276,9 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
return true;
|
||||
}
|
||||
E endpoint = getFilterEndpoint(endpointBean);
|
||||
Class<?> generic = ResolvableType.forClass(EndpointFilter.class, filter)
|
||||
.resolveGeneric(0);
|
||||
Class<?> generic = ResolvableType.forClass(EndpointFilter.class, filter).resolveGeneric(0);
|
||||
if (generic == null || generic.isInstance(endpoint)) {
|
||||
EndpointFilter<E> instance = (EndpointFilter<E>) BeanUtils
|
||||
.instantiateClass(filter);
|
||||
EndpointFilter<E> instance = (EndpointFilter<E>) BeanUtils.instantiateClass(filter);
|
||||
return isFilterMatch(instance, endpoint);
|
||||
}
|
||||
return false;
|
||||
@@ -316,16 +291,15 @@ 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) {
|
||||
E endpoint = this.filterEndpoints.get(endpointBean);
|
||||
if (endpoint == null) {
|
||||
endpoint = createEndpoint(endpointBean.getBean(), endpointBean.getId(),
|
||||
endpointBean.isEnabledByDefault(), Collections.emptySet());
|
||||
endpoint = createEndpoint(endpointBean.getBean(), endpointBean.getId(), endpointBean.isEnabledByDefault(),
|
||||
Collections.emptySet());
|
||||
this.filterEndpoints.put(endpointBean, endpoint);
|
||||
}
|
||||
return endpoint;
|
||||
@@ -333,8 +307,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Class<? extends E> getEndpointType() {
|
||||
return (Class<? extends E>) ResolvableType
|
||||
.forClass(EndpointDiscoverer.class, getClass()).resolveGeneric(0);
|
||||
return (Class<? extends E>) ResolvableType.forClass(EndpointDiscoverer.class, getClass()).resolveGeneric(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,10 +319,8 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
* @return a created endpoint (a {@link DiscoveredEndpoint} is recommended)
|
||||
* @since 2.0.6
|
||||
*/
|
||||
protected E createEndpoint(Object endpointBean, EndpointId id,
|
||||
boolean enabledByDefault, Collection<O> operations) {
|
||||
return createEndpoint(endpointBean, (id != null) ? id.toString() : null,
|
||||
enabledByDefault, operations);
|
||||
protected E createEndpoint(Object endpointBean, EndpointId id, boolean enabledByDefault, Collection<O> operations) {
|
||||
return createEndpoint(endpointBean, (id != null) ? id.toString() : null, enabledByDefault, operations);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -363,8 +334,8 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
* {@link #createEndpoint(Object, EndpointId, boolean, Collection)}
|
||||
*/
|
||||
@Deprecated
|
||||
protected abstract E createEndpoint(Object endpointBean, String id,
|
||||
boolean enabledByDefault, Collection<O> operations);
|
||||
protected abstract E createEndpoint(Object endpointBean, String id, boolean enabledByDefault,
|
||||
Collection<O> operations);
|
||||
|
||||
/**
|
||||
* Factory method to create an {@link Operation endpoint operation}.
|
||||
@@ -374,10 +345,9 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
* @return a created operation
|
||||
* @since 2.0.6
|
||||
*/
|
||||
protected O createOperation(EndpointId endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
return createOperation((endpointId != null) ? endpointId.toString() : null,
|
||||
operationMethod, invoker);
|
||||
protected O createOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker) {
|
||||
return createOperation((endpointId != null) ? endpointId.toString() : null, operationMethod, invoker);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -390,8 +360,8 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
* {@link #createOperation(EndpointId, DiscoveredOperationMethod, OperationInvoker)}
|
||||
*/
|
||||
@Deprecated
|
||||
protected abstract O createOperation(String endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker);
|
||||
protected abstract O createOperation(String endpointId, DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker);
|
||||
|
||||
/**
|
||||
* Create an {@link OperationKey} for the given operation.
|
||||
@@ -463,13 +433,11 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
private Set<ExtensionBean> extensions = new LinkedHashSet<>();
|
||||
|
||||
EndpointBean(String beanName, Object bean) {
|
||||
AnnotationAttributes attributes = AnnotatedElementUtils
|
||||
.findMergedAnnotationAttributes(bean.getClass(), Endpoint.class, true,
|
||||
true);
|
||||
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(bean.getClass(),
|
||||
Endpoint.class, true, true);
|
||||
String id = attributes.getString("id");
|
||||
Assert.state(StringUtils.hasText(id),
|
||||
() -> "No @Endpoint id attribute specified for "
|
||||
+ bean.getClass().getName());
|
||||
() -> "No @Endpoint id attribute specified for " + bean.getClass().getName());
|
||||
this.beanName = beanName;
|
||||
this.bean = bean;
|
||||
this.id = EndpointId.of(id);
|
||||
@@ -486,8 +454,8 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
}
|
||||
|
||||
private Class<?> getFilter(Class<?> type) {
|
||||
AnnotationAttributes attributes = AnnotatedElementUtils
|
||||
.getMergedAnnotationAttributes(type, FilteredEndpoint.class);
|
||||
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(type,
|
||||
FilteredEndpoint.class);
|
||||
if (attributes == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -532,15 +500,13 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
|
||||
ExtensionBean(String beanName, Object bean) {
|
||||
this.bean = bean;
|
||||
this.beanName = beanName;
|
||||
AnnotationAttributes attributes = AnnotatedElementUtils
|
||||
.getMergedAnnotationAttributes(bean.getClass(),
|
||||
EndpointExtension.class);
|
||||
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(bean.getClass(),
|
||||
EndpointExtension.class);
|
||||
Class<?> endpointType = attributes.getClass("endpoint");
|
||||
AnnotationAttributes endpointAttributes = AnnotatedElementUtils
|
||||
.findMergedAnnotationAttributes(endpointType, Endpoint.class, true,
|
||||
true);
|
||||
Assert.state(endpointAttributes != null, () -> "Extension "
|
||||
+ endpointType.getName() + " does not specify an endpoint");
|
||||
AnnotationAttributes endpointAttributes = AnnotatedElementUtils.findMergedAnnotationAttributes(endpointType,
|
||||
Endpoint.class, true, true);
|
||||
Assert.state(endpointAttributes != null,
|
||||
() -> "Extension " + endpointType.getName() + " does not specify an endpoint");
|
||||
this.endpointId = EndpointId.of(endpointAttributes.getString("id"));
|
||||
this.filter = attributes.getClass("filter");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,12 +35,10 @@ public final class MissingParametersException extends InvalidEndpointRequestExce
|
||||
private final Set<OperationParameter> missingParameters;
|
||||
|
||||
public MissingParametersException(Set<OperationParameter> missingParameters) {
|
||||
super("Failed to invoke operation because the following required "
|
||||
+ "parameters were missing: "
|
||||
super("Failed to invoke operation because the following required " + "parameters were missing: "
|
||||
+ StringUtils.collectionToCommaDelimitedString(missingParameters),
|
||||
"Missing parameters: "
|
||||
+ missingParameters.stream().map(OperationParameter::getName)
|
||||
.collect(Collectors.joining(",")));
|
||||
+ missingParameters.stream().map(OperationParameter::getName).collect(Collectors.joining(",")));
|
||||
this.missingParameters = missingParameters;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,10 +37,9 @@ public interface OperationInvokerAdvisor {
|
||||
* @return an potentially new operation invoker with support for additional features
|
||||
* @since 2.0.6
|
||||
*/
|
||||
default OperationInvoker apply(EndpointId endpointId, OperationType operationType,
|
||||
OperationParameters parameters, OperationInvoker invoker) {
|
||||
return apply((endpointId != null) ? endpointId.toString() : null, operationType,
|
||||
parameters, invoker);
|
||||
default OperationInvoker apply(EndpointId endpointId, OperationType operationType, OperationParameters parameters,
|
||||
OperationInvoker invoker) {
|
||||
return apply((endpointId != null) ? endpointId.toString() : null, operationType, parameters, invoker);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +53,7 @@ public interface OperationInvokerAdvisor {
|
||||
* {@link #apply(EndpointId, OperationType, OperationParameters, OperationInvoker)}
|
||||
*/
|
||||
@Deprecated
|
||||
OperationInvoker apply(String endpointId, OperationType operationType,
|
||||
OperationParameters parameters, OperationInvoker invoker);
|
||||
OperationInvoker apply(String endpointId, OperationType operationType, OperationParameters parameters,
|
||||
OperationInvoker invoker);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,10 +38,9 @@ public final class ParameterMappingException extends InvalidEndpointRequestExcep
|
||||
* @param value the value being mapped
|
||||
* @param cause the cause of the mapping failure
|
||||
*/
|
||||
public ParameterMappingException(OperationParameter parameter, Object value,
|
||||
Throwable cause) {
|
||||
super("Failed to map " + value + " of type " + value.getClass() + " to "
|
||||
+ parameter, "Parameter mapping failure", cause);
|
||||
public ParameterMappingException(OperationParameter parameter, Object value, Throwable cause) {
|
||||
super("Failed to map " + value + " of type " + value.getClass() + " to " + parameter,
|
||||
"Parameter mapping failure", cause);
|
||||
this.parameter = parameter;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,7 +37,6 @@ public interface ParameterValueMapper {
|
||||
* @return a value suitable for that parameter
|
||||
* @throws ParameterMappingException when a mapping failure occurs
|
||||
*/
|
||||
Object mapParameterValue(OperationParameter parameter, Object value)
|
||||
throws ParameterMappingException;
|
||||
Object mapParameterValue(OperationParameter parameter, Object value) throws ParameterMappingException;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -52,8 +52,7 @@ public class ConversionServiceParameterValueMapper implements ParameterValueMapp
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object mapParameterValue(OperationParameter parameter, Object value)
|
||||
throws ParameterMappingException {
|
||||
public Object mapParameterValue(OperationParameter parameter, Object value) throws ParameterMappingException {
|
||||
try {
|
||||
return this.conversionService.convert(value, parameter.getType());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -52,8 +52,7 @@ public class OperationMethod {
|
||||
Assert.notNull(operationType, "OperationType must not be null");
|
||||
this.method = method;
|
||||
this.operationType = operationType;
|
||||
this.operationParameters = new OperationMethodParameters(method,
|
||||
DEFAULT_PARAMETER_NAME_DISCOVERER);
|
||||
this.operationParameters = new OperationMethodParameters(method, DEFAULT_PARAMETER_NAME_DISCOVERER);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,8 +81,7 @@ public class OperationMethod {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Operation " + this.operationType.name().toLowerCase(Locale.ENGLISH)
|
||||
+ " method " + this.method;
|
||||
return "Operation " + this.operationType.name().toLowerCase(Locale.ENGLISH) + " method " + this.method;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -43,24 +43,19 @@ class OperationMethodParameters implements OperationParameters {
|
||||
* @param method the source method
|
||||
* @param parameterNameDiscoverer the parameter name discoverer
|
||||
*/
|
||||
OperationMethodParameters(Method method,
|
||||
ParameterNameDiscoverer parameterNameDiscoverer) {
|
||||
OperationMethodParameters(Method method, ParameterNameDiscoverer parameterNameDiscoverer) {
|
||||
Assert.notNull(method, "Method must not be null");
|
||||
Assert.notNull(parameterNameDiscoverer,
|
||||
"ParameterNameDiscoverer must not be null");
|
||||
Assert.notNull(parameterNameDiscoverer, "ParameterNameDiscoverer must not be null");
|
||||
String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
|
||||
Parameter[] parameters = method.getParameters();
|
||||
Assert.state(parameterNames != null,
|
||||
() -> "Failed to extract parameter names for " + method);
|
||||
Assert.state(parameterNames != null, () -> "Failed to extract parameter names for " + method);
|
||||
this.operationParameters = getOperationParameters(parameters, parameterNames);
|
||||
}
|
||||
|
||||
private List<OperationParameter> getOperationParameters(Parameter[] parameters,
|
||||
String[] names) {
|
||||
private List<OperationParameter> getOperationParameters(Parameter[] parameters, String[] names) {
|
||||
List<OperationParameter> operationParameters = new ArrayList<>(parameters.length);
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
operationParameters
|
||||
.add(new OperationMethodParameter(names[i], parameters[i]));
|
||||
operationParameters.add(new OperationMethodParameter(names[i], parameters[i]));
|
||||
}
|
||||
return Collections.unmodifiableList(operationParameters);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -78,8 +78,7 @@ 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());
|
||||
.filter((parameter) -> isMissing(context, parameter)).collect(Collectors.toSet());
|
||||
if (!missing.isEmpty()) {
|
||||
throw new MissingParametersException(missing);
|
||||
}
|
||||
@@ -99,12 +98,11 @@ 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) {
|
||||
private Object resolveArgument(OperationParameter parameter, InvocationContext context) {
|
||||
if (Principal.class.equals(parameter.getType())) {
|
||||
return context.getSecurityContext().getPrincipal();
|
||||
}
|
||||
@@ -117,8 +115,8 @@ 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-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,21 +36,20 @@ public class CachingOperationInvokerAdvisor implements OperationInvokerAdvisor {
|
||||
|
||||
private final Function<EndpointId, Long> endpointIdTimeToLive;
|
||||
|
||||
public CachingOperationInvokerAdvisor(
|
||||
Function<EndpointId, Long> endpointIdTimeToLive) {
|
||||
public CachingOperationInvokerAdvisor(Function<EndpointId, Long> endpointIdTimeToLive) {
|
||||
this.endpointIdTimeToLive = endpointIdTimeToLive;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public OperationInvoker apply(String endpointId, OperationType operationType,
|
||||
OperationParameters parameters, OperationInvoker invoker) {
|
||||
public OperationInvoker apply(String endpointId, OperationType operationType, OperationParameters parameters,
|
||||
OperationInvoker invoker) {
|
||||
return apply(EndpointId.of(endpointId), operationType, parameters, invoker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationInvoker apply(EndpointId endpointId, OperationType operationType,
|
||||
OperationParameters parameters, OperationInvoker invoker) {
|
||||
public OperationInvoker apply(EndpointId endpointId, OperationType operationType, OperationParameters parameters,
|
||||
OperationInvoker invoker) {
|
||||
if (operationType == OperationType.READ && !hasMandatoryParameter(parameters)) {
|
||||
Long timeToLive = this.endpointIdTimeToLive.apply(endpointId);
|
||||
if (timeToLive != null && timeToLive > 0) {
|
||||
@@ -62,8 +61,7 @@ public class CachingOperationInvokerAdvisor implements OperationInvokerAdvisor {
|
||||
|
||||
private boolean hasMandatoryParameter(OperationParameters parameters) {
|
||||
for (OperationParameter parameter : parameters) {
|
||||
if (parameter.isMandatory()
|
||||
&& !SecurityContext.class.isAssignableFrom(parameter.getType())) {
|
||||
if (parameter.isMandatory() && !SecurityContext.class.isAssignableFrom(parameter.getType())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -48,8 +48,8 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public class EndpointMBean implements DynamicMBean {
|
||||
|
||||
private static final boolean REACTOR_PRESENT = ClassUtils.isPresent(
|
||||
"reactor.core.publisher.Mono", EndpointMBean.class.getClassLoader());
|
||||
private static final boolean REACTOR_PRESENT = ClassUtils.isPresent("reactor.core.publisher.Mono",
|
||||
EndpointMBean.class.getClassLoader());
|
||||
|
||||
private final JmxOperationResponseMapper responseMapper;
|
||||
|
||||
@@ -61,8 +61,7 @@ public class EndpointMBean implements DynamicMBean {
|
||||
|
||||
private final Map<String, JmxOperation> operations;
|
||||
|
||||
EndpointMBean(JmxOperationResponseMapper responseMapper, ClassLoader classLoader,
|
||||
ExposableJmxEndpoint endpoint) {
|
||||
EndpointMBean(JmxOperationResponseMapper responseMapper, ClassLoader classLoader, ExposableJmxEndpoint endpoint) {
|
||||
Assert.notNull(responseMapper, "ResponseMapper must not be null");
|
||||
Assert.notNull(endpoint, "Endpoint must not be null");
|
||||
this.responseMapper = responseMapper;
|
||||
@@ -74,8 +73,7 @@ public class EndpointMBean implements DynamicMBean {
|
||||
|
||||
private Map<String, JmxOperation> getOperations(ExposableJmxEndpoint endpoint) {
|
||||
Map<String, JmxOperation> operations = new HashMap<>();
|
||||
endpoint.getOperations()
|
||||
.forEach((operation) -> operations.put(operation.getName(), operation));
|
||||
endpoint.getOperations().forEach((operation) -> operations.put(operation.getName(), operation));
|
||||
return Collections.unmodifiableMap(operations);
|
||||
}
|
||||
|
||||
@@ -89,12 +87,11 @@ public class EndpointMBean implements DynamicMBean {
|
||||
throws MBeanException, ReflectionException {
|
||||
JmxOperation operation = this.operations.get(actionName);
|
||||
if (operation == null) {
|
||||
String message = "Endpoint with id '" + this.endpoint.getEndpointId()
|
||||
+ "' has no operation named " + actionName;
|
||||
String message = "Endpoint with id '" + this.endpoint.getEndpointId() + "' has no operation named "
|
||||
+ actionName;
|
||||
throw new ReflectionException(new IllegalArgumentException(message), message);
|
||||
}
|
||||
ClassLoader previousClassLoader = overrideThreadContextClassLoader(
|
||||
this.classLoader);
|
||||
ClassLoader previousClassLoader = overrideThreadContextClassLoader(this.classLoader);
|
||||
try {
|
||||
return invoke(operation, params);
|
||||
}
|
||||
@@ -115,14 +112,12 @@ public class EndpointMBean implements DynamicMBean {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object invoke(JmxOperation operation, Object[] params)
|
||||
throws MBeanException, ReflectionException {
|
||||
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);
|
||||
InvocationContext context = new InvocationContext(SecurityContext.NONE, arguments);
|
||||
Object result = operation.invoke(context);
|
||||
if (REACTOR_PRESENT) {
|
||||
result = ReactiveHandler.handle(result);
|
||||
@@ -130,8 +125,7 @@ public class EndpointMBean implements DynamicMBean {
|
||||
return this.responseMapper.mapResponse(result);
|
||||
}
|
||||
catch (InvalidEndpointRequestException ex) {
|
||||
throw new ReflectionException(new IllegalArgumentException(ex.getMessage()),
|
||||
ex.getMessage());
|
||||
throw new ReflectionException(new IllegalArgumentException(ex.getMessage()), ex.getMessage());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new MBeanException(translateIfNecessary(ex), ex.getMessage());
|
||||
@@ -160,8 +154,8 @@ public class EndpointMBean implements DynamicMBean {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(Attribute attribute) throws AttributeNotFoundException,
|
||||
InvalidAttributeValueException, MBeanException, ReflectionException {
|
||||
public void setAttribute(Attribute attribute)
|
||||
throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
|
||||
throw new AttributeNotFoundException("EndpointMBeans do not support attributes");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,7 +35,6 @@ public interface EndpointObjectNameFactory {
|
||||
* @return the {@link ObjectName} to use for the endpoint
|
||||
* @throws MalformedObjectNameException if the object name is invalid
|
||||
*/
|
||||
ObjectName getObjectName(ExposableJmxEndpoint endpoint)
|
||||
throws MalformedObjectNameException;
|
||||
ObjectName getObjectName(ExposableJmxEndpoint endpoint) throws MalformedObjectNameException;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,10 +40,9 @@ 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.listType = this.objectMapper.getTypeFactory().constructParametricType(List.class, Object.class);
|
||||
this.mapType = this.objectMapper.getTypeFactory().constructParametricType(Map.class, String.class,
|
||||
Object.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -43,8 +43,7 @@ import org.springframework.util.Assert;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class JmxEndpointExporter
|
||||
implements InitializingBean, DisposableBean, BeanClassLoaderAware {
|
||||
public class JmxEndpointExporter implements InitializingBean, DisposableBean, BeanClassLoaderAware {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JmxEndpointExporter.class);
|
||||
|
||||
@@ -60,10 +59,8 @@ public class JmxEndpointExporter
|
||||
|
||||
private Collection<ObjectName> registered;
|
||||
|
||||
public JmxEndpointExporter(MBeanServer mBeanServer,
|
||||
EndpointObjectNameFactory objectNameFactory,
|
||||
JmxOperationResponseMapper responseMapper,
|
||||
Collection<? extends ExposableJmxEndpoint> endpoints) {
|
||||
public JmxEndpointExporter(MBeanServer mBeanServer, EndpointObjectNameFactory objectNameFactory,
|
||||
JmxOperationResponseMapper responseMapper, Collection<? extends ExposableJmxEndpoint> endpoints) {
|
||||
Assert.notNull(mBeanServer, "MBeanServer must not be null");
|
||||
Assert.notNull(objectNameFactory, "ObjectNameFactory must not be null");
|
||||
Assert.notNull(responseMapper, "ResponseMapper must not be null");
|
||||
@@ -97,19 +94,15 @@ public class JmxEndpointExporter
|
||||
Assert.notNull(endpoint, "Endpoint must not be null");
|
||||
try {
|
||||
ObjectName name = this.objectNameFactory.getObjectName(endpoint);
|
||||
EndpointMBean mbean = new EndpointMBean(this.responseMapper, this.classLoader,
|
||||
endpoint);
|
||||
EndpointMBean mbean = new EndpointMBean(this.responseMapper, this.classLoader, endpoint);
|
||||
this.mBeanServer.registerMBean(mbean, name);
|
||||
return name;
|
||||
}
|
||||
catch (MalformedObjectNameException ex) {
|
||||
throw new IllegalStateException(
|
||||
"Invalid ObjectName for " + getEndpointDescription(endpoint), ex);
|
||||
throw new IllegalStateException("Invalid ObjectName for " + getEndpointDescription(endpoint), ex);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new MBeanExportException(
|
||||
"Failed to register MBean for " + getEndpointDescription(endpoint),
|
||||
ex);
|
||||
throw new MBeanExportException("Failed to register MBean for " + getEndpointDescription(endpoint), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,8 +113,7 @@ public class JmxEndpointExporter
|
||||
private void unregister(ObjectName objectName) {
|
||||
try {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Unregister endpoint with ObjectName '" + objectName + "' "
|
||||
+ "from the JMX domain");
|
||||
logger.debug("Unregister endpoint with ObjectName '" + objectName + "' " + "from the JMX domain");
|
||||
}
|
||||
this.mBeanServer.unregisterMBean(objectName);
|
||||
}
|
||||
@@ -129,9 +121,7 @@ public class JmxEndpointExporter
|
||||
// Ignore and continue
|
||||
}
|
||||
catch (MBeanRegistrationException ex) {
|
||||
throw new JmxException(
|
||||
"Failed to unregister MBean with ObjectName '" + objectName + "'",
|
||||
ex);
|
||||
throw new JmxException("Failed to unregister MBean with ObjectName '" + objectName + "'", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -53,8 +53,8 @@ class MBeanInfoFactory {
|
||||
String className = EndpointMBean.class.getName();
|
||||
String description = getDescription(endpoint);
|
||||
ModelMBeanOperationInfo[] operations = getMBeanOperations(endpoint);
|
||||
return new ModelMBeanInfoSupport(className, description, NO_ATTRIBUTES,
|
||||
NO_CONSTRUCTORS, operations, NO_NOTIFICATIONS);
|
||||
return new ModelMBeanInfoSupport(className, description, NO_ATTRIBUTES, NO_CONSTRUCTORS, operations,
|
||||
NO_NOTIFICATIONS);
|
||||
}
|
||||
|
||||
private String getDescription(ExposableJmxEndpoint endpoint) {
|
||||
@@ -62,8 +62,7 @@ class MBeanInfoFactory {
|
||||
}
|
||||
|
||||
private ModelMBeanOperationInfo[] getMBeanOperations(ExposableJmxEndpoint endpoint) {
|
||||
return endpoint.getOperations().stream().map(this::getMBeanOperation)
|
||||
.toArray(ModelMBeanOperationInfo[]::new);
|
||||
return endpoint.getOperations().stream().map(this::getMBeanOperation).toArray(ModelMBeanOperationInfo[]::new);
|
||||
}
|
||||
|
||||
private ModelMBeanOperationInfo getMBeanOperation(JmxOperation operation) {
|
||||
@@ -76,21 +75,18 @@ class MBeanInfoFactory {
|
||||
}
|
||||
|
||||
private MBeanParameterInfo[] getSignature(List<JmxOperationParameter> parameters) {
|
||||
return parameters.stream().map(this::getMBeanParameter)
|
||||
.toArray(MBeanParameterInfo[]::new);
|
||||
return parameters.stream().map(this::getMBeanParameter).toArray(MBeanParameterInfo[]::new);
|
||||
}
|
||||
|
||||
private MBeanParameterInfo getMBeanParameter(JmxOperationParameter parameter) {
|
||||
return new MBeanParameterInfo(parameter.getName(), parameter.getType().getName(),
|
||||
parameter.getDescription());
|
||||
return new MBeanParameterInfo(parameter.getName(), parameter.getType().getName(), parameter.getDescription());
|
||||
}
|
||||
|
||||
private int getImpact(OperationType operationType) {
|
||||
if (operationType == OperationType.READ) {
|
||||
return MBeanOperationInfo.INFO;
|
||||
}
|
||||
if (operationType == OperationType.WRITE
|
||||
|| operationType == OperationType.DELETE) {
|
||||
if (operationType == OperationType.WRITE || operationType == OperationType.DELETE) {
|
||||
return MBeanOperationInfo.ACTION;
|
||||
}
|
||||
return MBeanOperationInfo.UNKNOWN;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,12 +29,10 @@ import org.springframework.boot.actuate.endpoint.jmx.JmxOperation;
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DiscoveredJmxEndpoint extends AbstractDiscoveredEndpoint<JmxOperation>
|
||||
implements ExposableJmxEndpoint {
|
||||
class DiscoveredJmxEndpoint extends AbstractDiscoveredEndpoint<JmxOperation> implements ExposableJmxEndpoint {
|
||||
|
||||
DiscoveredJmxEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
||||
EndpointId id, boolean enabledByDefault,
|
||||
Collection<JmxOperation> operations) {
|
||||
DiscoveredJmxEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean, EndpointId id,
|
||||
boolean enabledByDefault, Collection<JmxOperation> operations) {
|
||||
super(discoverer, endpointBean, id, enabledByDefault, operations);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -60,14 +60,12 @@ class DiscoveredJmxOperation extends AbstractDiscoveredOperation implements JmxO
|
||||
|
||||
private final List<JmxOperationParameter> parameters;
|
||||
|
||||
DiscoveredJmxOperation(EndpointId endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
DiscoveredJmxOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
super(operationMethod, invoker);
|
||||
Method method = operationMethod.getMethod();
|
||||
this.name = method.getName();
|
||||
this.outputType = JmxType.get(method.getReturnType());
|
||||
this.description = getDescription(method,
|
||||
() -> "Invoke " + this.name + " for endpoint " + endpointId);
|
||||
this.description = getDescription(method, () -> "Invoke " + this.name + " for endpoint " + endpointId);
|
||||
this.parameters = getParameters(operationMethod);
|
||||
}
|
||||
|
||||
@@ -84,29 +82,24 @@ class DiscoveredJmxOperation extends AbstractDiscoveredOperation implements JmxO
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Method method = operationMethod.getMethod();
|
||||
ManagedOperationParameter[] managed = jmxAttributeSource
|
||||
.getManagedOperationParameters(method);
|
||||
ManagedOperationParameter[] managed = jmxAttributeSource.getManagedOperationParameters(method);
|
||||
if (managed.length == 0) {
|
||||
return asList(operationMethod.getParameters().stream()
|
||||
.map(DiscoveredJmxOperationParameter::new));
|
||||
return asList(operationMethod.getParameters().stream().map(DiscoveredJmxOperationParameter::new));
|
||||
}
|
||||
return mergeParameters(operationMethod.getParameters(), managed);
|
||||
}
|
||||
|
||||
private List<JmxOperationParameter> mergeParameters(
|
||||
OperationParameters operationParameters,
|
||||
private List<JmxOperationParameter> mergeParameters(OperationParameters operationParameters,
|
||||
ManagedOperationParameter[] managedParameters) {
|
||||
List<JmxOperationParameter> merged = new ArrayList<>(managedParameters.length);
|
||||
for (int i = 0; i < managedParameters.length; i++) {
|
||||
merged.add(new DiscoveredJmxOperationParameter(managedParameters[i],
|
||||
operationParameters.get(i)));
|
||||
merged.add(new DiscoveredJmxOperationParameter(managedParameters[i], operationParameters.get(i)));
|
||||
}
|
||||
return Collections.unmodifiableList(merged);
|
||||
}
|
||||
|
||||
private <T> List<T> asList(Stream<T> stream) {
|
||||
return stream.collect(Collectors.collectingAndThen(Collectors.toList(),
|
||||
Collections::unmodifiableList));
|
||||
return stream.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,16 +124,14 @@ 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)
|
||||
creator.append("name", this.name).append("outputType", this.outputType).append("description", this.description)
|
||||
.append("parameters", this.parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* A discovered {@link JmxOperationParameter}.
|
||||
*/
|
||||
private static class DiscoveredJmxOperationParameter
|
||||
implements JmxOperationParameter {
|
||||
private static class DiscoveredJmxOperationParameter implements JmxOperationParameter {
|
||||
|
||||
private final String name;
|
||||
|
||||
@@ -197,8 +188,7 @@ class DiscoveredJmxOperation extends AbstractDiscoveredOperation implements JmxO
|
||||
if (source.isEnum()) {
|
||||
return String.class;
|
||||
}
|
||||
if (Date.class.isAssignableFrom(source)
|
||||
|| Instant.class.isAssignableFrom(source)) {
|
||||
if (Date.class.isAssignableFrom(source) || Instant.class.isAssignableFrom(source)) {
|
||||
return String.class;
|
||||
}
|
||||
if (source.getName().startsWith("java.")) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,8 +36,7 @@ import org.springframework.context.ApplicationContext;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class JmxEndpointDiscoverer
|
||||
extends EndpointDiscoverer<ExposableJmxEndpoint, JmxOperation>
|
||||
public class JmxEndpointDiscoverer extends EndpointDiscoverer<ExposableJmxEndpoint, JmxOperation>
|
||||
implements JmxEndpointsSupplier {
|
||||
|
||||
/**
|
||||
@@ -47,8 +46,7 @@ public class JmxEndpointDiscoverer
|
||||
* @param invokerAdvisors invoker advisors to apply
|
||||
* @param filters filters to apply
|
||||
*/
|
||||
public JmxEndpointDiscoverer(ApplicationContext applicationContext,
|
||||
ParameterValueMapper parameterValueMapper,
|
||||
public JmxEndpointDiscoverer(ApplicationContext applicationContext, ParameterValueMapper parameterValueMapper,
|
||||
Collection<OperationInvokerAdvisor> invokerAdvisors,
|
||||
Collection<EndpointFilter<ExposableJmxEndpoint>> filters) {
|
||||
super(applicationContext, parameterValueMapper, invokerAdvisors, filters);
|
||||
@@ -56,36 +54,33 @@ public class JmxEndpointDiscoverer
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
protected ExposableJmxEndpoint createEndpoint(Object endpointBean, String id,
|
||||
boolean enabledByDefault, Collection<JmxOperation> operations) {
|
||||
return createEndpoint(endpointBean, EndpointId.of(id), enabledByDefault,
|
||||
operations);
|
||||
protected ExposableJmxEndpoint createEndpoint(Object endpointBean, String id, boolean enabledByDefault,
|
||||
Collection<JmxOperation> operations) {
|
||||
return createEndpoint(endpointBean, EndpointId.of(id), enabledByDefault, operations);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ExposableJmxEndpoint createEndpoint(Object endpointBean, EndpointId id,
|
||||
boolean enabledByDefault, Collection<JmxOperation> operations) {
|
||||
return new DiscoveredJmxEndpoint(this, endpointBean, id, enabledByDefault,
|
||||
operations);
|
||||
protected ExposableJmxEndpoint createEndpoint(Object endpointBean, EndpointId id, boolean enabledByDefault,
|
||||
Collection<JmxOperation> operations) {
|
||||
return new DiscoveredJmxEndpoint(this, endpointBean, id, enabledByDefault, operations);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
protected JmxOperation createOperation(String endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
protected JmxOperation createOperation(String endpointId, DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker) {
|
||||
return createOperation(EndpointId.of(endpointId), operationMethod, invoker);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JmxOperation createOperation(EndpointId endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
protected JmxOperation createOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker) {
|
||||
return new DiscoveredJmxOperation(endpointId, operationMethod, invoker);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OperationKey createOperationKey(JmxOperation operation) {
|
||||
return new OperationKey(operation.getName(),
|
||||
() -> "MBean call '" + operation.getName() + "'");
|
||||
return new OperationKey(operation.getName(), () -> "MBean call '" + operation.getName() + "'");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -52,12 +52,10 @@ public class EndpointLinksResolver {
|
||||
* @param endpoints the endpoints
|
||||
* @param basePath the basePath
|
||||
*/
|
||||
public EndpointLinksResolver(Collection<? extends ExposableEndpoint<?>> endpoints,
|
||||
String basePath) {
|
||||
public EndpointLinksResolver(Collection<? extends ExposableEndpoint<?>> endpoints, String basePath) {
|
||||
this.endpoints = endpoints;
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Exposing " + endpoints.size()
|
||||
+ " endpoint(s) beneath base path '" + basePath + "'");
|
||||
logger.info("Exposing " + endpoints.size() + " endpoint(s) beneath base path '" + basePath + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,8 +89,7 @@ public class EndpointLinksResolver {
|
||||
return requestUrl;
|
||||
}
|
||||
|
||||
private void collectLinks(Map<String, Link> links, ExposableWebEndpoint endpoint,
|
||||
String normalizedUrl) {
|
||||
private void collectLinks(Map<String, Link> links, ExposableWebEndpoint endpoint, String normalizedUrl) {
|
||||
for (WebOperation operation : endpoint.getOperations()) {
|
||||
links.put(operation.getId(), createLink(normalizedUrl, operation));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -61,11 +61,9 @@ public final class EndpointServlet {
|
||||
|
||||
public EndpointServlet withInitParameters(Map<String, String> initParameters) {
|
||||
Assert.notNull(initParameters, "InitParameters must not be null");
|
||||
boolean hasEmptyName = initParameters.keySet().stream()
|
||||
.anyMatch((name) -> !StringUtils.hasText(name));
|
||||
boolean hasEmptyName = initParameters.keySet().stream().anyMatch((name) -> !StringUtils.hasText(name));
|
||||
Assert.isTrue(!hasEmptyName, "InitParameters must not contain empty names");
|
||||
Map<String, String> mergedInitParameters = new LinkedHashMap<>(
|
||||
this.initParameters);
|
||||
Map<String, String> mergedInitParameters = new LinkedHashMap<>(this.initParameters);
|
||||
mergedInitParameters.putAll(initParameters);
|
||||
return new EndpointServlet(this.servlet, mergedInitParameters);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,8 +25,7 @@ import org.springframework.boot.actuate.endpoint.Operation;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public interface ExposableServletEndpoint
|
||||
extends ExposableEndpoint<Operation>, PathMappedEndpoint {
|
||||
public interface ExposableServletEndpoint extends ExposableEndpoint<Operation>, PathMappedEndpoint {
|
||||
|
||||
/**
|
||||
* Return details of the servlet that should registered.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,6 @@ import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public interface ExposableWebEndpoint
|
||||
extends ExposableEndpoint<WebOperation>, PathMappedEndpoint {
|
||||
public interface ExposableWebEndpoint extends ExposableEndpoint<WebOperation>, PathMappedEndpoint {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -56,21 +56,18 @@ public class PathMappedEndpoints implements Iterable<PathMappedEndpoint> {
|
||||
* @param basePath the base path of the endpoints
|
||||
* @param suppliers the endpoint suppliers
|
||||
*/
|
||||
public PathMappedEndpoints(String basePath,
|
||||
Collection<EndpointsSupplier<?>> suppliers) {
|
||||
public PathMappedEndpoints(String basePath, Collection<EndpointsSupplier<?>> suppliers) {
|
||||
Assert.notNull(suppliers, "Suppliers must not be null");
|
||||
this.basePath = (basePath != null) ? basePath : "";
|
||||
this.endpoints = getEndpoints(suppliers);
|
||||
}
|
||||
|
||||
private Map<EndpointId, PathMappedEndpoint> getEndpoints(
|
||||
Collection<EndpointsSupplier<?>> suppliers) {
|
||||
private Map<EndpointId, PathMappedEndpoint> getEndpoints(Collection<EndpointsSupplier<?>> suppliers) {
|
||||
Map<EndpointId, PathMappedEndpoint> endpoints = new LinkedHashMap<>();
|
||||
suppliers.forEach((supplier) -> {
|
||||
supplier.getEndpoints().forEach((endpoint) -> {
|
||||
if (endpoint instanceof PathMappedEndpoint) {
|
||||
endpoints.put(endpoint.getEndpointId(),
|
||||
(PathMappedEndpoint) endpoint);
|
||||
endpoints.put(endpoint.getEndpointId(), (PathMappedEndpoint) endpoint);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -189,8 +186,7 @@ public class PathMappedEndpoints implements Iterable<PathMappedEndpoint> {
|
||||
}
|
||||
|
||||
private <T> List<T> asList(Stream<T> stream) {
|
||||
return stream.collect(Collectors.collectingAndThen(Collectors.toList(),
|
||||
Collections::unmodifiableList));
|
||||
return stream.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,8 +45,7 @@ public class ServletEndpointRegistrar implements ServletContextInitializer {
|
||||
|
||||
private final Collection<ExposableServletEndpoint> servletEndpoints;
|
||||
|
||||
public ServletEndpointRegistrar(String basePath,
|
||||
Collection<ExposableServletEndpoint> servletEndpoints) {
|
||||
public ServletEndpointRegistrar(String basePath, Collection<ExposableServletEndpoint> servletEndpoints) {
|
||||
Assert.notNull(servletEndpoints, "ServletEndpoints must not be null");
|
||||
this.basePath = cleanBasePath(basePath);
|
||||
this.servletEndpoints = servletEndpoints;
|
||||
@@ -61,18 +60,15 @@ public class ServletEndpointRegistrar implements ServletContextInitializer {
|
||||
|
||||
@Override
|
||||
public void onStartup(ServletContext servletContext) throws ServletException {
|
||||
this.servletEndpoints
|
||||
.forEach((servletEndpoint) -> register(servletContext, servletEndpoint));
|
||||
this.servletEndpoints.forEach((servletEndpoint) -> register(servletContext, servletEndpoint));
|
||||
}
|
||||
|
||||
private void register(ServletContext servletContext,
|
||||
ExposableServletEndpoint endpoint) {
|
||||
private void register(ServletContext servletContext, ExposableServletEndpoint endpoint) {
|
||||
String name = endpoint.getEndpointId().toLowerCaseString() + "-actuator-endpoint";
|
||||
String path = this.basePath + "/" + endpoint.getRootPath();
|
||||
String urlMapping = path.endsWith("/") ? path + "*" : path + "/*";
|
||||
EndpointServlet endpointServlet = endpoint.getEndpointServlet();
|
||||
Dynamic registration = servletContext.addServlet(name,
|
||||
endpointServlet.getServlet());
|
||||
Dynamic registration = servletContext.addServlet(name, endpointServlet.getServlet());
|
||||
registration.addMapping(urlMapping);
|
||||
registration.setInitParameters(endpointServlet.getInitParameters());
|
||||
logger.info("Registered '" + path + "' to " + name);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,8 +47,8 @@ public final class WebOperationRequestPredicate {
|
||||
* @param produces the media types that the operation produces
|
||||
* @param consumes the media types that the operation consumes
|
||||
*/
|
||||
public WebOperationRequestPredicate(String path, WebEndpointHttpMethod httpMethod,
|
||||
Collection<String> consumes, Collection<String> produces) {
|
||||
public WebOperationRequestPredicate(String path, WebEndpointHttpMethod httpMethod, Collection<String> consumes,
|
||||
Collection<String> produces) {
|
||||
this.path = path;
|
||||
this.canonicalPath = path.replaceAll("\\{.*?}", "{*}");
|
||||
this.httpMethod = httpMethod;
|
||||
@@ -118,15 +118,12 @@ public final class WebOperationRequestPredicate {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder(
|
||||
this.httpMethod + " to path '" + this.path + "'");
|
||||
StringBuilder result = new StringBuilder(this.httpMethod + " to path '" + this.path + "'");
|
||||
if (!CollectionUtils.isEmpty(this.consumes)) {
|
||||
result.append(" consumes: "
|
||||
+ StringUtils.collectionToCommaDelimitedString(this.consumes));
|
||||
result.append(" consumes: " + StringUtils.collectionToCommaDelimitedString(this.consumes));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(this.produces)) {
|
||||
result.append(" produces: "
|
||||
+ StringUtils.collectionToCommaDelimitedString(this.produces));
|
||||
result.append(" produces: " + StringUtils.collectionToCommaDelimitedString(this.produces));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,8 +39,7 @@ import org.springframework.util.ClassUtils;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class ControllerEndpointDiscoverer
|
||||
extends EndpointDiscoverer<ExposableControllerEndpoint, Operation>
|
||||
public class ControllerEndpointDiscoverer extends EndpointDiscoverer<ExposableControllerEndpoint, Operation>
|
||||
implements ControllerEndpointsSupplier {
|
||||
|
||||
private final PathMapper endpointPathMapper;
|
||||
@@ -51,11 +50,9 @@ public class ControllerEndpointDiscoverer
|
||||
* @param endpointPathMapper the endpoint path mapper
|
||||
* @param filters filters to apply
|
||||
*/
|
||||
public ControllerEndpointDiscoverer(ApplicationContext applicationContext,
|
||||
PathMapper endpointPathMapper,
|
||||
public ControllerEndpointDiscoverer(ApplicationContext applicationContext, PathMapper endpointPathMapper,
|
||||
Collection<EndpointFilter<ExposableControllerEndpoint>> filters) {
|
||||
super(applicationContext, ParameterValueMapper.NONE, Collections.emptyList(),
|
||||
filters);
|
||||
super(applicationContext, ParameterValueMapper.NONE, Collections.emptyList(), filters);
|
||||
Assert.notNull(endpointPathMapper, "EndpointPathMapper must not be null");
|
||||
this.endpointPathMapper = endpointPathMapper;
|
||||
}
|
||||
@@ -69,38 +66,34 @@ public class ControllerEndpointDiscoverer
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
protected ExposableControllerEndpoint createEndpoint(Object endpointBean, String id,
|
||||
boolean enabledByDefault, Collection<Operation> operations) {
|
||||
return createEndpoint(endpointBean, (id != null) ? EndpointId.of(id) : null,
|
||||
enabledByDefault, operations);
|
||||
protected ExposableControllerEndpoint createEndpoint(Object endpointBean, String id, boolean enabledByDefault,
|
||||
Collection<Operation> operations) {
|
||||
return createEndpoint(endpointBean, (id != null) ? EndpointId.of(id) : null, enabledByDefault, operations);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ExposableControllerEndpoint createEndpoint(Object endpointBean,
|
||||
EndpointId id, boolean enabledByDefault, Collection<Operation> operations) {
|
||||
protected ExposableControllerEndpoint createEndpoint(Object endpointBean, EndpointId id, boolean enabledByDefault,
|
||||
Collection<Operation> operations) {
|
||||
String rootPath = this.endpointPathMapper.getRootPath(id);
|
||||
return new DiscoveredControllerEndpoint(this, endpointBean, id, rootPath,
|
||||
enabledByDefault);
|
||||
return new DiscoveredControllerEndpoint(this, endpointBean, id, rootPath, enabledByDefault);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
protected Operation createOperation(String endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
protected Operation createOperation(String endpointId, DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker) {
|
||||
return createOperation(EndpointId.of(endpointId), operationMethod, invoker);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Operation createOperation(EndpointId endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
throw new IllegalStateException(
|
||||
"ControllerEndpoints must not declare operations");
|
||||
protected Operation createOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker) {
|
||||
throw new IllegalStateException("ControllerEndpoints must not declare operations");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OperationKey createOperationKey(Operation operation) {
|
||||
throw new IllegalStateException(
|
||||
"ControllerEndpoints must not declare operations");
|
||||
throw new IllegalStateException("ControllerEndpoints must not declare operations");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,6 @@ import org.springframework.boot.actuate.endpoint.EndpointsSupplier;
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ControllerEndpointsSupplier
|
||||
extends EndpointsSupplier<ExposableControllerEndpoint> {
|
||||
public interface ControllerEndpointsSupplier extends EndpointsSupplier<ExposableControllerEndpoint> {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,8 +33,8 @@ class DiscoveredControllerEndpoint extends AbstractDiscoveredEndpoint<Operation>
|
||||
|
||||
private final String rootPath;
|
||||
|
||||
DiscoveredControllerEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
||||
EndpointId id, String rootPath, boolean enabledByDefault) {
|
||||
DiscoveredControllerEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean, EndpointId id,
|
||||
String rootPath, boolean enabledByDefault) {
|
||||
super(discoverer, endpointBean, id, enabledByDefault, Collections.emptyList());
|
||||
this.rootPath = rootPath;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,24 +32,22 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DiscoveredServletEndpoint extends AbstractDiscoveredEndpoint<Operation>
|
||||
implements ExposableServletEndpoint {
|
||||
class DiscoveredServletEndpoint extends AbstractDiscoveredEndpoint<Operation> implements ExposableServletEndpoint {
|
||||
|
||||
private final String rootPath;
|
||||
|
||||
private final EndpointServlet endpointServlet;
|
||||
|
||||
DiscoveredServletEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
||||
EndpointId id, String rootPath, boolean enabledByDefault) {
|
||||
DiscoveredServletEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean, EndpointId id, String rootPath,
|
||||
boolean enabledByDefault) {
|
||||
super(discoverer, endpointBean, id, enabledByDefault, Collections.emptyList());
|
||||
String beanType = endpointBean.getClass().getName();
|
||||
Assert.state(endpointBean instanceof Supplier,
|
||||
() -> "ServletEndpoint bean " + beanType + " must be a supplier");
|
||||
Object supplied = ((Supplier<?>) endpointBean).get();
|
||||
Assert.state(supplied != null,
|
||||
() -> "ServletEndpoint bean " + beanType + " must not supply null");
|
||||
Assert.state(supplied instanceof EndpointServlet, () -> "ServletEndpoint bean "
|
||||
+ beanType + " must supply an EndpointServlet");
|
||||
Assert.state(supplied != null, () -> "ServletEndpoint bean " + beanType + " must not supply null");
|
||||
Assert.state(supplied instanceof EndpointServlet,
|
||||
() -> "ServletEndpoint bean " + beanType + " must supply an EndpointServlet");
|
||||
this.endpointServlet = (EndpointServlet) supplied;
|
||||
this.rootPath = rootPath;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,14 +29,12 @@ import org.springframework.boot.actuate.endpoint.web.WebOperation;
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DiscoveredWebEndpoint extends AbstractDiscoveredEndpoint<WebOperation>
|
||||
implements ExposableWebEndpoint {
|
||||
class DiscoveredWebEndpoint extends AbstractDiscoveredEndpoint<WebOperation> implements ExposableWebEndpoint {
|
||||
|
||||
private final String rootPath;
|
||||
|
||||
DiscoveredWebEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean,
|
||||
EndpointId id, String rootPath, boolean enabledByDefault,
|
||||
Collection<WebOperation> operations) {
|
||||
DiscoveredWebEndpoint(EndpointDiscoverer<?, ?> discoverer, Object endpointBean, EndpointId id, String rootPath,
|
||||
boolean enabledByDefault, Collection<WebOperation> operations) {
|
||||
super(discoverer, endpointBean, id, enabledByDefault, operations);
|
||||
this.rootPath = rootPath;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,8 +42,7 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
class DiscoveredWebOperation extends AbstractDiscoveredOperation implements WebOperation {
|
||||
|
||||
private static final boolean REACTIVE_STREAMS_PRESENT = ClassUtils.isPresent(
|
||||
"org.reactivestreams.Publisher",
|
||||
private static final boolean REACTIVE_STREAMS_PRESENT = ClassUtils.isPresent("org.reactivestreams.Publisher",
|
||||
DiscoveredWebOperation.class.getClassLoader());
|
||||
|
||||
private final String id;
|
||||
@@ -52,8 +51,7 @@ class DiscoveredWebOperation extends AbstractDiscoveredOperation implements WebO
|
||||
|
||||
private final WebOperationRequestPredicate requestPredicate;
|
||||
|
||||
DiscoveredWebOperation(EndpointId endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker,
|
||||
DiscoveredWebOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod, OperationInvoker invoker,
|
||||
WebOperationRequestPredicate requestPredicate) {
|
||||
super(operationMethod, invoker);
|
||||
Method method = operationMethod.getMethod();
|
||||
@@ -63,8 +61,8 @@ class DiscoveredWebOperation extends AbstractDiscoveredOperation implements WebO
|
||||
}
|
||||
|
||||
private String getId(EndpointId endpointId, Method method) {
|
||||
return endpointId + Stream.of(method.getParameters()).filter(this::hasSelector)
|
||||
.map(this::dashName).collect(Collectors.joining());
|
||||
return endpointId + Stream.of(method.getParameters()).filter(this::hasSelector).map(this::dashName)
|
||||
.collect(Collectors.joining());
|
||||
}
|
||||
|
||||
private boolean hasSelector(Parameter parameter) {
|
||||
@@ -76,8 +74,7 @@ class DiscoveredWebOperation extends AbstractDiscoveredOperation implements WebO
|
||||
}
|
||||
|
||||
private boolean getBlocking(Method method) {
|
||||
return !REACTIVE_STREAMS_PRESENT
|
||||
|| !Publisher.class.isAssignableFrom(method.getReturnType());
|
||||
return !REACTIVE_STREAMS_PRESENT || !Publisher.class.isAssignableFrom(method.getReturnType());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,8 +94,8 @@ 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,8 +29,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public interface ExposableControllerEndpoint
|
||||
extends ExposableEndpoint<Operation>, PathMappedEndpoint {
|
||||
public interface ExposableControllerEndpoint extends ExposableEndpoint<Operation>, PathMappedEndpoint {
|
||||
|
||||
/**
|
||||
* Return the source controller that contains {@link RequestMapping} methods.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -51,20 +51,19 @@ class RequestPredicateFactory {
|
||||
this.endpointMediaTypes = endpointMediaTypes;
|
||||
}
|
||||
|
||||
public WebOperationRequestPredicate getRequestPredicate(EndpointId endpointId,
|
||||
String rootPath, DiscoveredOperationMethod operationMethod) {
|
||||
public WebOperationRequestPredicate getRequestPredicate(EndpointId endpointId, String rootPath,
|
||||
DiscoveredOperationMethod operationMethod) {
|
||||
Method method = operationMethod.getMethod();
|
||||
String path = getPath(rootPath, method);
|
||||
WebEndpointHttpMethod httpMethod = determineHttpMethod(
|
||||
operationMethod.getOperationType());
|
||||
WebEndpointHttpMethod httpMethod = determineHttpMethod(operationMethod.getOperationType());
|
||||
Collection<String> consumes = getConsumes(httpMethod, method);
|
||||
Collection<String> produces = getProduces(operationMethod, method);
|
||||
return new WebOperationRequestPredicate(path, httpMethod, consumes, produces);
|
||||
}
|
||||
|
||||
private String getPath(String rootPath, Method method) {
|
||||
return rootPath + Stream.of(method.getParameters()).filter(this::hasSelector)
|
||||
.map(this::slashName).collect(Collectors.joining());
|
||||
return rootPath + Stream.of(method.getParameters()).filter(this::hasSelector).map(this::slashName)
|
||||
.collect(Collectors.joining());
|
||||
}
|
||||
|
||||
private boolean hasSelector(Parameter parameter) {
|
||||
@@ -75,21 +74,18 @@ class RequestPredicateFactory {
|
||||
return "/{" + parameter.getName() + "}";
|
||||
}
|
||||
|
||||
private Collection<String> getConsumes(WebEndpointHttpMethod httpMethod,
|
||||
Method method) {
|
||||
private Collection<String> getConsumes(WebEndpointHttpMethod httpMethod, Method method) {
|
||||
if (WebEndpointHttpMethod.POST == httpMethod && consumesRequestBody(method)) {
|
||||
return this.endpointMediaTypes.getConsumed();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private Collection<String> getProduces(DiscoveredOperationMethod operationMethod,
|
||||
Method method) {
|
||||
private Collection<String> getProduces(DiscoveredOperationMethod operationMethod, Method method) {
|
||||
if (!operationMethod.getProducesMediaTypes().isEmpty()) {
|
||||
return operationMethod.getProducesMediaTypes();
|
||||
}
|
||||
if (Void.class.equals(method.getReturnType())
|
||||
|| void.class.equals(method.getReturnType())) {
|
||||
if (Void.class.equals(method.getReturnType()) || void.class.equals(method.getReturnType())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (producesResource(method)) {
|
||||
@@ -104,8 +100,7 @@ class RequestPredicateFactory {
|
||||
}
|
||||
if (WebEndpointResponse.class.isAssignableFrom(method.getReturnType())) {
|
||||
ResolvableType returnType = ResolvableType.forMethodReturnType(method);
|
||||
if (ResolvableType.forClass(Resource.class)
|
||||
.isAssignableFrom(returnType.getGeneric(0))) {
|
||||
if (ResolvableType.forClass(Resource.class).isAssignableFrom(returnType.getGeneric(0))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,8 +39,7 @@ import org.springframework.util.ClassUtils;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class ServletEndpointDiscoverer
|
||||
extends EndpointDiscoverer<ExposableServletEndpoint, Operation>
|
||||
public class ServletEndpointDiscoverer extends EndpointDiscoverer<ExposableServletEndpoint, Operation>
|
||||
implements ServletEndpointsSupplier {
|
||||
|
||||
private final PathMapper endpointPathMapper;
|
||||
@@ -51,11 +50,9 @@ public class ServletEndpointDiscoverer
|
||||
* @param endpointPathMapper the endpoint path mapper
|
||||
* @param filters filters to apply
|
||||
*/
|
||||
public ServletEndpointDiscoverer(ApplicationContext applicationContext,
|
||||
PathMapper endpointPathMapper,
|
||||
public ServletEndpointDiscoverer(ApplicationContext applicationContext, PathMapper endpointPathMapper,
|
||||
Collection<EndpointFilter<ExposableServletEndpoint>> filters) {
|
||||
super(applicationContext, ParameterValueMapper.NONE, Collections.emptyList(),
|
||||
filters);
|
||||
super(applicationContext, ParameterValueMapper.NONE, Collections.emptyList(), filters);
|
||||
Assert.notNull(endpointPathMapper, "EndpointPathMapper must not be null");
|
||||
this.endpointPathMapper = endpointPathMapper;
|
||||
}
|
||||
@@ -68,30 +65,28 @@ public class ServletEndpointDiscoverer
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
protected ExposableServletEndpoint createEndpoint(Object endpointBean, String id,
|
||||
boolean enabledByDefault, Collection<Operation> operations) {
|
||||
return createEndpoint(endpointBean, EndpointId.of(id), enabledByDefault,
|
||||
operations);
|
||||
protected ExposableServletEndpoint createEndpoint(Object endpointBean, String id, boolean enabledByDefault,
|
||||
Collection<Operation> operations) {
|
||||
return createEndpoint(endpointBean, EndpointId.of(id), enabledByDefault, operations);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ExposableServletEndpoint createEndpoint(Object endpointBean, EndpointId id,
|
||||
boolean enabledByDefault, Collection<Operation> operations) {
|
||||
protected ExposableServletEndpoint createEndpoint(Object endpointBean, EndpointId id, boolean enabledByDefault,
|
||||
Collection<Operation> operations) {
|
||||
String rootPath = this.endpointPathMapper.getRootPath(id);
|
||||
return new DiscoveredServletEndpoint(this, endpointBean, id, rootPath,
|
||||
enabledByDefault);
|
||||
return new DiscoveredServletEndpoint(this, endpointBean, id, rootPath, enabledByDefault);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
protected Operation createOperation(String endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
protected Operation createOperation(String endpointId, DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker) {
|
||||
return createOperation(EndpointId.of(endpointId), operationMethod, invoker);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Operation createOperation(EndpointId endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
protected Operation createOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker) {
|
||||
throw new IllegalStateException("ServletEndpoints must not declare operations");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,6 @@ import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint;
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ServletEndpointsSupplier
|
||||
extends EndpointsSupplier<ExposableServletEndpoint> {
|
||||
public interface ServletEndpointsSupplier extends EndpointsSupplier<ExposableServletEndpoint> {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,8 +40,7 @@ import org.springframework.util.Assert;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class WebEndpointDiscoverer
|
||||
extends EndpointDiscoverer<ExposableWebEndpoint, WebOperation>
|
||||
public class WebEndpointDiscoverer extends EndpointDiscoverer<ExposableWebEndpoint, WebOperation>
|
||||
implements WebEndpointsSupplier {
|
||||
|
||||
private final PathMapper endpointPathMapper;
|
||||
@@ -57,8 +56,7 @@ public class WebEndpointDiscoverer
|
||||
* @param invokerAdvisors invoker advisors to apply
|
||||
* @param filters filters to apply
|
||||
*/
|
||||
public WebEndpointDiscoverer(ApplicationContext applicationContext,
|
||||
ParameterValueMapper parameterValueMapper,
|
||||
public WebEndpointDiscoverer(ApplicationContext applicationContext, ParameterValueMapper parameterValueMapper,
|
||||
EndpointMediaTypes endpointMediaTypes, PathMapper endpointPathMapper,
|
||||
Collection<OperationInvokerAdvisor> invokerAdvisors,
|
||||
Collection<EndpointFilter<ExposableWebEndpoint>> filters) {
|
||||
@@ -70,35 +68,32 @@ public class WebEndpointDiscoverer
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
protected ExposableWebEndpoint createEndpoint(Object endpointBean, String id,
|
||||
boolean enabledByDefault, Collection<WebOperation> operations) {
|
||||
return createEndpoint(endpointBean, EndpointId.of(id), enabledByDefault,
|
||||
operations);
|
||||
protected ExposableWebEndpoint createEndpoint(Object endpointBean, String id, boolean enabledByDefault,
|
||||
Collection<WebOperation> operations) {
|
||||
return createEndpoint(endpointBean, EndpointId.of(id), enabledByDefault, operations);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ExposableWebEndpoint createEndpoint(Object endpointBean, EndpointId id,
|
||||
boolean enabledByDefault, Collection<WebOperation> operations) {
|
||||
protected ExposableWebEndpoint createEndpoint(Object endpointBean, EndpointId id, boolean enabledByDefault,
|
||||
Collection<WebOperation> operations) {
|
||||
String rootPath = this.endpointPathMapper.getRootPath(id);
|
||||
return new DiscoveredWebEndpoint(this, endpointBean, id, rootPath,
|
||||
enabledByDefault, operations);
|
||||
return new DiscoveredWebEndpoint(this, endpointBean, id, rootPath, enabledByDefault, operations);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
protected WebOperation createOperation(String endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
protected WebOperation createOperation(String endpointId, DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker) {
|
||||
return createOperation(EndpointId.of(endpointId), operationMethod, invoker);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WebOperation createOperation(EndpointId endpointId,
|
||||
DiscoveredOperationMethod operationMethod, OperationInvoker invoker) {
|
||||
protected WebOperation createOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod,
|
||||
OperationInvoker invoker) {
|
||||
String rootPath = this.endpointPathMapper.getRootPath(endpointId);
|
||||
WebOperationRequestPredicate requestPredicate = this.requestPredicateFactory
|
||||
.getRequestPredicate(endpointId, rootPath, operationMethod);
|
||||
return new DiscoveredWebOperation(endpointId, operationMethod, invoker,
|
||||
requestPredicate);
|
||||
WebOperationRequestPredicate requestPredicate = this.requestPredicateFactory.getRequestPredicate(endpointId,
|
||||
rootPath, operationMethod);
|
||||
return new DiscoveredWebOperation(endpointId, operationMethod, invoker, requestPredicate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -74,38 +74,33 @@ public class JerseyEndpointResourceFactory {
|
||||
* @return the resources for the operations
|
||||
*/
|
||||
public Collection<Resource> createEndpointResources(EndpointMapping endpointMapping,
|
||||
Collection<ExposableWebEndpoint> endpoints,
|
||||
EndpointMediaTypes endpointMediaTypes, EndpointLinksResolver linksResolver) {
|
||||
Collection<ExposableWebEndpoint> endpoints, EndpointMediaTypes endpointMediaTypes,
|
||||
EndpointLinksResolver linksResolver) {
|
||||
List<Resource> resources = new ArrayList<>();
|
||||
endpoints.stream().flatMap((endpoint) -> endpoint.getOperations().stream())
|
||||
.map((operation) -> createResource(endpointMapping, operation))
|
||||
.forEach(resources::add);
|
||||
.map((operation) -> createResource(endpointMapping, operation)).forEach(resources::add);
|
||||
if (StringUtils.hasText(endpointMapping.getPath())) {
|
||||
Resource resource = createEndpointLinksResource(endpointMapping.getPath(),
|
||||
endpointMediaTypes, linksResolver);
|
||||
Resource resource = createEndpointLinksResource(endpointMapping.getPath(), endpointMediaTypes,
|
||||
linksResolver);
|
||||
resources.add(resource);
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
|
||||
private Resource createResource(EndpointMapping endpointMapping,
|
||||
WebOperation operation) {
|
||||
private Resource createResource(EndpointMapping endpointMapping, WebOperation operation) {
|
||||
WebOperationRequestPredicate requestPredicate = operation.getRequestPredicate();
|
||||
Builder resourceBuilder = Resource.builder()
|
||||
.path(endpointMapping.createSubPath(requestPredicate.getPath()));
|
||||
Builder resourceBuilder = Resource.builder().path(endpointMapping.createSubPath(requestPredicate.getPath()));
|
||||
resourceBuilder.addMethod(requestPredicate.getHttpMethod().name())
|
||||
.consumes(StringUtils.toStringArray(requestPredicate.getConsumes()))
|
||||
.produces(StringUtils.toStringArray(requestPredicate.getProduces()))
|
||||
.handledBy(new OperationInflector(operation,
|
||||
!requestPredicate.getConsumes().isEmpty()));
|
||||
.handledBy(new OperationInflector(operation, !requestPredicate.getConsumes().isEmpty()));
|
||||
return resourceBuilder.build();
|
||||
}
|
||||
|
||||
private Resource createEndpointLinksResource(String endpointPath,
|
||||
EndpointMediaTypes endpointMediaTypes, EndpointLinksResolver linksResolver) {
|
||||
private Resource createEndpointLinksResource(String endpointPath, EndpointMediaTypes endpointMediaTypes,
|
||||
EndpointLinksResolver linksResolver) {
|
||||
Builder resourceBuilder = Resource.builder().path(endpointPath);
|
||||
resourceBuilder.addMethod("GET")
|
||||
.produces(StringUtils.toStringArray(endpointMediaTypes.getProduced()))
|
||||
resourceBuilder.addMethod("GET").produces(StringUtils.toStringArray(endpointMediaTypes.getProduced()))
|
||||
.handledBy(new EndpointLinksInflector(linksResolver));
|
||||
return resourceBuilder.build();
|
||||
}
|
||||
@@ -113,16 +108,14 @@ public class JerseyEndpointResourceFactory {
|
||||
/**
|
||||
* {@link Inflector} to invoke the {@link WebOperation}.
|
||||
*/
|
||||
private static final class OperationInflector
|
||||
implements Inflector<ContainerRequestContext, Object> {
|
||||
private static final class OperationInflector implements Inflector<ContainerRequestContext, Object> {
|
||||
|
||||
private static final List<Function<Object, Object>> BODY_CONVERTERS;
|
||||
|
||||
static {
|
||||
List<Function<Object, Object>> converters = new ArrayList<>();
|
||||
converters.add(new ResourceBodyConverter());
|
||||
if (ClassUtils.isPresent("reactor.core.publisher.Mono",
|
||||
OperationInflector.class.getClassLoader())) {
|
||||
if (ClassUtils.isPresent("reactor.core.publisher.Mono", OperationInflector.class.getClassLoader())) {
|
||||
converters.add(new MonoBodyConverter());
|
||||
}
|
||||
BODY_CONVERTERS = Collections.unmodifiableList(converters);
|
||||
@@ -146,8 +139,8 @@ public class JerseyEndpointResourceFactory {
|
||||
arguments.putAll(extractPathParameters(data));
|
||||
arguments.putAll(extractQueryParameters(data));
|
||||
try {
|
||||
Object response = this.operation.invoke(new InvocationContext(
|
||||
new JerseySecurityContext(data.getSecurityContext()), arguments));
|
||||
Object response = this.operation
|
||||
.invoke(new InvocationContext(new JerseySecurityContext(data.getSecurityContext()), arguments));
|
||||
return convertToJaxRsResponse(response, data.getRequest().getMethod());
|
||||
}
|
||||
catch (InvalidEndpointRequestException ex) {
|
||||
@@ -164,18 +157,15 @@ public class JerseyEndpointResourceFactory {
|
||||
return (Map<String, Object>) entity;
|
||||
}
|
||||
|
||||
private Map<String, Object> extractPathParameters(
|
||||
ContainerRequestContext requestContext) {
|
||||
private Map<String, Object> extractPathParameters(ContainerRequestContext requestContext) {
|
||||
return extract(requestContext.getUriInfo().getPathParameters());
|
||||
}
|
||||
|
||||
private Map<String, Object> extractQueryParameters(
|
||||
ContainerRequestContext requestContext) {
|
||||
private Map<String, Object> extractQueryParameters(ContainerRequestContext requestContext) {
|
||||
return extract(requestContext.getUriInfo().getQueryParameters());
|
||||
}
|
||||
|
||||
private Map<String, Object> extract(
|
||||
MultivaluedMap<String, String> multivaluedMap) {
|
||||
private Map<String, Object> extract(MultivaluedMap<String, String> multivaluedMap) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
multivaluedMap.forEach((name, values) -> {
|
||||
if (!CollectionUtils.isEmpty(values)) {
|
||||
@@ -193,13 +183,11 @@ public class JerseyEndpointResourceFactory {
|
||||
}
|
||||
try {
|
||||
if (!(response instanceof WebEndpointResponse)) {
|
||||
return Response.status(Status.OK).entity(convertIfNecessary(response))
|
||||
.build();
|
||||
return Response.status(Status.OK).entity(convertIfNecessary(response)).build();
|
||||
}
|
||||
WebEndpointResponse<?> webEndpointResponse = (WebEndpointResponse<?>) response;
|
||||
return Response.status(webEndpointResponse.getStatus())
|
||||
.entity(convertIfNecessary(webEndpointResponse.getBody()))
|
||||
.build();
|
||||
.entity(convertIfNecessary(webEndpointResponse.getBody())).build();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
|
||||
@@ -254,8 +242,7 @@ public class JerseyEndpointResourceFactory {
|
||||
/**
|
||||
* {@link Inflector} to for endpoint links.
|
||||
*/
|
||||
private static final class EndpointLinksInflector
|
||||
implements Inflector<ContainerRequestContext, Response> {
|
||||
private static final class EndpointLinksInflector implements Inflector<ContainerRequestContext, Response> {
|
||||
|
||||
private final EndpointLinksResolver linksResolver;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -75,8 +75,7 @@ import org.springframework.web.util.pattern.PathPatternParser;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
extends RequestMappingInfoHandlerMapping {
|
||||
public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappingInfoHandlerMapping {
|
||||
|
||||
private static final PathPatternParser pathPatternParser = new PathPatternParser();
|
||||
|
||||
@@ -88,15 +87,14 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
|
||||
private final CorsConfiguration corsConfiguration;
|
||||
|
||||
private final Method linksMethod = ReflectionUtils.findMethod(getClass(), "links",
|
||||
private final Method linksMethod = ReflectionUtils.findMethod(getClass(), "links", ServerWebExchange.class);
|
||||
|
||||
private final Method handleWriteMethod = ReflectionUtils.findMethod(WriteOperationHandler.class, "handle",
|
||||
ServerWebExchange.class, Map.class);
|
||||
|
||||
private final Method handleReadMethod = ReflectionUtils.findMethod(ReadOperationHandler.class, "handle",
|
||||
ServerWebExchange.class);
|
||||
|
||||
private final Method handleWriteMethod = ReflectionUtils.findMethod(
|
||||
WriteOperationHandler.class, "handle", ServerWebExchange.class, Map.class);
|
||||
|
||||
private final Method handleReadMethod = ReflectionUtils
|
||||
.findMethod(ReadOperationHandler.class, "handle", ServerWebExchange.class);
|
||||
|
||||
/**
|
||||
* Creates a new {@code AbstractWebFluxEndpointHandlerMapping} that provides mappings
|
||||
* for the operations of the given {@code webEndpoints}.
|
||||
@@ -106,8 +104,8 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
* @param corsConfiguration the CORS configuration for the endpoints
|
||||
*/
|
||||
public AbstractWebFluxEndpointHandlerMapping(EndpointMapping endpointMapping,
|
||||
Collection<ExposableWebEndpoint> endpoints,
|
||||
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration) {
|
||||
Collection<ExposableWebEndpoint> endpoints, EndpointMediaTypes endpointMediaTypes,
|
||||
CorsConfiguration corsConfiguration) {
|
||||
this.endpointMapping = endpointMapping;
|
||||
this.endpoints = endpoints;
|
||||
this.endpointMediaTypes = endpointMediaTypes;
|
||||
@@ -127,22 +125,19 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
}
|
||||
}
|
||||
|
||||
private void registerMappingForOperation(ExposableWebEndpoint endpoint,
|
||||
WebOperation operation) {
|
||||
private void registerMappingForOperation(ExposableWebEndpoint endpoint, WebOperation operation) {
|
||||
OperationInvoker invoker = operation::invoke;
|
||||
if (operation.isBlocking()) {
|
||||
invoker = new ElasticSchedulerInvoker(invoker);
|
||||
}
|
||||
ReactiveWebOperation reactiveWebOperation = wrapReactiveWebOperation(endpoint,
|
||||
operation, new ReactiveWebOperationAdapter(invoker));
|
||||
ReactiveWebOperation reactiveWebOperation = wrapReactiveWebOperation(endpoint, operation,
|
||||
new ReactiveWebOperationAdapter(invoker));
|
||||
if (operation.getType() == OperationType.WRITE) {
|
||||
registerMapping(createRequestMappingInfo(operation),
|
||||
new WriteOperationHandler((reactiveWebOperation)),
|
||||
registerMapping(createRequestMappingInfo(operation), new WriteOperationHandler((reactiveWebOperation)),
|
||||
this.handleWriteMethod);
|
||||
}
|
||||
else {
|
||||
registerMapping(createRequestMappingInfo(operation),
|
||||
new ReadOperationHandler((reactiveWebOperation)),
|
||||
registerMapping(createRequestMappingInfo(operation), new ReadOperationHandler((reactiveWebOperation)),
|
||||
this.handleReadMethod);
|
||||
}
|
||||
}
|
||||
@@ -155,40 +150,36 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
* @param reactiveWebOperation the reactive web operation to wrap
|
||||
* @return a wrapped reactive web operation
|
||||
*/
|
||||
protected ReactiveWebOperation wrapReactiveWebOperation(ExposableWebEndpoint endpoint,
|
||||
WebOperation operation, ReactiveWebOperation reactiveWebOperation) {
|
||||
protected ReactiveWebOperation wrapReactiveWebOperation(ExposableWebEndpoint endpoint, WebOperation operation,
|
||||
ReactiveWebOperation reactiveWebOperation) {
|
||||
return reactiveWebOperation;
|
||||
}
|
||||
|
||||
private RequestMappingInfo createRequestMappingInfo(WebOperation operation) {
|
||||
WebOperationRequestPredicate predicate = operation.getRequestPredicate();
|
||||
PatternsRequestCondition patterns = new PatternsRequestCondition(pathPatternParser
|
||||
.parse(this.endpointMapping.createSubPath(predicate.getPath())));
|
||||
PatternsRequestCondition patterns = new PatternsRequestCondition(
|
||||
pathPatternParser.parse(this.endpointMapping.createSubPath(predicate.getPath())));
|
||||
RequestMethodsRequestCondition methods = new RequestMethodsRequestCondition(
|
||||
RequestMethod.valueOf(predicate.getHttpMethod().name()));
|
||||
ConsumesRequestCondition consumes = new ConsumesRequestCondition(
|
||||
StringUtils.toStringArray(predicate.getConsumes()));
|
||||
ProducesRequestCondition produces = new ProducesRequestCondition(
|
||||
StringUtils.toStringArray(predicate.getProduces()));
|
||||
return new RequestMappingInfo(null, patterns, methods, null, null, consumes,
|
||||
produces, null);
|
||||
return new RequestMappingInfo(null, patterns, methods, null, null, consumes, produces, null);
|
||||
}
|
||||
|
||||
private void registerLinksMapping() {
|
||||
PatternsRequestCondition patterns = new PatternsRequestCondition(
|
||||
pathPatternParser.parse(this.endpointMapping.getPath()));
|
||||
RequestMethodsRequestCondition methods = new RequestMethodsRequestCondition(
|
||||
RequestMethod.GET);
|
||||
RequestMethodsRequestCondition methods = new RequestMethodsRequestCondition(RequestMethod.GET);
|
||||
ProducesRequestCondition produces = new ProducesRequestCondition(
|
||||
StringUtils.toStringArray(this.endpointMediaTypes.getProduced()));
|
||||
RequestMappingInfo mapping = new RequestMappingInfo(patterns, methods, null, null,
|
||||
null, produces, null);
|
||||
RequestMappingInfo mapping = new RequestMappingInfo(patterns, methods, null, null, null, produces, null);
|
||||
registerMapping(mapping, this, this.linksMethod);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CorsConfiguration initCorsConfiguration(Object handler, Method method,
|
||||
RequestMappingInfo mapping) {
|
||||
protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mapping) {
|
||||
return this.corsConfiguration;
|
||||
}
|
||||
|
||||
@@ -198,8 +189,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RequestMappingInfo getMappingForMethod(Method method,
|
||||
Class<?> handlerType) {
|
||||
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -227,8 +217,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
|
||||
@Override
|
||||
public Object invoke(InvocationContext context) {
|
||||
return Mono.create(
|
||||
(sink) -> Schedulers.elastic().schedule(() -> invoke(context, sink)));
|
||||
return Mono.create((sink) -> Schedulers.elastic().schedule(() -> invoke(context, sink)));
|
||||
}
|
||||
|
||||
private void invoke(InvocationContext context, MonoSink<Object> sink) {
|
||||
@@ -249,8 +238,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
@FunctionalInterface
|
||||
protected interface ReactiveWebOperation {
|
||||
|
||||
Mono<ResponseEntity<Object>> handle(ServerWebExchange exchange,
|
||||
Map<String, String> body);
|
||||
Mono<ResponseEntity<Object>> handle(ServerWebExchange exchange, Map<String, String> body);
|
||||
|
||||
}
|
||||
|
||||
@@ -258,8 +246,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
* Adapter class to convert an {@link OperationInvoker} into a
|
||||
* {@link ReactiveWebOperation}.
|
||||
*/
|
||||
private static final class ReactiveWebOperationAdapter
|
||||
implements ReactiveWebOperation {
|
||||
private static final class ReactiveWebOperationAdapter implements ReactiveWebOperation {
|
||||
|
||||
private final OperationInvoker invoker;
|
||||
|
||||
@@ -271,8 +258,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
}
|
||||
|
||||
private Supplier<Mono<? extends SecurityContext>> getSecurityContextSupplier() {
|
||||
if (ClassUtils.isPresent(
|
||||
"org.springframework.security.core.context.ReactiveSecurityContextHolder",
|
||||
if (ClassUtils.isPresent("org.springframework.security.core.context.ReactiveSecurityContextHolder",
|
||||
getClass().getClassLoader())) {
|
||||
return this::springSecurityContext;
|
||||
}
|
||||
@@ -281,8 +267,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
|
||||
public Mono<? extends SecurityContext> springSecurityContext() {
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map((securityContext) -> new ReactiveSecurityContext(
|
||||
securityContext.getAuthentication()))
|
||||
.map((securityContext) -> new ReactiveSecurityContext(securityContext.getAuthentication()))
|
||||
.switchIfEmpty(Mono.just(new ReactiveSecurityContext(null)));
|
||||
}
|
||||
|
||||
@@ -291,26 +276,22 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<ResponseEntity<Object>> handle(ServerWebExchange exchange,
|
||||
Map<String, String> body) {
|
||||
public Mono<ResponseEntity<Object>> handle(ServerWebExchange exchange, Map<String, String> body) {
|
||||
Map<String, Object> arguments = getArguments(exchange, body);
|
||||
return this.securityContextSupplier.get()
|
||||
.map((securityContext) -> new InvocationContext(securityContext,
|
||||
arguments))
|
||||
.flatMap((invocationContext) -> handleResult(
|
||||
(Publisher<?>) this.invoker.invoke(invocationContext),
|
||||
.map((securityContext) -> new InvocationContext(securityContext, arguments))
|
||||
.flatMap((invocationContext) -> handleResult((Publisher<?>) this.invoker.invoke(invocationContext),
|
||||
exchange.getRequest().getMethod()));
|
||||
}
|
||||
|
||||
private Map<String, Object> getArguments(ServerWebExchange exchange,
|
||||
Map<String, String> body) {
|
||||
private Map<String, Object> getArguments(ServerWebExchange exchange, Map<String, String> body) {
|
||||
Map<String, Object> arguments = new LinkedHashMap<>();
|
||||
arguments.putAll(getTemplateVariables(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;
|
||||
}
|
||||
|
||||
@@ -318,14 +299,12 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
return exchange.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
|
||||
}
|
||||
|
||||
private Mono<ResponseEntity<Object>> handleResult(Publisher<?> result,
|
||||
HttpMethod httpMethod) {
|
||||
private Mono<ResponseEntity<Object>> handleResult(Publisher<?> result, HttpMethod httpMethod) {
|
||||
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));
|
||||
(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) {
|
||||
@@ -397,8 +376,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping
|
||||
role = this.roleVoter.getRolePrefix() + role;
|
||||
}
|
||||
return this.roleVoter.vote(this.authentication, null,
|
||||
Collections.singletonList(new SecurityConfig(
|
||||
role))) == AccessDecisionVoter.ACCESS_GRANTED;
|
||||
Collections.singletonList(new SecurityConfig(role))) == AccessDecisionVoter.ACCESS_GRANTED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -59,8 +59,7 @@ public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMappi
|
||||
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
|
||||
*/
|
||||
public ControllerEndpointHandlerMapping(EndpointMapping endpointMapping,
|
||||
Collection<ExposableControllerEndpoint> endpoints,
|
||||
CorsConfiguration corsConfiguration) {
|
||||
Collection<ExposableControllerEndpoint> endpoints, CorsConfiguration corsConfiguration) {
|
||||
Assert.notNull(endpointMapping, "EndpointMapping must not be null");
|
||||
Assert.notNull(endpoints, "Endpoints must not be null");
|
||||
this.endpointMapping = endpointMapping;
|
||||
@@ -69,8 +68,7 @@ public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMappi
|
||||
setOrder(-100);
|
||||
}
|
||||
|
||||
private Map<Object, ExposableControllerEndpoint> getHandlers(
|
||||
Collection<ExposableControllerEndpoint> endpoints) {
|
||||
private Map<Object, ExposableControllerEndpoint> getHandlers(Collection<ExposableControllerEndpoint> endpoints) {
|
||||
Map<Object, ExposableControllerEndpoint> handlers = new LinkedHashMap<>();
|
||||
endpoints.forEach((endpoint) -> handlers.put(endpoint.getController(), endpoint));
|
||||
return Collections.unmodifiableMap(handlers);
|
||||
@@ -82,44 +80,36 @@ public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMappi
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerHandlerMethod(Object handler, Method method,
|
||||
RequestMappingInfo mapping) {
|
||||
protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
|
||||
ExposableControllerEndpoint endpoint = this.handlers.get(handler);
|
||||
mapping = withEndpointMappedPatterns(endpoint, mapping);
|
||||
super.registerHandlerMethod(handler, method, mapping);
|
||||
}
|
||||
|
||||
private RequestMappingInfo withEndpointMappedPatterns(
|
||||
ExposableControllerEndpoint endpoint, RequestMappingInfo mapping) {
|
||||
private RequestMappingInfo withEndpointMappedPatterns(ExposableControllerEndpoint endpoint,
|
||||
RequestMappingInfo mapping) {
|
||||
Set<PathPattern> patterns = mapping.getPatternsCondition().getPatterns();
|
||||
if (patterns.isEmpty()) {
|
||||
patterns = Collections.singleton(getPathPatternParser().parse(""));
|
||||
}
|
||||
PathPattern[] endpointMappedPatterns = patterns.stream()
|
||||
.map((pattern) -> getEndpointMappedPattern(endpoint, pattern))
|
||||
.toArray(PathPattern[]::new);
|
||||
.map((pattern) -> getEndpointMappedPattern(endpoint, pattern)).toArray(PathPattern[]::new);
|
||||
return withNewPatterns(mapping, endpointMappedPatterns);
|
||||
}
|
||||
|
||||
private PathPattern getEndpointMappedPattern(ExposableControllerEndpoint endpoint,
|
||||
PathPattern pattern) {
|
||||
return getPathPatternParser().parse(
|
||||
this.endpointMapping.createSubPath(endpoint.getRootPath() + pattern));
|
||||
private PathPattern getEndpointMappedPattern(ExposableControllerEndpoint endpoint, PathPattern pattern) {
|
||||
return getPathPatternParser().parse(this.endpointMapping.createSubPath(endpoint.getRootPath() + pattern));
|
||||
}
|
||||
|
||||
private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping,
|
||||
PathPattern[] patterns) {
|
||||
PatternsRequestCondition patternsCondition = new PatternsRequestCondition(
|
||||
patterns);
|
||||
return new RequestMappingInfo(patternsCondition, mapping.getMethodsCondition(),
|
||||
mapping.getParamsCondition(), mapping.getHeadersCondition(),
|
||||
mapping.getConsumesCondition(), mapping.getProducesCondition(),
|
||||
private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping, PathPattern[] patterns) {
|
||||
PatternsRequestCondition patternsCondition = new PatternsRequestCondition(patterns);
|
||||
return new RequestMappingInfo(patternsCondition, mapping.getMethodsCondition(), mapping.getParamsCondition(),
|
||||
mapping.getHeadersCondition(), mapping.getConsumesCondition(), mapping.getProducesCondition(),
|
||||
mapping.getCustomCondition());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CorsConfiguration initCorsConfiguration(Object handler, Method method,
|
||||
RequestMappingInfo mapping) {
|
||||
protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mapping) {
|
||||
return this.corsConfiguration;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,8 +40,7 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandlerMapping
|
||||
implements InitializingBean {
|
||||
public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandlerMapping implements InitializingBean {
|
||||
|
||||
private final EndpointLinksResolver linksResolver;
|
||||
|
||||
@@ -54,8 +53,7 @@ public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandle
|
||||
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
|
||||
* @param linksResolver resolver for determining links to available endpoints
|
||||
*/
|
||||
public WebFluxEndpointHandlerMapping(EndpointMapping endpointMapping,
|
||||
Collection<ExposableWebEndpoint> endpoints,
|
||||
public WebFluxEndpointHandlerMapping(EndpointMapping endpointMapping, Collection<ExposableWebEndpoint> endpoints,
|
||||
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
|
||||
EndpointLinksResolver linksResolver) {
|
||||
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration);
|
||||
@@ -66,10 +64,9 @@ public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandle
|
||||
@Override
|
||||
@ResponseBody
|
||||
protected Map<String, Map<String, Link>> links(ServerWebExchange exchange) {
|
||||
String requestUri = UriComponentsBuilder.fromUri(exchange.getRequest().getURI())
|
||||
.replaceQuery(null).toUriString();
|
||||
return Collections.singletonMap("_links",
|
||||
this.linksResolver.resolveLinks(requestUri));
|
||||
String requestUri = UriComponentsBuilder.fromUri(exchange.getRequest().getURI()).replaceQuery(null)
|
||||
.toUriString();
|
||||
return Collections.singletonMap("_links", this.linksResolver.resolveLinks(requestUri));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -68,8 +68,7 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public abstract class AbstractWebMvcEndpointHandlerMapping
|
||||
extends RequestMappingInfoHandlerMapping
|
||||
public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappingInfoHandlerMapping
|
||||
implements InitializingBean, MatchableHandlerMapping {
|
||||
|
||||
private final EndpointMapping endpointMapping;
|
||||
@@ -80,11 +79,11 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
|
||||
|
||||
private final CorsConfiguration corsConfiguration;
|
||||
|
||||
private final Method linksMethod = ReflectionUtils.findMethod(getClass(), "links",
|
||||
HttpServletRequest.class, HttpServletResponse.class);
|
||||
private final Method linksMethod = ReflectionUtils.findMethod(getClass(), "links", HttpServletRequest.class,
|
||||
HttpServletResponse.class);
|
||||
|
||||
private final Method handleMethod = ReflectionUtils.findMethod(OperationHandler.class,
|
||||
"handle", HttpServletRequest.class, Map.class);
|
||||
private final Method handleMethod = ReflectionUtils.findMethod(OperationHandler.class, "handle",
|
||||
HttpServletRequest.class, Map.class);
|
||||
|
||||
private static final RequestMappingInfo.BuilderConfiguration builderConfig = getBuilderConfig();
|
||||
|
||||
@@ -96,8 +95,7 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
|
||||
* @param endpointMediaTypes media types consumed and produced by the endpoints
|
||||
*/
|
||||
public AbstractWebMvcEndpointHandlerMapping(EndpointMapping endpointMapping,
|
||||
Collection<ExposableWebEndpoint> endpoints,
|
||||
EndpointMediaTypes endpointMediaTypes) {
|
||||
Collection<ExposableWebEndpoint> endpoints, EndpointMediaTypes endpointMediaTypes) {
|
||||
this(endpointMapping, endpoints, endpointMediaTypes, null);
|
||||
}
|
||||
|
||||
@@ -110,8 +108,8 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
|
||||
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
|
||||
*/
|
||||
public AbstractWebMvcEndpointHandlerMapping(EndpointMapping endpointMapping,
|
||||
Collection<ExposableWebEndpoint> endpoints,
|
||||
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration) {
|
||||
Collection<ExposableWebEndpoint> endpoints, EndpointMediaTypes endpointMediaTypes,
|
||||
CorsConfiguration corsConfiguration) {
|
||||
this.endpointMapping = endpointMapping;
|
||||
this.endpoints = endpoints;
|
||||
this.endpointMediaTypes = endpointMediaTypes;
|
||||
@@ -133,16 +131,14 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
|
||||
|
||||
@Override
|
||||
public RequestMatchResult match(HttpServletRequest request, String pattern) {
|
||||
RequestMappingInfo info = RequestMappingInfo.paths(pattern).options(builderConfig)
|
||||
.build();
|
||||
RequestMappingInfo info = RequestMappingInfo.paths(pattern).options(builderConfig).build();
|
||||
RequestMappingInfo matchingInfo = info.getMatchingCondition(request);
|
||||
if (matchingInfo == null) {
|
||||
return null;
|
||||
}
|
||||
Set<String> patterns = matchingInfo.getPatternsCondition().getPatterns();
|
||||
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
|
||||
return new RequestMatchResult(patterns.iterator().next(), lookupPath,
|
||||
getPathMatcher());
|
||||
return new RequestMatchResult(patterns.iterator().next(), lookupPath, getPathMatcher());
|
||||
}
|
||||
|
||||
private static RequestMappingInfo.BuilderConfiguration getBuilderConfig() {
|
||||
@@ -154,13 +150,12 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
|
||||
return config;
|
||||
}
|
||||
|
||||
private void registerMappingForOperation(ExposableWebEndpoint endpoint,
|
||||
WebOperation operation) {
|
||||
private void registerMappingForOperation(ExposableWebEndpoint endpoint, WebOperation operation) {
|
||||
OperationInvoker invoker = operation::invoke;
|
||||
ServletWebOperation servletWebOperation = wrapServletWebOperation(endpoint,
|
||||
operation, new ServletWebOperationAdapter(invoker));
|
||||
registerMapping(createRequestMappingInfo(operation),
|
||||
new OperationHandler(servletWebOperation), this.handleMethod);
|
||||
ServletWebOperation servletWebOperation = wrapServletWebOperation(endpoint, operation,
|
||||
new ServletWebOperationAdapter(invoker));
|
||||
registerMapping(createRequestMappingInfo(operation), new OperationHandler(servletWebOperation),
|
||||
this.handleMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,47 +167,40 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
|
||||
* @return a wrapped servlet web operation
|
||||
*/
|
||||
|
||||
protected ServletWebOperation wrapServletWebOperation(ExposableWebEndpoint endpoint,
|
||||
WebOperation operation, ServletWebOperation servletWebOperation) {
|
||||
protected ServletWebOperation wrapServletWebOperation(ExposableWebEndpoint endpoint, WebOperation operation,
|
||||
ServletWebOperation servletWebOperation) {
|
||||
return servletWebOperation;
|
||||
}
|
||||
|
||||
private RequestMappingInfo createRequestMappingInfo(WebOperation operation) {
|
||||
WebOperationRequestPredicate predicate = operation.getRequestPredicate();
|
||||
PatternsRequestCondition patterns = patternsRequestConditionForPattern(
|
||||
predicate.getPath());
|
||||
PatternsRequestCondition patterns = patternsRequestConditionForPattern(predicate.getPath());
|
||||
RequestMethodsRequestCondition methods = new RequestMethodsRequestCondition(
|
||||
RequestMethod.valueOf(predicate.getHttpMethod().name()));
|
||||
ConsumesRequestCondition consumes = new ConsumesRequestCondition(
|
||||
StringUtils.toStringArray(predicate.getConsumes()));
|
||||
ProducesRequestCondition produces = new ProducesRequestCondition(
|
||||
StringUtils.toStringArray(predicate.getProduces()));
|
||||
return new RequestMappingInfo(null, patterns, methods, null, null, consumes,
|
||||
produces, null);
|
||||
return new RequestMappingInfo(null, patterns, methods, null, null, consumes, produces, null);
|
||||
}
|
||||
|
||||
private void registerLinksMapping() {
|
||||
PatternsRequestCondition patterns = patternsRequestConditionForPattern("");
|
||||
RequestMethodsRequestCondition methods = new RequestMethodsRequestCondition(
|
||||
RequestMethod.GET);
|
||||
ProducesRequestCondition produces = new ProducesRequestCondition(
|
||||
this.endpointMediaTypes.getProduced().toArray(StringUtils
|
||||
.toStringArray(this.endpointMediaTypes.getProduced())));
|
||||
RequestMappingInfo mapping = new RequestMappingInfo(patterns, methods, null, null,
|
||||
null, produces, null);
|
||||
RequestMethodsRequestCondition methods = new RequestMethodsRequestCondition(RequestMethod.GET);
|
||||
ProducesRequestCondition produces = new ProducesRequestCondition(this.endpointMediaTypes.getProduced()
|
||||
.toArray(StringUtils.toStringArray(this.endpointMediaTypes.getProduced())));
|
||||
RequestMappingInfo mapping = new RequestMappingInfo(patterns, methods, null, null, null, produces, null);
|
||||
registerMapping(mapping, this, this.linksMethod);
|
||||
}
|
||||
|
||||
private PatternsRequestCondition patternsRequestConditionForPattern(String path) {
|
||||
String[] patterns = new String[] { this.endpointMapping.createSubPath(path) };
|
||||
return new PatternsRequestCondition(patterns, builderConfig.getUrlPathHelper(),
|
||||
builderConfig.getPathMatcher(), builderConfig.useSuffixPatternMatch(),
|
||||
builderConfig.useTrailingSlashMatch());
|
||||
return new PatternsRequestCondition(patterns, builderConfig.getUrlPathHelper(), builderConfig.getPathMatcher(),
|
||||
builderConfig.useSuffixPatternMatch(), builderConfig.useTrailingSlashMatch());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CorsConfiguration initCorsConfiguration(Object handler, Method method,
|
||||
RequestMappingInfo mapping) {
|
||||
protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mapping) {
|
||||
return this.corsConfiguration;
|
||||
}
|
||||
|
||||
@@ -222,8 +210,7 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RequestMappingInfo getMappingForMethod(Method method,
|
||||
Class<?> handlerType) {
|
||||
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -232,8 +219,7 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
|
||||
interceptors.add(new SkipPathExtensionContentNegotiation());
|
||||
}
|
||||
|
||||
protected abstract Object links(HttpServletRequest request,
|
||||
HttpServletResponse response);
|
||||
protected abstract Object links(HttpServletRequest request, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* Return the web endpoints being mapped.
|
||||
@@ -266,13 +252,11 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(HttpServletRequest request,
|
||||
@RequestBody(required = false) Map<String, String> body) {
|
||||
public Object handle(HttpServletRequest request, @RequestBody(required = false) Map<String, String> body) {
|
||||
Map<String, Object> arguments = getArguments(request, body);
|
||||
try {
|
||||
return handleResult(
|
||||
this.invoker.invoke(new InvocationContext(
|
||||
new ServletSecurityContext(request), arguments)),
|
||||
this.invoker.invoke(new InvocationContext(new ServletSecurityContext(request), arguments)),
|
||||
HttpMethod.valueOf(request.getMethod()));
|
||||
}
|
||||
catch (InvalidEndpointRequestException ex) {
|
||||
@@ -280,35 +264,32 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> getArguments(HttpServletRequest request,
|
||||
Map<String, String> body) {
|
||||
private Map<String, Object> getArguments(HttpServletRequest request, Map<String, String> body) {
|
||||
Map<String, Object> arguments = new LinkedHashMap<>();
|
||||
arguments.putAll(getTemplateVariables(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;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, String> getTemplateVariables(HttpServletRequest request) {
|
||||
return (Map<String, String>) request
|
||||
.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
|
||||
return (Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
|
||||
}
|
||||
|
||||
private Object handleResult(Object result, HttpMethod httpMethod) {
|
||||
if (result == null) {
|
||||
return new ResponseEntity<>((httpMethod != HttpMethod.GET)
|
||||
? HttpStatus.NO_CONTENT : HttpStatus.NOT_FOUND);
|
||||
return new ResponseEntity<>(
|
||||
(httpMethod != HttpMethod.GET) ? HttpStatus.NO_CONTENT : HttpStatus.NOT_FOUND);
|
||||
}
|
||||
if (!(result instanceof WebEndpointResponse)) {
|
||||
return result;
|
||||
}
|
||||
WebEndpointResponse<?> response = (WebEndpointResponse<?>) result;
|
||||
return new ResponseEntity<Object>(response.getBody(),
|
||||
HttpStatus.valueOf(response.getStatus()));
|
||||
return new ResponseEntity<Object>(response.getBody(), HttpStatus.valueOf(response.getStatus()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -325,8 +306,7 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
public Object handle(HttpServletRequest request,
|
||||
@RequestBody(required = false) Map<String, String> body) {
|
||||
public Object handle(HttpServletRequest request, @RequestBody(required = false) Map<String, String> body) {
|
||||
return this.operation.handle(request, body);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -59,8 +59,7 @@ public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMappi
|
||||
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
|
||||
*/
|
||||
public ControllerEndpointHandlerMapping(EndpointMapping endpointMapping,
|
||||
Collection<ExposableControllerEndpoint> endpoints,
|
||||
CorsConfiguration corsConfiguration) {
|
||||
Collection<ExposableControllerEndpoint> endpoints, CorsConfiguration corsConfiguration) {
|
||||
Assert.notNull(endpointMapping, "EndpointMapping must not be null");
|
||||
Assert.notNull(endpoints, "Endpoints must not be null");
|
||||
this.endpointMapping = endpointMapping;
|
||||
@@ -70,8 +69,7 @@ public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMappi
|
||||
setUseSuffixPatternMatch(false);
|
||||
}
|
||||
|
||||
private Map<Object, ExposableControllerEndpoint> getHandlers(
|
||||
Collection<ExposableControllerEndpoint> endpoints) {
|
||||
private Map<Object, ExposableControllerEndpoint> getHandlers(Collection<ExposableControllerEndpoint> endpoints) {
|
||||
Map<Object, ExposableControllerEndpoint> handlers = new LinkedHashMap<>();
|
||||
endpoints.forEach((endpoint) -> handlers.put(endpoint.getController(), endpoint));
|
||||
return Collections.unmodifiableMap(handlers);
|
||||
@@ -83,44 +81,37 @@ public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMappi
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerHandlerMethod(Object handler, Method method,
|
||||
RequestMappingInfo mapping) {
|
||||
protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
|
||||
ExposableControllerEndpoint endpoint = this.handlers.get(handler);
|
||||
mapping = withEndpointMappedPatterns(endpoint, mapping);
|
||||
super.registerHandlerMethod(handler, method, mapping);
|
||||
}
|
||||
|
||||
private RequestMappingInfo withEndpointMappedPatterns(
|
||||
ExposableControllerEndpoint endpoint, RequestMappingInfo mapping) {
|
||||
private RequestMappingInfo withEndpointMappedPatterns(ExposableControllerEndpoint endpoint,
|
||||
RequestMappingInfo mapping) {
|
||||
Set<String> patterns = mapping.getPatternsCondition().getPatterns();
|
||||
if (patterns.isEmpty()) {
|
||||
patterns = Collections.singleton("");
|
||||
}
|
||||
String[] endpointMappedPatterns = patterns.stream()
|
||||
.map((pattern) -> getEndpointMappedPattern(endpoint, pattern))
|
||||
.toArray(String[]::new);
|
||||
.map((pattern) -> getEndpointMappedPattern(endpoint, pattern)).toArray(String[]::new);
|
||||
return withNewPatterns(mapping, endpointMappedPatterns);
|
||||
}
|
||||
|
||||
private String getEndpointMappedPattern(ExposableControllerEndpoint endpoint,
|
||||
String pattern) {
|
||||
private String getEndpointMappedPattern(ExposableControllerEndpoint endpoint, String pattern) {
|
||||
return this.endpointMapping.createSubPath(endpoint.getRootPath() + pattern);
|
||||
}
|
||||
|
||||
private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping,
|
||||
String[] patterns) {
|
||||
PatternsRequestCondition patternsCondition = new PatternsRequestCondition(
|
||||
patterns, null, null, useSuffixPatternMatch(), useTrailingSlashMatch(),
|
||||
null);
|
||||
return new RequestMappingInfo(patternsCondition, mapping.getMethodsCondition(),
|
||||
mapping.getParamsCondition(), mapping.getHeadersCondition(),
|
||||
mapping.getConsumesCondition(), mapping.getProducesCondition(),
|
||||
private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping, String[] patterns) {
|
||||
PatternsRequestCondition patternsCondition = new PatternsRequestCondition(patterns, null, null,
|
||||
useSuffixPatternMatch(), useTrailingSlashMatch(), null);
|
||||
return new RequestMappingInfo(patternsCondition, mapping.getMethodsCondition(), mapping.getParamsCondition(),
|
||||
mapping.getHeadersCondition(), mapping.getConsumesCondition(), mapping.getProducesCondition(),
|
||||
mapping.getCustomCondition());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CorsConfiguration initCorsConfiguration(Object handler, Method method,
|
||||
RequestMappingInfo mapping) {
|
||||
protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mapping) {
|
||||
return this.corsConfiguration;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,12 +30,11 @@ import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
*/
|
||||
final class SkipPathExtensionContentNegotiation extends HandlerInterceptorAdapter {
|
||||
|
||||
private static final String SKIP_ATTRIBUTE = PathExtensionContentNegotiationStrategy.class
|
||||
.getName() + ".SKIP";
|
||||
private static final String SKIP_ATTRIBUTE = PathExtensionContentNegotiationStrategy.class.getName() + ".SKIP";
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
|
||||
Object handler) throws Exception {
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
request.setAttribute(SKIP_ATTRIBUTE, Boolean.TRUE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -53,8 +53,7 @@ public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerM
|
||||
* @param corsConfiguration the CORS configuration for the endpoints or {@code null}
|
||||
* @param linksResolver resolver for determining links to available endpoints
|
||||
*/
|
||||
public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping,
|
||||
Collection<ExposableWebEndpoint> endpoints,
|
||||
public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection<ExposableWebEndpoint> endpoints,
|
||||
EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,
|
||||
EndpointLinksResolver linksResolver) {
|
||||
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration);
|
||||
@@ -64,10 +63,8 @@ public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerM
|
||||
|
||||
@Override
|
||||
@ResponseBody
|
||||
protected Map<String, Map<String, Link>> links(HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
return Collections.singletonMap("_links",
|
||||
this.linksResolver.resolveLinks(request.getRequestURL().toString()));
|
||||
protected Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
|
||||
return Collections.singletonMap("_links", this.linksResolver.resolveLinks(request.getRequestURL().toString()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -86,66 +86,54 @@ public class EnvironmentEndpoint {
|
||||
return getEnvironmentEntryDescriptor(toMatch);
|
||||
}
|
||||
|
||||
private EnvironmentDescriptor getEnvironmentDescriptor(
|
||||
Predicate<String> propertyNamePredicate) {
|
||||
private EnvironmentDescriptor getEnvironmentDescriptor(Predicate<String> propertyNamePredicate) {
|
||||
PlaceholdersResolver resolver = getResolver();
|
||||
List<PropertySourceDescriptor> propertySources = new ArrayList<>();
|
||||
getPropertySourcesAsMap().forEach((sourceName, source) -> {
|
||||
if (source instanceof EnumerablePropertySource) {
|
||||
propertySources.add(
|
||||
describeSource(sourceName, (EnumerablePropertySource<?>) source,
|
||||
resolver, propertyNamePredicate));
|
||||
propertySources.add(describeSource(sourceName, (EnumerablePropertySource<?>) source, resolver,
|
||||
propertyNamePredicate));
|
||||
}
|
||||
});
|
||||
return new EnvironmentDescriptor(
|
||||
Arrays.asList(this.environment.getActiveProfiles()), propertySources);
|
||||
return new EnvironmentDescriptor(Arrays.asList(this.environment.getActiveProfiles()), propertySources);
|
||||
}
|
||||
|
||||
private EnvironmentEntryDescriptor getEnvironmentEntryDescriptor(
|
||||
String propertyName) {
|
||||
Map<String, PropertyValueDescriptor> descriptors = getPropertySourceDescriptors(
|
||||
propertyName);
|
||||
private EnvironmentEntryDescriptor getEnvironmentEntryDescriptor(String propertyName) {
|
||||
Map<String, PropertyValueDescriptor> descriptors = getPropertySourceDescriptors(propertyName);
|
||||
PropertySummaryDescriptor summary = getPropertySummaryDescriptor(descriptors);
|
||||
return new EnvironmentEntryDescriptor(summary,
|
||||
Arrays.asList(this.environment.getActiveProfiles()),
|
||||
return new EnvironmentEntryDescriptor(summary, Arrays.asList(this.environment.getActiveProfiles()),
|
||||
toPropertySourceDescriptors(descriptors));
|
||||
}
|
||||
|
||||
private List<PropertySourceEntryDescriptor> toPropertySourceDescriptors(
|
||||
Map<String, PropertyValueDescriptor> descriptors) {
|
||||
List<PropertySourceEntryDescriptor> result = new ArrayList<>();
|
||||
descriptors.forEach((name, property) -> result
|
||||
.add(new PropertySourceEntryDescriptor(name, property)));
|
||||
descriptors.forEach((name, property) -> result.add(new PropertySourceEntryDescriptor(name, property)));
|
||||
return result;
|
||||
}
|
||||
|
||||
private PropertySummaryDescriptor getPropertySummaryDescriptor(
|
||||
Map<String, PropertyValueDescriptor> descriptors) {
|
||||
private PropertySummaryDescriptor getPropertySummaryDescriptor(Map<String, PropertyValueDescriptor> descriptors) {
|
||||
for (Map.Entry<String, PropertyValueDescriptor> entry : descriptors.entrySet()) {
|
||||
if (entry.getValue() != null) {
|
||||
return new PropertySummaryDescriptor(entry.getKey(),
|
||||
entry.getValue().getValue());
|
||||
return new PropertySummaryDescriptor(entry.getKey(), entry.getValue().getValue());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<String, PropertyValueDescriptor> getPropertySourceDescriptors(
|
||||
String propertyName) {
|
||||
private Map<String, PropertyValueDescriptor> getPropertySourceDescriptors(String propertyName) {
|
||||
Map<String, PropertyValueDescriptor> propertySources = new LinkedHashMap<>();
|
||||
PlaceholdersResolver resolver = getResolver();
|
||||
getPropertySourcesAsMap().forEach((sourceName, source) -> propertySources
|
||||
.put(sourceName, source.containsProperty(propertyName)
|
||||
? describeValueOf(propertyName, source, resolver) : null));
|
||||
getPropertySourcesAsMap().forEach((sourceName, source) -> propertySources.put(sourceName,
|
||||
source.containsProperty(propertyName) ? describeValueOf(propertyName, source, resolver) : null));
|
||||
return propertySources;
|
||||
}
|
||||
|
||||
private PropertySourceDescriptor describeSource(String sourceName,
|
||||
EnumerablePropertySource<?> source, PlaceholdersResolver resolver,
|
||||
Predicate<String> namePredicate) {
|
||||
private PropertySourceDescriptor describeSource(String sourceName, EnumerablePropertySource<?> source,
|
||||
PlaceholdersResolver resolver, Predicate<String> namePredicate) {
|
||||
Map<String, PropertyValueDescriptor> properties = new LinkedHashMap<>();
|
||||
Stream.of(source.getPropertyNames()).filter(namePredicate).forEach(
|
||||
(name) -> properties.put(name, describeValueOf(name, source, resolver)));
|
||||
Stream.of(source.getPropertyNames()).filter(namePredicate)
|
||||
.forEach((name) -> properties.put(name, describeValueOf(name, source, resolver)));
|
||||
return new PropertySourceDescriptor(sourceName, properties);
|
||||
}
|
||||
|
||||
@@ -153,8 +141,7 @@ public class EnvironmentEndpoint {
|
||||
private PropertyValueDescriptor describeValueOf(String name, PropertySource<?> source,
|
||||
PlaceholdersResolver resolver) {
|
||||
Object resolved = resolver.resolvePlaceholders(source.getProperty(name));
|
||||
String origin = ((source instanceof OriginLookup)
|
||||
? getOrigin((OriginLookup<Object>) source, name) : null);
|
||||
String origin = ((source instanceof OriginLookup) ? getOrigin((OriginLookup<Object>) source, name) : null);
|
||||
return new PropertyValueDescriptor(sanitize(name, resolved), origin);
|
||||
}
|
||||
|
||||
@@ -164,15 +151,13 @@ public class EnvironmentEndpoint {
|
||||
}
|
||||
|
||||
private PlaceholdersResolver getResolver() {
|
||||
return new PropertySourcesPlaceholdersSanitizingResolver(getPropertySources(),
|
||||
this.sanitizer);
|
||||
return new PropertySourcesPlaceholdersSanitizingResolver(getPropertySources(), this.sanitizer);
|
||||
}
|
||||
|
||||
private Map<String, PropertySource<?>> getPropertySourcesAsMap() {
|
||||
Map<String, PropertySource<?>> map = new LinkedHashMap<>();
|
||||
for (PropertySource<?> source : getPropertySources()) {
|
||||
if (!ConfigurationPropertySources
|
||||
.isAttachedConfigurationPropertySource(source)) {
|
||||
if (!ConfigurationPropertySources.isAttachedConfigurationPropertySource(source)) {
|
||||
extract("", map, source);
|
||||
}
|
||||
}
|
||||
@@ -186,11 +171,9 @@ public class EnvironmentEndpoint {
|
||||
return new StandardEnvironment().getPropertySources();
|
||||
}
|
||||
|
||||
private void extract(String root, Map<String, PropertySource<?>> map,
|
||||
PropertySource<?> source) {
|
||||
private void extract(String root, Map<String, PropertySource<?>> map, PropertySource<?> source) {
|
||||
if (source instanceof CompositePropertySource) {
|
||||
for (PropertySource<?> nest : ((CompositePropertySource) source)
|
||||
.getPropertySources()) {
|
||||
for (PropertySource<?> nest : ((CompositePropertySource) source).getPropertySources()) {
|
||||
extract(source.getName() + ":", map, nest);
|
||||
}
|
||||
}
|
||||
@@ -207,17 +190,13 @@ public class EnvironmentEndpoint {
|
||||
* {@link PropertySourcesPlaceholdersResolver} that sanitizes sensitive placeholders
|
||||
* if present.
|
||||
*/
|
||||
private static class PropertySourcesPlaceholdersSanitizingResolver
|
||||
extends PropertySourcesPlaceholdersResolver {
|
||||
private static class PropertySourcesPlaceholdersSanitizingResolver extends PropertySourcesPlaceholdersResolver {
|
||||
|
||||
private final Sanitizer sanitizer;
|
||||
|
||||
PropertySourcesPlaceholdersSanitizingResolver(Iterable<PropertySource<?>> sources,
|
||||
Sanitizer sanitizer) {
|
||||
super(sources,
|
||||
new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX,
|
||||
SystemPropertyUtils.PLACEHOLDER_SUFFIX,
|
||||
SystemPropertyUtils.VALUE_SEPARATOR, true));
|
||||
PropertySourcesPlaceholdersSanitizingResolver(Iterable<PropertySource<?>> sources, Sanitizer sanitizer) {
|
||||
super(sources, new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX,
|
||||
SystemPropertyUtils.PLACEHOLDER_SUFFIX, SystemPropertyUtils.VALUE_SEPARATOR, true));
|
||||
this.sanitizer = sanitizer;
|
||||
}
|
||||
|
||||
@@ -241,8 +220,7 @@ public class EnvironmentEndpoint {
|
||||
|
||||
private final List<PropertySourceDescriptor> propertySources;
|
||||
|
||||
private EnvironmentDescriptor(List<String> activeProfiles,
|
||||
List<PropertySourceDescriptor> propertySources) {
|
||||
private EnvironmentDescriptor(List<String> activeProfiles, List<PropertySourceDescriptor> propertySources) {
|
||||
this.activeProfiles = activeProfiles;
|
||||
this.propertySources = propertySources;
|
||||
}
|
||||
@@ -269,8 +247,7 @@ public class EnvironmentEndpoint {
|
||||
|
||||
private final List<PropertySourceEntryDescriptor> propertySources;
|
||||
|
||||
private EnvironmentEntryDescriptor(PropertySummaryDescriptor property,
|
||||
List<String> activeProfiles,
|
||||
private EnvironmentEntryDescriptor(PropertySummaryDescriptor property, List<String> activeProfiles,
|
||||
List<PropertySourceEntryDescriptor> propertySources) {
|
||||
this.property = property;
|
||||
this.activeProfiles = activeProfiles;
|
||||
@@ -325,8 +302,7 @@ public class EnvironmentEndpoint {
|
||||
|
||||
private final Map<String, PropertyValueDescriptor> properties;
|
||||
|
||||
private PropertySourceDescriptor(String name,
|
||||
Map<String, PropertyValueDescriptor> properties) {
|
||||
private PropertySourceDescriptor(String name, Map<String, PropertyValueDescriptor> properties) {
|
||||
this.name = name;
|
||||
this.properties = properties;
|
||||
}
|
||||
@@ -351,8 +327,7 @@ public class EnvironmentEndpoint {
|
||||
|
||||
private final PropertyValueDescriptor property;
|
||||
|
||||
private PropertySourceEntryDescriptor(String name,
|
||||
PropertyValueDescriptor property) {
|
||||
private PropertySourceEntryDescriptor(String name, PropertyValueDescriptor property) {
|
||||
this.name = name;
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,8 +38,7 @@ public class EnvironmentEndpointWebExtension {
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
public WebEndpointResponse<EnvironmentEntryDescriptor> environmentEntry(
|
||||
@Selector String toMatch) {
|
||||
public WebEndpointResponse<EnvironmentEntryDescriptor> environmentEntry(@Selector String toMatch) {
|
||||
EnvironmentEntryDescriptor descriptor = this.delegate.environmentEntry(toMatch);
|
||||
return new WebEndpointResponse<>(descriptor, getStatus(descriptor));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,11 +57,11 @@ public class FlywayEndpoint {
|
||||
Map<String, ContextFlywayBeans> contextFlywayBeans = new HashMap<>();
|
||||
while (target != null) {
|
||||
Map<String, FlywayDescriptor> flywayBeans = new HashMap<>();
|
||||
target.getBeansOfType(Flyway.class).forEach((name, flyway) -> flywayBeans
|
||||
.put(name, new FlywayDescriptor(flyway.info().all())));
|
||||
target.getBeansOfType(Flyway.class)
|
||||
.forEach((name, flyway) -> flywayBeans.put(name, new FlywayDescriptor(flyway.info().all())));
|
||||
ApplicationContext parent = target.getParent();
|
||||
contextFlywayBeans.put(target.getId(), new ContextFlywayBeans(flywayBeans,
|
||||
(parent != null) ? parent.getId() : null));
|
||||
contextFlywayBeans.put(target.getId(),
|
||||
new ContextFlywayBeans(flywayBeans, (parent != null) ? parent.getId() : null));
|
||||
target = parent;
|
||||
}
|
||||
return new ApplicationFlywayBeans(contextFlywayBeans);
|
||||
@@ -95,8 +95,7 @@ public class FlywayEndpoint {
|
||||
|
||||
private final String parentId;
|
||||
|
||||
private ContextFlywayBeans(Map<String, FlywayDescriptor> flywayBeans,
|
||||
String parentId) {
|
||||
private ContextFlywayBeans(Map<String, FlywayDescriptor> flywayBeans, String parentId) {
|
||||
this.flywayBeans = flywayBeans;
|
||||
this.parentId = parentId;
|
||||
}
|
||||
@@ -119,8 +118,7 @@ public class FlywayEndpoint {
|
||||
private final List<FlywayMigration> migrations;
|
||||
|
||||
private FlywayDescriptor(MigrationInfo[] migrations) {
|
||||
this.migrations = Stream.of(migrations).map(FlywayMigration::new)
|
||||
.collect(Collectors.toList());
|
||||
this.migrations = Stream.of(migrations).map(FlywayMigration::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public FlywayDescriptor(List<FlywayMigration> migrations) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,8 +33,7 @@ public abstract class AbstractHealthAggregator implements HealthAggregator {
|
||||
|
||||
@Override
|
||||
public final Health aggregate(Map<String, Health> healths) {
|
||||
List<Status> statusCandidates = healths.values().stream().map(Health::getStatus)
|
||||
.collect(Collectors.toList());
|
||||
List<Status> statusCandidates = healths.values().stream().map(Health::getStatus).collect(Collectors.toList());
|
||||
Status status = aggregateStatus(statusCandidates);
|
||||
Map<String, Object> details = aggregateDetails(healths);
|
||||
return new Health.Builder(status, details).build();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -70,10 +70,8 @@ public abstract class AbstractHealthIndicator implements HealthIndicator {
|
||||
* @param healthCheckFailedMessage the message to log on health check failure
|
||||
* @since 2.0.0
|
||||
*/
|
||||
protected AbstractHealthIndicator(
|
||||
Function<Exception, String> healthCheckFailedMessage) {
|
||||
Assert.notNull(healthCheckFailedMessage,
|
||||
"HealthCheckFailedMessage must not be null");
|
||||
protected AbstractHealthIndicator(Function<Exception, String> healthCheckFailedMessage) {
|
||||
Assert.notNull(healthCheckFailedMessage, "HealthCheckFailedMessage must not be null");
|
||||
this.healthCheckFailedMessage = healthCheckFailedMessage;
|
||||
}
|
||||
|
||||
@@ -86,8 +84,7 @@ public abstract class AbstractHealthIndicator implements HealthIndicator {
|
||||
catch (Exception ex) {
|
||||
if (this.logger.isWarnEnabled()) {
|
||||
String message = this.healthCheckFailedMessage.apply(ex);
|
||||
this.logger.warn(StringUtils.hasText(message) ? message : DEFAULT_MESSAGE,
|
||||
ex);
|
||||
this.logger.warn(StringUtils.hasText(message) ? message : DEFAULT_MESSAGE, ex);
|
||||
}
|
||||
builder.down(ex);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,8 +49,7 @@ public class CompositeHealthIndicator implements HealthIndicator {
|
||||
* @param indicators a map of {@link HealthIndicator}s with the key being used as an
|
||||
* indicator name.
|
||||
*/
|
||||
public CompositeHealthIndicator(HealthAggregator healthAggregator,
|
||||
Map<String, HealthIndicator> indicators) {
|
||||
public CompositeHealthIndicator(HealthAggregator healthAggregator, Map<String, HealthIndicator> indicators) {
|
||||
Assert.notNull(healthAggregator, "HealthAggregator must not be null");
|
||||
Assert.notNull(indicators, "Indicators must not be null");
|
||||
this.indicators = new LinkedHashMap<>(indicators);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,8 +31,7 @@ public class CompositeHealthIndicatorFactory {
|
||||
|
||||
private final Function<String, String> healthIndicatorNameFactory;
|
||||
|
||||
public CompositeHealthIndicatorFactory(
|
||||
Function<String, String> healthIndicatorNameFactory) {
|
||||
public CompositeHealthIndicatorFactory(Function<String, String> healthIndicatorNameFactory) {
|
||||
this.healthIndicatorNameFactory = healthIndicatorNameFactory;
|
||||
}
|
||||
|
||||
@@ -47,13 +46,11 @@ public class CompositeHealthIndicatorFactory {
|
||||
* @return a {@link HealthIndicator} that delegates to the specified
|
||||
* {@code healthIndicators}.
|
||||
*/
|
||||
public CompositeHealthIndicator createHealthIndicator(
|
||||
HealthAggregator healthAggregator,
|
||||
public CompositeHealthIndicator createHealthIndicator(HealthAggregator healthAggregator,
|
||||
Map<String, HealthIndicator> healthIndicators) {
|
||||
Assert.notNull(healthAggregator, "HealthAggregator must not be null");
|
||||
Assert.notNull(healthIndicators, "HealthIndicators must not be null");
|
||||
CompositeHealthIndicator healthIndicator = new CompositeHealthIndicator(
|
||||
healthAggregator);
|
||||
CompositeHealthIndicator healthIndicator = new CompositeHealthIndicator(healthAggregator);
|
||||
for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) {
|
||||
String name = this.healthIndicatorNameFactory.apply(entry.getKey());
|
||||
healthIndicator.addHealthIndicator(name, entry.getValue());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,8 +57,8 @@ public class CompositeReactiveHealthIndicator implements ReactiveHealthIndicator
|
||||
Assert.notNull(indicators, "Indicators must not be null");
|
||||
this.indicators = new LinkedHashMap<>(indicators);
|
||||
this.healthAggregator = healthAggregator;
|
||||
this.timeoutCompose = (mono) -> (this.timeout != null) ? mono.timeout(
|
||||
Duration.ofMillis(this.timeout), Mono.just(this.timeoutHealth)) : mono;
|
||||
this.timeoutCompose = (mono) -> (this.timeout != null)
|
||||
? mono.timeout(Duration.ofMillis(this.timeout), Mono.just(this.timeoutHealth)) : mono;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,8 +67,7 @@ public class CompositeReactiveHealthIndicator implements ReactiveHealthIndicator
|
||||
* @param indicator the health indicator to add
|
||||
* @return this instance
|
||||
*/
|
||||
public CompositeReactiveHealthIndicator addHealthIndicator(String name,
|
||||
ReactiveHealthIndicator indicator) {
|
||||
public CompositeReactiveHealthIndicator addHealthIndicator(String name, ReactiveHealthIndicator indicator) {
|
||||
this.indicators.put(name, indicator);
|
||||
return this;
|
||||
}
|
||||
@@ -82,21 +81,17 @@ public class CompositeReactiveHealthIndicator implements ReactiveHealthIndicator
|
||||
* {@code timeout}
|
||||
* @return this instance
|
||||
*/
|
||||
public CompositeReactiveHealthIndicator timeoutStrategy(long timeout,
|
||||
Health timeoutHealth) {
|
||||
public CompositeReactiveHealthIndicator timeoutStrategy(long timeout, Health timeoutHealth) {
|
||||
this.timeout = timeout;
|
||||
this.timeoutHealth = (timeoutHealth != null) ? timeoutHealth
|
||||
: Health.unknown().build();
|
||||
this.timeoutHealth = (timeoutHealth != null) ? timeoutHealth : Health.unknown().build();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Health> health() {
|
||||
return Flux.fromIterable(this.indicators.entrySet())
|
||||
.flatMap((entry) -> Mono.zip(Mono.just(entry.getKey()),
|
||||
entry.getValue().health().compose(this.timeoutCompose)))
|
||||
.collectMap(Tuple2::getT1, Tuple2::getT2)
|
||||
.map(this.healthAggregator::aggregate);
|
||||
return Flux.fromIterable(this.indicators.entrySet()).flatMap(
|
||||
(entry) -> Mono.zip(Mono.just(entry.getKey()), entry.getValue().health().compose(this.timeoutCompose)))
|
||||
.collectMap(Tuple2::getT1, Tuple2::getT2).map(this.healthAggregator::aggregate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,8 +33,7 @@ public class CompositeReactiveHealthIndicatorFactory {
|
||||
|
||||
private final Function<String, String> healthIndicatorNameFactory;
|
||||
|
||||
public CompositeReactiveHealthIndicatorFactory(
|
||||
Function<String, String> healthIndicatorNameFactory) {
|
||||
public CompositeReactiveHealthIndicatorFactory(Function<String, String> healthIndicatorNameFactory) {
|
||||
this.healthIndicatorNameFactory = healthIndicatorNameFactory;
|
||||
}
|
||||
|
||||
@@ -55,35 +54,28 @@ public class CompositeReactiveHealthIndicatorFactory {
|
||||
* @return a {@link ReactiveHealthIndicator} that delegates to the specified
|
||||
* {@code reactiveHealthIndicators}.
|
||||
*/
|
||||
public CompositeReactiveHealthIndicator createReactiveHealthIndicator(
|
||||
HealthAggregator healthAggregator,
|
||||
public CompositeReactiveHealthIndicator createReactiveHealthIndicator(HealthAggregator healthAggregator,
|
||||
Map<String, ReactiveHealthIndicator> reactiveHealthIndicators,
|
||||
Map<String, HealthIndicator> healthIndicators) {
|
||||
Assert.notNull(healthAggregator, "HealthAggregator must not be null");
|
||||
Assert.notNull(reactiveHealthIndicators,
|
||||
"ReactiveHealthIndicators must not be null");
|
||||
CompositeReactiveHealthIndicator healthIndicator = new CompositeReactiveHealthIndicator(
|
||||
healthAggregator);
|
||||
merge(reactiveHealthIndicators, healthIndicators)
|
||||
.forEach((beanName, indicator) -> {
|
||||
String name = this.healthIndicatorNameFactory.apply(beanName);
|
||||
healthIndicator.addHealthIndicator(name, indicator);
|
||||
});
|
||||
Assert.notNull(reactiveHealthIndicators, "ReactiveHealthIndicators must not be null");
|
||||
CompositeReactiveHealthIndicator healthIndicator = new CompositeReactiveHealthIndicator(healthAggregator);
|
||||
merge(reactiveHealthIndicators, healthIndicators).forEach((beanName, indicator) -> {
|
||||
String name = this.healthIndicatorNameFactory.apply(beanName);
|
||||
healthIndicator.addHealthIndicator(name, indicator);
|
||||
});
|
||||
return healthIndicator;
|
||||
}
|
||||
|
||||
private Map<String, ReactiveHealthIndicator> merge(
|
||||
Map<String, ReactiveHealthIndicator> reactiveHealthIndicators,
|
||||
private Map<String, ReactiveHealthIndicator> merge(Map<String, ReactiveHealthIndicator> reactiveHealthIndicators,
|
||||
Map<String, HealthIndicator> healthIndicators) {
|
||||
if (ObjectUtils.isEmpty(healthIndicators)) {
|
||||
return reactiveHealthIndicators;
|
||||
}
|
||||
Map<String, ReactiveHealthIndicator> allIndicators = new LinkedHashMap<>(
|
||||
reactiveHealthIndicators);
|
||||
Map<String, ReactiveHealthIndicator> allIndicators = new LinkedHashMap<>(reactiveHealthIndicators);
|
||||
healthIndicators.forEach((beanName, indicator) -> {
|
||||
String name = this.healthIndicatorNameFactory.apply(beanName);
|
||||
allIndicators.computeIfAbsent(name,
|
||||
(n) -> new HealthIndicatorReactiveAdapter(indicator));
|
||||
allIndicators.computeIfAbsent(name, (n) -> new HealthIndicatorReactiveAdapter(indicator));
|
||||
});
|
||||
return allIndicators;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,8 +39,7 @@ public class HealthEndpointWebExtension {
|
||||
|
||||
private final HealthWebEndpointResponseMapper responseMapper;
|
||||
|
||||
public HealthEndpointWebExtension(HealthIndicator delegate,
|
||||
HealthWebEndpointResponseMapper responseMapper) {
|
||||
public HealthEndpointWebExtension(HealthIndicator delegate, HealthWebEndpointResponseMapper responseMapper) {
|
||||
this.delegate = delegate;
|
||||
this.responseMapper = responseMapper;
|
||||
}
|
||||
@@ -50,10 +49,8 @@ public class HealthEndpointWebExtension {
|
||||
return this.responseMapper.map(this.delegate.health(), securityContext);
|
||||
}
|
||||
|
||||
public WebEndpointResponse<Health> getHealth(SecurityContext securityContext,
|
||||
ShowDetails showDetails) {
|
||||
return this.responseMapper.map(this.delegate.health(), securityContext,
|
||||
showDetails);
|
||||
public WebEndpointResponse<Health> getHealth(SecurityContext securityContext, ShowDetails showDetails) {
|
||||
return this.responseMapper.map(this.delegate.health(), securityContext, showDetails);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,8 +42,7 @@ public class HealthStatusHttpMapper {
|
||||
|
||||
private void setupDefaultStatusMapping() {
|
||||
addStatusMapping(Status.DOWN, WebEndpointResponse.STATUS_SERVICE_UNAVAILABLE);
|
||||
addStatusMapping(Status.OUT_OF_SERVICE,
|
||||
WebEndpointResponse.STATUS_SERVICE_UNAVAILABLE);
|
||||
addStatusMapping(Status.OUT_OF_SERVICE, WebEndpointResponse.STATUS_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,10 +101,8 @@ public class HealthStatusHttpMapper {
|
||||
public int mapStatus(Status status) {
|
||||
String code = getUniformValue(status.getCode());
|
||||
if (code != null) {
|
||||
return this.statusMapping.keySet().stream()
|
||||
.filter((key) -> code.equals(getUniformValue(key)))
|
||||
.map(this.statusMapping::get).findFirst()
|
||||
.orElse(WebEndpointResponse.STATUS_OK);
|
||||
return this.statusMapping.keySet().stream().filter((key) -> code.equals(getUniformValue(key)))
|
||||
.map(this.statusMapping::get).findFirst().orElse(WebEndpointResponse.STATUS_OK);
|
||||
}
|
||||
return WebEndpointResponse.STATUS_OK;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,8 +36,8 @@ public class HealthWebEndpointResponseMapper {
|
||||
|
||||
private final Set<String> authorizedRoles;
|
||||
|
||||
public HealthWebEndpointResponseMapper(HealthStatusHttpMapper statusHttpMapper,
|
||||
ShowDetails showDetails, Set<String> authorizedRoles) {
|
||||
public HealthWebEndpointResponseMapper(HealthStatusHttpMapper statusHttpMapper, ShowDetails showDetails,
|
||||
Set<String> authorizedRoles) {
|
||||
this.statusHttpMapper = statusHttpMapper;
|
||||
this.showDetails = showDetails;
|
||||
this.authorizedRoles = authorizedRoles;
|
||||
@@ -50,8 +50,7 @@ public class HealthWebEndpointResponseMapper {
|
||||
* @param securityContext the security context
|
||||
* @return the mapped response
|
||||
*/
|
||||
public WebEndpointResponse<Health> map(Health health,
|
||||
SecurityContext securityContext) {
|
||||
public WebEndpointResponse<Health> map(Health health, SecurityContext securityContext) {
|
||||
return map(health, securityContext, this.showDetails);
|
||||
}
|
||||
|
||||
@@ -63,12 +62,9 @@ public class HealthWebEndpointResponseMapper {
|
||||
* @param showDetails when to show details in the response
|
||||
* @return the mapped response
|
||||
*/
|
||||
public WebEndpointResponse<Health> map(Health health, SecurityContext securityContext,
|
||||
ShowDetails showDetails) {
|
||||
if (showDetails == ShowDetails.NEVER
|
||||
|| (showDetails == ShowDetails.WHEN_AUTHORIZED
|
||||
&& (securityContext.getPrincipal() == null
|
||||
|| !isUserInRole(securityContext)))) {
|
||||
public WebEndpointResponse<Health> map(Health health, SecurityContext securityContext, ShowDetails showDetails) {
|
||||
if (showDetails == ShowDetails.NEVER || (showDetails == ShowDetails.WHEN_AUTHORIZED
|
||||
&& (securityContext.getPrincipal() == null || !isUserInRole(securityContext)))) {
|
||||
health = Health.status(health.getStatus()).build();
|
||||
}
|
||||
Integer status = this.statusHttpMapper.mapStatus(health.getStatus());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,14 +44,11 @@ public class ReactiveHealthEndpointWebExtension {
|
||||
|
||||
@ReadOperation
|
||||
public Mono<WebEndpointResponse<Health>> health(SecurityContext securityContext) {
|
||||
return this.delegate.health()
|
||||
.map((health) -> this.responseMapper.map(health, securityContext));
|
||||
return this.delegate.health().map((health) -> this.responseMapper.map(health, securityContext));
|
||||
}
|
||||
|
||||
public Mono<WebEndpointResponse<Health>> health(SecurityContext securityContext,
|
||||
ShowDetails showDetails) {
|
||||
return this.delegate.health().map((health) -> this.responseMapper.map(health,
|
||||
securityContext, showDetails));
|
||||
public Mono<WebEndpointResponse<Health>> health(SecurityContext securityContext, ShowDetails showDetails) {
|
||||
return this.delegate.health().map((health) -> this.responseMapper.map(health, securityContext, showDetails));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,8 +32,7 @@ import org.springframework.core.env.ConfigurableEnvironment;
|
||||
*/
|
||||
public class EnvironmentInfoContributor implements InfoContributor {
|
||||
|
||||
private static final Bindable<Map<String, Object>> STRING_OBJECT_MAP = Bindable
|
||||
.mapOf(String.class, Object.class);
|
||||
private static final Bindable<Map<String, Object>> STRING_OBJECT_MAP = Bindable.mapOf(String.class, Object.class);
|
||||
|
||||
private final ConfigurableEnvironment environment;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -64,10 +64,8 @@ public class GitInfoContributor extends InfoPropertiesInfoContributor<GitPropert
|
||||
*/
|
||||
@Override
|
||||
protected void postProcessContent(Map<String, Object> content) {
|
||||
replaceValue(getNestedMap(content, "commit"), "time",
|
||||
getProperties().getCommitTime());
|
||||
replaceValue(getNestedMap(content, "build"), "time",
|
||||
getProperties().getInstant("build.time"));
|
||||
replaceValue(getNestedMap(content, "commit"), "time", getProperties().getCommitTime());
|
||||
replaceValue(getNestedMap(content, "build"), "time", getProperties().getInstant("build.time"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -62,8 +62,7 @@ public final class Info {
|
||||
public <T> T get(String id, Class<T> type) {
|
||||
Object value = get(id);
|
||||
if (value != null && type != null && !type.isInstance(value)) {
|
||||
throw new IllegalStateException("Info entry is not of required type ["
|
||||
+ type.getName() + "]: " + value);
|
||||
throw new IllegalStateException("Info entry is not of required type [" + type.getName() + "]: " + value);
|
||||
}
|
||||
return (T) value;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,11 +36,9 @@ import org.springframework.util.StringUtils;
|
||||
* @author Madhura Bhave
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public abstract class InfoPropertiesInfoContributor<T extends InfoProperties>
|
||||
implements InfoContributor {
|
||||
public abstract class InfoPropertiesInfoContributor<T extends InfoProperties> implements InfoContributor {
|
||||
|
||||
private static final Bindable<Map<String, Object>> STRING_OBJECT_MAP = Bindable
|
||||
.mapOf(String.class, Object.class);
|
||||
private static final Bindable<Map<String, Object>> STRING_OBJECT_MAP = Bindable.mapOf(String.class, Object.class);
|
||||
|
||||
private final T properties;
|
||||
|
||||
@@ -92,8 +90,8 @@ public abstract class InfoPropertiesInfoContributor<T extends InfoProperties>
|
||||
* @return the raw content
|
||||
*/
|
||||
protected Map<String, Object> extractContent(PropertySource<?> propertySource) {
|
||||
return new Binder(ConfigurationPropertySources.from(propertySource))
|
||||
.bind("", STRING_OBJECT_MAP).orElseGet(LinkedHashMap::new);
|
||||
return new Binder(ConfigurationPropertySources.from(propertySource)).bind("", STRING_OBJECT_MAP)
|
||||
.orElseGet(LinkedHashMap::new);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,8 +49,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Arthur Kalimullin
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class DataSourceHealthIndicator extends AbstractHealthIndicator
|
||||
implements InitializingBean {
|
||||
public class DataSourceHealthIndicator extends AbstractHealthIndicator implements InitializingBean {
|
||||
|
||||
private static final String DEFAULT_QUERY = "SELECT 1";
|
||||
|
||||
@@ -91,8 +90,7 @@ public class DataSourceHealthIndicator extends AbstractHealthIndicator
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.state(this.dataSource != null,
|
||||
"DataSource for DataSourceHealthIndicator must be specified");
|
||||
Assert.state(this.dataSource != null, "DataSource for DataSourceHealthIndicator must be specified");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,8 +109,7 @@ public class DataSourceHealthIndicator extends AbstractHealthIndicator
|
||||
String validationQuery = getValidationQuery(product);
|
||||
if (StringUtils.hasText(validationQuery)) {
|
||||
// Avoid calling getObject as it breaks MySQL on Java 7
|
||||
List<Object> results = this.jdbcTemplate.query(validationQuery,
|
||||
new SingleColumnRowMapper());
|
||||
List<Object> results = this.jdbcTemplate.query(validationQuery, new SingleColumnRowMapper());
|
||||
Object result = DataAccessUtils.requiredSingleResult(results);
|
||||
builder.withDetail("hello", result);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -51,8 +51,7 @@ public class JmsHealthIndicator extends AbstractHealthIndicator {
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
try (Connection connection = this.connectionFactory.createConnection()) {
|
||||
new MonitoredConnection(connection).start();
|
||||
builder.up().withDetail("provider",
|
||||
connection.getMetaData().getJMSProviderName());
|
||||
builder.up().withDetail("provider", connection.getMetaData().getJMSProviderName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,8 +69,8 @@ public class JmsHealthIndicator extends AbstractHealthIndicator {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
if (!this.latch.await(5, TimeUnit.SECONDS)) {
|
||||
JmsHealthIndicator.this.logger.warn(
|
||||
"Connection failed to start within 5 seconds and will be closed.");
|
||||
JmsHealthIndicator.this.logger
|
||||
.warn("Connection failed to start within 5 seconds and will be closed.");
|
||||
closeConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -65,18 +65,17 @@ public class LiquibaseEndpoint {
|
||||
DatabaseFactory factory = DatabaseFactory.getInstance();
|
||||
StandardChangeLogHistoryService service = new StandardChangeLogHistoryService();
|
||||
this.context.getBeansOfType(SpringLiquibase.class)
|
||||
.forEach((name, liquibase) -> liquibaseBeans.put(name,
|
||||
createReport(liquibase, service, factory)));
|
||||
.forEach((name, liquibase) -> liquibaseBeans.put(name, createReport(liquibase, service, factory)));
|
||||
ApplicationContext parent = target.getParent();
|
||||
contextBeans.put(target.getId(), new ContextLiquibaseBeans(liquibaseBeans,
|
||||
(parent != null) ? parent.getId() : null));
|
||||
contextBeans.put(target.getId(),
|
||||
new ContextLiquibaseBeans(liquibaseBeans, (parent != null) ? parent.getId() : null));
|
||||
target = parent;
|
||||
}
|
||||
return new ApplicationLiquibaseBeans(contextBeans);
|
||||
}
|
||||
|
||||
private LiquibaseBean createReport(SpringLiquibase liquibase,
|
||||
ChangeLogHistoryService service, DatabaseFactory factory) {
|
||||
private LiquibaseBean createReport(SpringLiquibase liquibase, ChangeLogHistoryService service,
|
||||
DatabaseFactory factory) {
|
||||
try {
|
||||
DataSource dataSource = liquibase.getDataSource();
|
||||
JdbcConnection connection = new JdbcConnection(dataSource.getConnection());
|
||||
@@ -88,8 +87,8 @@ public class LiquibaseEndpoint {
|
||||
database.setDefaultSchemaName(defaultSchema);
|
||||
}
|
||||
service.setDatabase(database);
|
||||
return new LiquibaseBean(service.getRanChangeSets().stream()
|
||||
.map(ChangeSet::new).collect(Collectors.toList()));
|
||||
return new LiquibaseBean(
|
||||
service.getRanChangeSets().stream().map(ChangeSet::new).collect(Collectors.toList()));
|
||||
}
|
||||
finally {
|
||||
if (database != null) {
|
||||
@@ -133,8 +132,7 @@ public class LiquibaseEndpoint {
|
||||
|
||||
private final String parentId;
|
||||
|
||||
private ContextLiquibaseBeans(Map<String, LiquibaseBean> liquibaseBeans,
|
||||
String parentId) {
|
||||
private ContextLiquibaseBeans(Map<String, LiquibaseBean> liquibaseBeans, String parentId) {
|
||||
this.liquibaseBeans = liquibaseBeans;
|
||||
this.parentId = parentId;
|
||||
}
|
||||
@@ -203,15 +201,14 @@ public class LiquibaseEndpoint {
|
||||
this.changeLog = ranChangeSet.getChangeLog();
|
||||
this.comments = ranChangeSet.getComments();
|
||||
this.contexts = ranChangeSet.getContextExpression().getContexts();
|
||||
this.dateExecuted = Instant
|
||||
.ofEpochMilli(ranChangeSet.getDateExecuted().getTime());
|
||||
this.dateExecuted = Instant.ofEpochMilli(ranChangeSet.getDateExecuted().getTime());
|
||||
this.deploymentId = ranChangeSet.getDeploymentId();
|
||||
this.description = ranChangeSet.getDescription();
|
||||
this.execType = ranChangeSet.getExecType();
|
||||
this.id = ranChangeSet.getId();
|
||||
this.labels = ranChangeSet.getLabels().getLabels();
|
||||
this.checksum = ((ranChangeSet.getLastCheckSum() != null)
|
||||
? ranChangeSet.getLastCheckSum().toString() : null);
|
||||
this.checksum = ((ranChangeSet.getLastCheckSum() != null) ? ranChangeSet.getLastCheckSum().toString()
|
||||
: null);
|
||||
this.orderExecuted = ranChangeSet.getOrderExecuted();
|
||||
this.tag = ranChangeSet.getTag();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,8 +57,7 @@ public class LoggersEndpoint {
|
||||
|
||||
@ReadOperation
|
||||
public Map<String, Object> loggers() {
|
||||
Collection<LoggerConfiguration> configurations = this.loggingSystem
|
||||
.getLoggerConfigurations();
|
||||
Collection<LoggerConfiguration> configurations = this.loggingSystem.getLoggerConfigurations();
|
||||
if (configurations == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
@@ -71,14 +70,12 @@ public class LoggersEndpoint {
|
||||
@ReadOperation
|
||||
public LoggerLevels loggerLevels(@Selector String name) {
|
||||
Assert.notNull(name, "Name must not be null");
|
||||
LoggerConfiguration configuration = this.loggingSystem
|
||||
.getLoggerConfiguration(name);
|
||||
LoggerConfiguration configuration = this.loggingSystem.getLoggerConfiguration(name);
|
||||
return (configuration != null) ? new LoggerLevels(configuration) : null;
|
||||
}
|
||||
|
||||
@WriteOperation
|
||||
public void configureLogLevel(@Selector String name,
|
||||
@Nullable LogLevel configuredLevel) {
|
||||
public void configureLogLevel(@Selector String name, @Nullable LogLevel configuredLevel) {
|
||||
Assert.notNull(name, "Name must not be empty");
|
||||
this.loggingSystem.setLogLevel(name, configuredLevel);
|
||||
}
|
||||
@@ -88,8 +85,7 @@ public class LoggersEndpoint {
|
||||
return new TreeSet<>(levels).descendingSet();
|
||||
}
|
||||
|
||||
private Map<String, LoggerLevels> getLoggers(
|
||||
Collection<LoggerConfiguration> configurations) {
|
||||
private Map<String, LoggerLevels> getLoggers(Collection<LoggerConfiguration> configurations) {
|
||||
Map<String, LoggerLevels> loggers = new LinkedHashMap<>(configurations.size());
|
||||
for (LoggerConfiguration configuration : configurations) {
|
||||
loggers.put(configuration.getName(), new LoggerLevels(configuration));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,8 +38,7 @@ public class MailHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Builder builder) throws Exception {
|
||||
builder.withDetail("location",
|
||||
this.mailSender.getHost() + ":" + this.mailSender.getPort());
|
||||
builder.withDetail("location", this.mailSender.getHost() + ":" + this.mailSender.getPort());
|
||||
this.mailSender.testConnection();
|
||||
builder.up();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -77,8 +77,7 @@ public class HeapDumpWebEndpoint {
|
||||
try {
|
||||
if (this.lock.tryLock(this.timeout, TimeUnit.MILLISECONDS)) {
|
||||
try {
|
||||
return new WebEndpointResponse<>(
|
||||
dumpHeap((live != null) ? live : true));
|
||||
return new WebEndpointResponse<>(dumpHeap((live != null) ? live : true));
|
||||
}
|
||||
finally {
|
||||
this.lock.unlock();
|
||||
@@ -89,12 +88,10 @@ public class HeapDumpWebEndpoint {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return new WebEndpointResponse<>(
|
||||
WebEndpointResponse.STATUS_INTERNAL_SERVER_ERROR);
|
||||
return new WebEndpointResponse<>(WebEndpointResponse.STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
catch (HeapDumperUnavailableException ex) {
|
||||
return new WebEndpointResponse<>(
|
||||
WebEndpointResponse.STATUS_SERVICE_UNAVAILABLE);
|
||||
return new WebEndpointResponse<>(WebEndpointResponse.STATUS_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
return new WebEndpointResponse<>(WebEndpointResponse.STATUS_TOO_MANY_REQUESTS);
|
||||
}
|
||||
@@ -110,8 +107,7 @@ public class HeapDumpWebEndpoint {
|
||||
|
||||
private File createTempFile(boolean live) throws IOException {
|
||||
String date = new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(new Date());
|
||||
File file = File.createTempFile("heapdump" + date + (live ? "-live" : ""),
|
||||
".hprof");
|
||||
File file = File.createTempFile("heapdump" + date + (live ? "-live" : ""), ".hprof");
|
||||
file.delete();
|
||||
return file;
|
||||
}
|
||||
@@ -156,23 +152,21 @@ public class HeapDumpWebEndpoint {
|
||||
@SuppressWarnings("unchecked")
|
||||
protected HotSpotDiagnosticMXBeanHeapDumper() {
|
||||
try {
|
||||
Class<?> diagnosticMXBeanClass = ClassUtils.resolveClassName(
|
||||
"com.sun.management.HotSpotDiagnosticMXBean", null);
|
||||
this.diagnosticMXBean = ManagementFactory.getPlatformMXBean(
|
||||
(Class<PlatformManagedObject>) diagnosticMXBeanClass);
|
||||
this.dumpHeapMethod = ReflectionUtils.findMethod(diagnosticMXBeanClass,
|
||||
"dumpHeap", String.class, Boolean.TYPE);
|
||||
Class<?> diagnosticMXBeanClass = ClassUtils
|
||||
.resolveClassName("com.sun.management.HotSpotDiagnosticMXBean", null);
|
||||
this.diagnosticMXBean = ManagementFactory
|
||||
.getPlatformMXBean((Class<PlatformManagedObject>) diagnosticMXBeanClass);
|
||||
this.dumpHeapMethod = ReflectionUtils.findMethod(diagnosticMXBeanClass, "dumpHeap", String.class,
|
||||
Boolean.TYPE);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new HeapDumperUnavailableException(
|
||||
"Unable to locate HotSpotDiagnosticMXBean", ex);
|
||||
throw new HeapDumperUnavailableException("Unable to locate HotSpotDiagnosticMXBean", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dumpHeap(File file, boolean live) {
|
||||
ReflectionUtils.invokeMethod(this.dumpHeapMethod, this.diagnosticMXBean,
|
||||
file.getAbsolutePath(), live);
|
||||
ReflectionUtils.invokeMethod(this.dumpHeapMethod, this.diagnosticMXBean, file.getAbsolutePath(), live);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -245,9 +239,8 @@ public class HeapDumpWebEndpoint {
|
||||
Files.delete(getFile().toPath());
|
||||
}
|
||||
catch (IOException ex) {
|
||||
TemporaryFileSystemResource.this.logger.warn(
|
||||
"Failed to delete temporary heap dump file '" + getFile() + "'",
|
||||
ex);
|
||||
TemporaryFileSystemResource.this.logger
|
||||
.warn("Failed to delete temporary heap dump file '" + getFile() + "'", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,8 +36,7 @@ public class ThreadDumpEndpoint {
|
||||
|
||||
@ReadOperation
|
||||
public ThreadDumpDescriptor threadDump() {
|
||||
return new ThreadDumpDescriptor(Arrays
|
||||
.asList(ManagementFactory.getThreadMXBean().dumpAllThreads(true, true)));
|
||||
return new ThreadDumpDescriptor(Arrays.asList(ManagementFactory.getThreadMXBean().dumpAllThreads(true, true)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -66,8 +66,7 @@ public class MetricsEndpoint {
|
||||
|
||||
private void collectNames(Set<String> names, MeterRegistry registry) {
|
||||
if (registry instanceof CompositeMeterRegistry) {
|
||||
((CompositeMeterRegistry) registry).getRegistries()
|
||||
.forEach((member) -> collectNames(names, member));
|
||||
((CompositeMeterRegistry) registry).getRegistries().forEach((member) -> collectNames(names, member));
|
||||
}
|
||||
else {
|
||||
registry.getMeters().stream().map(this::getName).forEach(names::add);
|
||||
@@ -79,11 +78,9 @@ public class MetricsEndpoint {
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
public MetricResponse metric(@Selector String requiredMetricName,
|
||||
@Nullable List<String> tag) {
|
||||
public MetricResponse metric(@Selector String requiredMetricName, @Nullable List<String> tag) {
|
||||
List<Tag> tags = parseTags(tag);
|
||||
Collection<Meter> meters = findFirstMatchingMeters(this.registry,
|
||||
requiredMetricName, tags);
|
||||
Collection<Meter> meters = findFirstMatchingMeters(this.registry, requiredMetricName, tags);
|
||||
if (meters.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
@@ -91,9 +88,8 @@ public class MetricsEndpoint {
|
||||
Map<String, Set<String>> availableTags = getAvailableTags(meters);
|
||||
tags.forEach((t) -> availableTags.remove(t.getKey()));
|
||||
Meter.Id meterId = meters.iterator().next().getId();
|
||||
return new MetricResponse(requiredMetricName, meterId.getDescription(),
|
||||
meterId.getBaseUnit(), asList(samples, Sample::new),
|
||||
asList(availableTags, AvailableTag::new));
|
||||
return new MetricResponse(requiredMetricName, meterId.getDescription(), meterId.getBaseUnit(),
|
||||
asList(samples, Sample::new), asList(availableTags, AvailableTag::new));
|
||||
}
|
||||
|
||||
private List<Tag> parseTags(List<String> tags) {
|
||||
@@ -113,20 +109,17 @@ public class MetricsEndpoint {
|
||||
return Tag.of(parts[0], parts[1]);
|
||||
}
|
||||
|
||||
private Collection<Meter> findFirstMatchingMeters(MeterRegistry registry, String name,
|
||||
Iterable<Tag> tags) {
|
||||
private Collection<Meter> findFirstMatchingMeters(MeterRegistry registry, String name, Iterable<Tag> tags) {
|
||||
if (registry instanceof CompositeMeterRegistry) {
|
||||
return findFirstMatchingMeters((CompositeMeterRegistry) registry, name, tags);
|
||||
}
|
||||
return registry.find(name).tags(tags).meters();
|
||||
}
|
||||
|
||||
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());
|
||||
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());
|
||||
}
|
||||
|
||||
private Map<Statistic, Double> getSamples(Collection<Meter> meters) {
|
||||
@@ -136,8 +129,8 @@ 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) {
|
||||
@@ -165,8 +158,7 @@ public class MetricsEndpoint {
|
||||
}
|
||||
|
||||
private <K, V, T> List<T> asList(Map<K, V> map, BiFunction<K, V, T> mapper) {
|
||||
return map.entrySet().stream()
|
||||
.map((entry) -> mapper.apply(entry.getKey(), entry.getValue()))
|
||||
return map.entrySet().stream().map((entry) -> mapper.apply(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
}
|
||||
|
||||
@@ -202,8 +194,8 @@ public class MetricsEndpoint {
|
||||
|
||||
private final List<AvailableTag> availableTags;
|
||||
|
||||
MetricResponse(String name, String description, String baseUnit,
|
||||
List<Sample> measurements, List<AvailableTag> availableTags) {
|
||||
MetricResponse(String name, String description, String baseUnit, List<Sample> measurements,
|
||||
List<AvailableTag> availableTags) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.baseUnit = baseUnit;
|
||||
@@ -281,8 +273,7 @@ public class MetricsEndpoint {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MeasurementSample{" + "statistic=" + this.statistic + ", value="
|
||||
+ this.value + '}';
|
||||
return "MeasurementSample{" + "statistic=" + this.statistic + ", value=" + this.value + '}';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -52,8 +52,7 @@ public class RabbitMetrics implements MeterBinder {
|
||||
|
||||
@Override
|
||||
public void bindTo(MeterRegistry registry) {
|
||||
this.connectionFactory.setMetricsCollector(
|
||||
new MicrometerMetricsCollector(registry, "rabbitmq", this.tags));
|
||||
this.connectionFactory.setMetricsCollector(new MicrometerMetricsCollector(registry, "rabbitmq", this.tags));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,8 +47,7 @@ public class CacheMetricsRegistrar {
|
||||
* @param binderProviders the {@link CacheMeterBinderProvider} instances that should
|
||||
* be used to detect compatible caches
|
||||
*/
|
||||
public CacheMetricsRegistrar(MeterRegistry registry,
|
||||
Collection<CacheMeterBinderProvider<?>> binderProviders) {
|
||||
public CacheMetricsRegistrar(MeterRegistry registry, Collection<CacheMeterBinderProvider<?>> binderProviders) {
|
||||
this.registry = registry;
|
||||
this.binderProviders = binderProviders;
|
||||
}
|
||||
@@ -72,12 +71,10 @@ public class CacheMetricsRegistrar {
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
private MeterBinder getMeterBinder(Cache cache, Tags tags) {
|
||||
Tags cacheTags = tags.and(getAdditionalTags(cache));
|
||||
return LambdaSafe
|
||||
.callbacks(CacheMeterBinderProvider.class, this.binderProviders, cache)
|
||||
return LambdaSafe.callbacks(CacheMeterBinderProvider.class, this.binderProviders, cache)
|
||||
.withLogger(CacheMetricsRegistrar.class)
|
||||
.invokeAnd((binderProvider) -> binderProvider.getMeterBinder(cache,
|
||||
cacheTags))
|
||||
.filter(Objects::nonNull).findFirst().orElse(null);
|
||||
.invokeAnd((binderProvider) -> binderProvider.getMeterBinder(cache, cacheTags)).filter(Objects::nonNull)
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,8 +87,7 @@ public class CacheMetricsRegistrar {
|
||||
}
|
||||
|
||||
private Cache unwrapIfNecessary(Cache cache) {
|
||||
if (ClassUtils.isPresent(
|
||||
"org.springframework.cache.transaction.TransactionAwareCacheDecorator",
|
||||
if (ClassUtils.isPresent("org.springframework.cache.transaction.TransactionAwareCacheDecorator",
|
||||
getClass().getClassLoader())) {
|
||||
return TransactionAwareCacheDecoratorHandler.unwrapIfNecessary(cache);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,8 +28,7 @@ import org.springframework.cache.caffeine.CaffeineCache;
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class CaffeineCacheMeterBinderProvider
|
||||
implements CacheMeterBinderProvider<CaffeineCache> {
|
||||
public class CaffeineCacheMeterBinderProvider implements CacheMeterBinderProvider<CaffeineCache> {
|
||||
|
||||
@Override
|
||||
public MeterBinder getMeterBinder(CaffeineCache cache, Iterable<Tag> tags) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,8 +28,7 @@ import org.springframework.cache.ehcache.EhCacheCache;
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class EhCache2CacheMeterBinderProvider
|
||||
implements CacheMeterBinderProvider<EhCacheCache> {
|
||||
public class EhCache2CacheMeterBinderProvider implements CacheMeterBinderProvider<EhCacheCache> {
|
||||
|
||||
@Override
|
||||
public MeterBinder getMeterBinder(EhCacheCache cache, Iterable<Tag> tags) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,8 +27,7 @@ import io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics;
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class HazelcastCacheMeterBinderProvider
|
||||
implements CacheMeterBinderProvider<HazelcastCache> {
|
||||
public class HazelcastCacheMeterBinderProvider implements CacheMeterBinderProvider<HazelcastCache> {
|
||||
|
||||
@Override
|
||||
public MeterBinder getMeterBinder(HazelcastCache cache, Iterable<Tag> tags) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,8 +28,7 @@ import org.springframework.cache.jcache.JCacheCache;
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class JCacheCacheMeterBinderProvider
|
||||
implements CacheMeterBinderProvider<JCacheCache> {
|
||||
public class JCacheCacheMeterBinderProvider implements CacheMeterBinderProvider<JCacheCache> {
|
||||
|
||||
@Override
|
||||
public MeterBinder getMeterBinder(JCacheCache cache, Iterable<Tag> tags) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -48,21 +48,17 @@ public class DataSourcePoolMetrics implements MeterBinder {
|
||||
|
||||
private final Iterable<Tag> tags;
|
||||
|
||||
public DataSourcePoolMetrics(DataSource dataSource,
|
||||
Collection<DataSourcePoolMetadataProvider> metadataProviders,
|
||||
public DataSourcePoolMetrics(DataSource dataSource, Collection<DataSourcePoolMetadataProvider> metadataProviders,
|
||||
String dataSourceName, Iterable<Tag> tags) {
|
||||
this(dataSource, new CompositeDataSourcePoolMetadataProvider(metadataProviders),
|
||||
dataSourceName, tags);
|
||||
this(dataSource, new CompositeDataSourcePoolMetadataProvider(metadataProviders), dataSourceName, tags);
|
||||
}
|
||||
|
||||
public DataSourcePoolMetrics(DataSource dataSource,
|
||||
DataSourcePoolMetadataProvider metadataProvider, String name,
|
||||
public DataSourcePoolMetrics(DataSource dataSource, DataSourcePoolMetadataProvider metadataProvider, String name,
|
||||
Iterable<Tag> tags) {
|
||||
Assert.notNull(dataSource, "DataSource must not be null");
|
||||
Assert.notNull(metadataProvider, "MetadataProvider must not be null");
|
||||
this.dataSource = dataSource;
|
||||
this.metadataProvider = new CachingDataSourcePoolMetadataProvider(
|
||||
metadataProvider);
|
||||
this.metadataProvider = new CachingDataSourcePoolMetadataProvider(metadataProvider);
|
||||
this.tags = Tags.concat(tags, "name", name);
|
||||
}
|
||||
|
||||
@@ -75,29 +71,26 @@ public class DataSourcePoolMetrics implements MeterBinder {
|
||||
}
|
||||
}
|
||||
|
||||
private <N extends Number> void bindPoolMetadata(MeterRegistry registry,
|
||||
String metricName, Function<DataSourcePoolMetadata, N> function) {
|
||||
bindDataSource(registry, metricName,
|
||||
this.metadataProvider.getValueFunction(function));
|
||||
private <N extends Number> void bindPoolMetadata(MeterRegistry registry, String metricName,
|
||||
Function<DataSourcePoolMetadata, N> function) {
|
||||
bindDataSource(registry, metricName, this.metadataProvider.getValueFunction(function));
|
||||
}
|
||||
|
||||
private <N extends Number> void bindDataSource(MeterRegistry registry,
|
||||
String metricName, Function<DataSource, N> function) {
|
||||
private <N extends Number> void bindDataSource(MeterRegistry registry, String metricName,
|
||||
Function<DataSource, N> function) {
|
||||
if (function.apply(this.dataSource) != null) {
|
||||
registry.gauge("jdbc.connections." + metricName, this.tags, this.dataSource,
|
||||
(m) -> function.apply(m).doubleValue());
|
||||
}
|
||||
}
|
||||
|
||||
private static class CachingDataSourcePoolMetadataProvider
|
||||
implements DataSourcePoolMetadataProvider {
|
||||
private static class CachingDataSourcePoolMetadataProvider implements DataSourcePoolMetadataProvider {
|
||||
|
||||
private static final Map<DataSource, DataSourcePoolMetadata> cache = new ConcurrentReferenceHashMap<>();
|
||||
|
||||
private final DataSourcePoolMetadataProvider metadataProvider;
|
||||
|
||||
CachingDataSourcePoolMetadataProvider(
|
||||
DataSourcePoolMetadataProvider metadataProvider) {
|
||||
CachingDataSourcePoolMetadataProvider(DataSourcePoolMetadataProvider metadataProvider) {
|
||||
this.metadataProvider = metadataProvider;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,18 +30,14 @@ import org.springframework.util.StringUtils;
|
||||
* @author Jon Schneider
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class DefaultRestTemplateExchangeTagsProvider
|
||||
implements RestTemplateExchangeTagsProvider {
|
||||
public class DefaultRestTemplateExchangeTagsProvider implements RestTemplateExchangeTagsProvider {
|
||||
|
||||
@Override
|
||||
public Iterable<Tag> getTags(String urlTemplate, HttpRequest request,
|
||||
ClientHttpResponse response) {
|
||||
Tag uriTag = (StringUtils.hasText(urlTemplate)
|
||||
? RestTemplateExchangeTags.uri(urlTemplate)
|
||||
public Iterable<Tag> getTags(String urlTemplate, HttpRequest request, ClientHttpResponse response) {
|
||||
Tag uriTag = (StringUtils.hasText(urlTemplate) ? RestTemplateExchangeTags.uri(urlTemplate)
|
||||
: RestTemplateExchangeTags.uri(request));
|
||||
return Arrays.asList(RestTemplateExchangeTags.method(request), uriTag,
|
||||
RestTemplateExchangeTags.status(response),
|
||||
RestTemplateExchangeTags.clientName(request));
|
||||
RestTemplateExchangeTags.status(response), RestTemplateExchangeTags.clientName(request));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,8 +41,7 @@ import org.springframework.web.util.UriTemplateHandler;
|
||||
*/
|
||||
class MetricsClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private static final ThreadLocal<String> urlTemplate = new NamedThreadLocal<>(
|
||||
"Rest Template URL Template");
|
||||
private static final ThreadLocal<String> urlTemplate = new NamedThreadLocal<>("Rest Template URL Template");
|
||||
|
||||
private final MeterRegistry meterRegistry;
|
||||
|
||||
@@ -50,16 +49,16 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto
|
||||
|
||||
private final String metricName;
|
||||
|
||||
MetricsClientHttpRequestInterceptor(MeterRegistry meterRegistry,
|
||||
RestTemplateExchangeTagsProvider tagProvider, String metricName) {
|
||||
MetricsClientHttpRequestInterceptor(MeterRegistry meterRegistry, RestTemplateExchangeTagsProvider tagProvider,
|
||||
String metricName) {
|
||||
this.tagProvider = tagProvider;
|
||||
this.meterRegistry = meterRegistry;
|
||||
this.metricName = metricName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
|
||||
ClientHttpRequestExecution execution) throws IOException {
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
|
||||
throws IOException {
|
||||
long startTime = System.nanoTime();
|
||||
ClientHttpResponse response = null;
|
||||
try {
|
||||
@@ -67,8 +66,8 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto
|
||||
return response;
|
||||
}
|
||||
finally {
|
||||
getTimeBuilder(request, response).register(this.meterRegistry)
|
||||
.record(System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
|
||||
getTimeBuilder(request, response).register(this.meterRegistry).record(System.nanoTime() - startTime,
|
||||
TimeUnit.NANOSECONDS);
|
||||
urlTemplate.remove();
|
||||
}
|
||||
}
|
||||
@@ -91,10 +90,8 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto
|
||||
};
|
||||
}
|
||||
|
||||
private Timer.Builder getTimeBuilder(HttpRequest request,
|
||||
ClientHttpResponse response) {
|
||||
return Timer.builder(this.metricName)
|
||||
.tags(this.tagProvider.getTags(urlTemplate.get(), request, response))
|
||||
private Timer.Builder getTimeBuilder(HttpRequest request, ClientHttpResponse response) {
|
||||
return Timer.builder(this.metricName).tags(this.tagProvider.getTags(urlTemplate.get(), request, response))
|
||||
.description("Timer of RestTemplate operation");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,10 +46,9 @@ public class MetricsRestTemplateCustomizer implements RestTemplateCustomizer {
|
||||
* @param tagProvider the tag provider
|
||||
* @param metricName the name of the recorded metric
|
||||
*/
|
||||
public MetricsRestTemplateCustomizer(MeterRegistry meterRegistry,
|
||||
RestTemplateExchangeTagsProvider tagProvider, String metricName) {
|
||||
this.interceptor = new MetricsClientHttpRequestInterceptor(meterRegistry,
|
||||
tagProvider, metricName);
|
||||
public MetricsRestTemplateCustomizer(MeterRegistry meterRegistry, RestTemplateExchangeTagsProvider tagProvider,
|
||||
String metricName) {
|
||||
this.interceptor = new MetricsClientHttpRequestInterceptor(meterRegistry, tagProvider, metricName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,8 +56,7 @@ public class MetricsRestTemplateCustomizer implements RestTemplateCustomizer {
|
||||
UriTemplateHandler templateHandler = restTemplate.getUriTemplateHandler();
|
||||
templateHandler = this.interceptor.createUriTemplateHandler(templateHandler);
|
||||
restTemplate.setUriTemplateHandler(templateHandler);
|
||||
List<ClientHttpRequestInterceptor> existingInterceptors = restTemplate
|
||||
.getInterceptors();
|
||||
List<ClientHttpRequestInterceptor> existingInterceptors = restTemplate.getInterceptors();
|
||||
if (!existingInterceptors.contains(this.interceptor)) {
|
||||
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
|
||||
interceptors.add(this.interceptor);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user