Remove Legacy Metrics

- Simplify MBeans - instead of wrapping to expose lifecycle methods,
  implement `ManageableLifecycle`. Register an additional MBean for
  polled endpoints to control the lifecycle.

* Polishing

- Move `QueueChannel` `@ManagedAttribute`s to `QueueChannelOperations`
- Make all `AbstractEndpoints` `IntegrationManagedResource`s and remove `ManagedEndpoint`
  to allow exposure of any `@Managed*` methods (including those on `Pausable`)
- Revert to `Lifecycle` for classes that are not related to endpoints
- Remove legacy metrics from docs
This commit is contained in:
Gary Russell
2020-08-07 12:56:57 -04:00
committed by GitHub
parent da5d002d64
commit 1beb854fb4
148 changed files with 533 additions and 7064 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -111,14 +111,6 @@ public class IntegrationMBeanExportConfiguration implements ImportAware, Environ
setupDomain(exporter);
setupServer(exporter);
setupComponentNamePatterns(exporter);
if (this.configurer != null) {
if (this.configurer.getDefaultCountsEnabled() == null) {
this.configurer.setDefaultCountsEnabled(true);
}
if (this.configurer.getDefaultStatsEnabled() == null) {
this.configurer.setDefaultStatsEnabled(true);
}
}
return exporter;
}

View File

@@ -42,6 +42,7 @@ import org.springframework.beans.factory.config.DestructionAwareBeanPostProcesso
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.Lifecycle;
import org.springframework.integration.channel.AbstractMessageChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.IntegrationConfigUtils;
import org.springframework.integration.config.IntegrationManagementConfigurer;
@@ -50,15 +51,17 @@ import org.springframework.integration.context.OrderlyShutdownCapable;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.core.MessageSource;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.endpoint.AbstractMessageSource;
import org.springframework.integration.endpoint.IntegrationConsumer;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.gateway.MessagingGatewaySupport;
import org.springframework.integration.handler.AbstractMessageHandler;
import org.springframework.integration.handler.AbstractMessageProducingHandler;
import org.springframework.integration.history.MessageHistoryConfigurer;
import org.springframework.integration.support.context.NamedComponent;
import org.springframework.integration.support.management.MappingMessageRouterManagement;
import org.springframework.integration.support.management.MessageSourceManagement;
import org.springframework.integration.support.management.TrackableComponent;
import org.springframework.integration.support.management.IntegrationInboundManagement;
import org.springframework.integration.support.management.IntegrationManagement;
import org.springframework.integration.support.management.ManageableLifecycle;
import org.springframework.integration.support.utils.PatternMatchUtils;
import org.springframework.jmx.export.MBeanExporter;
import org.springframework.jmx.export.UnableToRegisterMBeanException;
@@ -66,8 +69,10 @@ import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedMetric;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler;
import org.springframework.jmx.export.naming.MetadataNamingStrategy;
import org.springframework.jmx.support.MetricType;
import org.springframework.lang.Nullable;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.util.Assert;
@@ -116,22 +121,15 @@ public class IntegrationMBeanExporter extends MBeanExporter
private final Map<Object, AtomicLong> anonymousSourceCounters = new HashMap<>();
private final Set<org.springframework.integration.support.management.MessageHandlerMetrics>
handlers = new HashSet<>();
private final Map<String, IntegrationManagement> handlers = new HashMap<>();
private final Set<org.springframework.integration.support.management.MessageSourceMetrics>
sources = new HashSet<>();
private final Map<String, IntegrationInboundManagement> sources = new HashMap<>();
private final Map<IntegrationInboundManagement, ManageableLifecycle> sourceLifecycles = new HashMap<>();
private final Set<Lifecycle> inboundLifecycleMessageProducers = new HashSet<>();
private final Set<org.springframework.integration.support.management.MessageChannelMetrics>
channels = new HashSet<>();
private final Map<String, org.springframework.integration.support.management.MessageChannelMetrics>
allChannelsByName = new HashMap<>();
private final Map<String, org.springframework.integration.support.management.MessageSourceMetrics>
allSourcesByName = new HashMap<>();
private final Map<String, IntegrationManagement> channels = new HashMap<>();
private final Map<Object, String> endpointsByMonitor = new HashMap<>();
@@ -146,7 +144,7 @@ public class IntegrationMBeanExporter extends MBeanExporter
private final Set<Object> runtimeBeans = new HashSet<>();
private final MetadataNamingStrategy defaultNamingStrategy =
new IntegrationMetadataNamingStrategy(this.attributeSource);
new MetadataNamingStrategy(this.attributeSource);
private String domain = DEFAULT_DOMAIN;
@@ -162,7 +160,7 @@ public class IntegrationMBeanExporter extends MBeanExporter
// Shouldn't be necessary, but to be on the safe side...
setAutodetect(false);
setNamingStrategy(this.defaultNamingStrategy);
setAssembler(new IntegrationMetadataMBeanInfoAssembler(this.attributeSource));
setAssembler(new MetadataMBeanInfoAssembler(this.attributeSource));
}
/**
@@ -248,14 +246,12 @@ public class IntegrationMBeanExporter extends MBeanExporter
}
private void populateMessageHandlers() {
Map<String, org.springframework.integration.support.management.MessageHandlerMetrics> messageHandlers =
this.applicationContext
.getBeansOfType(org.springframework.integration.support.management.MessageHandlerMetrics.class);
for (Entry<String, org.springframework.integration.support.management.MessageHandlerMetrics> entry
: messageHandlers.entrySet()) {
Map<String, MessageHandler> messageHandlers = this.applicationContext
.getBeansOfType(MessageHandler.class);
for (Entry<String, MessageHandler> entry : messageHandlers.entrySet()) {
String beanName = entry.getKey();
org.springframework.integration.support.management.MessageHandlerMetrics bean = entry.getValue();
MessageHandler bean = entry.getValue();
if (this.handlerInAnonymousWrapper(bean) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping " + beanName + " because it wraps another handler");
@@ -264,34 +260,35 @@ public class IntegrationMBeanExporter extends MBeanExporter
}
// If the handler is proxied, we have to extract the target to expose as an MBean.
// The MetadataMBeanInfoAssembler does not support JDK dynamic proxies.
org.springframework.integration.support.management.MessageHandlerMetrics monitor =
(org.springframework.integration.support.management.MessageHandlerMetrics) extractTarget(bean);
this.handlers.add(monitor);
MessageHandler monitor = (MessageHandler) extractTarget(bean);
if (monitor instanceof IntegrationManagement) {
this.handlers.put(beanName, (IntegrationManagement) monitor);
}
}
}
private void populateMessageSources() {
this.applicationContext.getBeansOfType(
org.springframework.integration.support.management.MessageSourceMetrics.class)
IntegrationInboundManagement.class)
.values()
.stream()
// If the channel is proxied, we have to extract the target to expose as an MBean.
// If the source is proxied, we have to extract the target to expose as an MBean.
// The MetadataMBeanInfoAssembler does not support JDK dynamic proxies.
.map(this::extractTarget)
.map(org.springframework.integration.support.management.MessageSourceMetrics.class::cast)
.forEach(this.sources::add);
.map(IntegrationInboundManagement.class::cast)
.forEach(src -> this.sources.put(src.getComponentName(), src));
}
private void populateMessageChannels() {
this.applicationContext.getBeansOfType(
org.springframework.integration.support.management.MessageChannelMetrics.class)
this.applicationContext.getBeansOfType(MessageChannel.class)
.values()
.stream()
// If the channel is proxied, we have to extract the target to expose as an MBean.
// The MetadataMBeanInfoAssembler does not support JDK dynamic proxies.
.map(this::extractTarget)
.map(org.springframework.integration.support.management.MessageChannelMetrics.class::cast)
.forEach(this.channels::add);
.filter(ch -> ch instanceof IntegrationManagement)
.map(IntegrationManagement.class::cast)
.forEach(ch -> this.channels.put(ch.getComponentName(), ch));
}
private void populateMessageProducers() {
@@ -305,8 +302,6 @@ public class IntegrationMBeanExporter extends MBeanExporter
private void configureManagementConfigurer() {
if (!this.applicationContext.containsBean(IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME)) {
this.managementConfigurer = new IntegrationManagementConfigurer();
this.managementConfigurer.setDefaultCountsEnabled(true);
this.managementConfigurer.setDefaultStatsEnabled(true);
this.managementConfigurer.setApplicationContext(this.applicationContext);
this.managementConfigurer.setBeanName(IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME);
this.managementConfigurer.afterSingletonsInstantiated();
@@ -322,12 +317,13 @@ public class IntegrationMBeanExporter extends MBeanExporter
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (this.singletonsInstantiated) {
try {
if (bean instanceof org.springframework.integration.support.management.MessageChannelMetrics) {
org.springframework.integration.support.management.MessageChannelMetrics monitor =
(org.springframework.integration.support.management.MessageChannelMetrics) extractTarget(bean);
this.channels.add(monitor);
registerChannel(monitor);
this.runtimeBeans.add(bean);
if (bean instanceof MessageChannel) {
MessageChannel monitor = (MessageChannel) extractTarget(bean);
if (monitor instanceof IntegrationManagement) {
this.channels.put(beanName, (IntegrationManagement) monitor);
registerChannel((IntegrationManagement) monitor);
this.runtimeBeans.add(bean);
}
}
else if (bean instanceof MessageProducer && bean instanceof Lifecycle) {
registerProducer((MessageProducer) bean);
@@ -348,25 +344,23 @@ public class IntegrationMBeanExporter extends MBeanExporter
if (bean instanceof IntegrationConsumer) {
IntegrationConsumer integrationConsumer = (IntegrationConsumer) bean;
MessageHandler handler = integrationConsumer.getHandler();
if (handler instanceof org.springframework.integration.support.management.MessageHandlerMetrics) {
org.springframework.integration.support.management.MessageHandlerMetrics messageHandlerMetrics =
(org.springframework.integration.support.management.MessageHandlerMetrics) extractTarget(handler);
registerHandler(messageHandlerMetrics);
this.handlers.add(messageHandlerMetrics);
this.runtimeBeans.add(messageHandlerMetrics);
return;
MessageHandler monitor = (MessageHandler) extractTarget(handler);
if (monitor instanceof IntegrationManagement) {
registerHandler((IntegrationManagement) monitor);
this.handlers.put(((IntegrationManagement) monitor).getComponentName(),
(IntegrationManagement) monitor);
this.runtimeBeans.add(monitor);
}
return;
}
else if (bean instanceof SourcePollingChannelAdapter) {
SourcePollingChannelAdapter pollingChannelAdapter = (SourcePollingChannelAdapter) bean;
MessageSource<?> messageSource = pollingChannelAdapter.getMessageSource();
if (messageSource instanceof org.springframework.integration.support.management.MessageSourceMetrics) {
org.springframework.integration.support.management.MessageSourceMetrics messageSourceMetrics =
(org.springframework.integration.support.management.MessageSourceMetrics)
extractTarget(messageSource);
registerSource(messageSourceMetrics);
this.sources.add(messageSourceMetrics);
this.runtimeBeans.add(messageSourceMetrics);
if (messageSource instanceof IntegrationInboundManagement) {
IntegrationInboundManagement monitor = (IntegrationInboundManagement) extractTarget(messageSource);
registerSource(monitor);
this.sourceLifecycles.put(monitor, pollingChannelAdapter);
this.runtimeBeans.add(monitor);
return;
}
}
@@ -384,9 +378,9 @@ public class IntegrationMBeanExporter extends MBeanExporter
@Override
public boolean requiresDestruction(Object bean) {
return bean instanceof org.springframework.integration.support.management.MessageChannelMetrics || // NOSONAR
bean instanceof org.springframework.integration.support.management.MessageHandlerMetrics ||
bean instanceof org.springframework.integration.support.management.MessageSourceMetrics ||
return bean instanceof AbstractMessageChannel || // NOSONAR
bean instanceof AbstractMessageHandler ||
bean instanceof AbstractMessageSource<?> ||
(bean instanceof MessageProducer && bean instanceof Lifecycle) ||
bean instanceof AbstractEndpoint;
}
@@ -403,21 +397,16 @@ public class IntegrationMBeanExporter extends MBeanExporter
else {
this.endpointsByMonitor.remove(bean);
if (bean instanceof org.springframework.integration.support.management.MessageChannelMetrics) {
this.channels.remove(bean);
this.allChannelsByName.remove(((NamedComponent) bean).getComponentName());
if (bean instanceof IntegrationManagement) {
this.channels.remove(((NamedComponent) bean).getComponentName());
}
else if (bean instanceof org.springframework.integration.support.management.MessageHandlerMetrics) {
this.handlers.remove(bean);
else if (bean instanceof IntegrationManagement) {
this.handlers.remove(((NamedComponent) bean).getComponentName());
this.endpointNames.remove(((NamedComponent) bean).getComponentName());
}
else if (bean instanceof org.springframework.integration.support.management.MessageSourceMetrics) {
this.sources.remove(bean);
else if (bean instanceof IntegrationInboundManagement) {
this.sources.remove(((NamedComponent) bean).getComponentName());
this.endpointNames.remove(((NamedComponent) bean).getComponentName());
String managedName =
((org.springframework.integration.support.management.MessageSourceMetrics) bean)
.getManagedName();
this.allSourcesByName.remove(managedName);
}
}
}
@@ -488,20 +477,6 @@ public class IntegrationMBeanExporter extends MBeanExporter
}
}
@Override
public void destroy() {
super.destroy();
for (org.springframework.integration.support.management.MessageChannelMetrics monitor : this.channels) {
logger.info("Summary on shutdown: " + monitor);
}
for (org.springframework.integration.support.management.MessageHandlerMetrics monitor : this.handlers) {
logger.info("Summary on shutdown: " + monitor);
}
for (org.springframework.integration.support.management.MessageSourceMetrics monitor : this.sources) {
logger.info("Summary on shutdown: " + monitor);
}
}
/**
* Shutdown active components.
* @param howLong The time to wait in total for all activities to complete
@@ -556,20 +531,11 @@ public class IntegrationMBeanExporter extends MBeanExporter
*/
@ManagedOperation
public void stopMessageSources() {
for (org.springframework.integration.support.management.MessageSourceMetrics sourceMetrics
: this.allSourcesByName.values()) {
if (sourceMetrics instanceof Lifecycle) {
if (logger.isInfoEnabled()) {
logger.info("Stopping message source " + sourceMetrics);
}
((Lifecycle) sourceMetrics).stop();
}
else {
if (logger.isInfoEnabled()) {
logger.info("Message source " + sourceMetrics + " cannot be stopped");
}
for (Lifecycle source : this.sourceLifecycles.values()) {
if (logger.isInfoEnabled()) {
logger.info("Stopping message source " + source);
}
source.stop();
}
}
@@ -592,8 +558,8 @@ public class IntegrationMBeanExporter extends MBeanExporter
@ManagedOperation
public void stopActiveChannels() {
// Stop any "active" channels (JMS etc).
for (org.springframework.integration.support.management.MessageChannelMetrics metrics : this.allChannelsByName.values()) {
MessageChannel channel = (MessageChannel) metrics;
for (IntegrationManagement metrics : this.channels.values()) {
IntegrationManagement channel = metrics;
if (channel instanceof Lifecycle) {
if (logger.isInfoEnabled()) {
logger.info("Stopping channel " + channel);
@@ -631,41 +597,41 @@ public class IntegrationMBeanExporter extends MBeanExporter
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "MessageChannel Count")
public int getChannelCount() {
return this.managementConfigurer.getChannelNames().length;
return this.channels.size();
}
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "MessageHandler Count")
public int getHandlerCount() {
return this.managementConfigurer.getHandlerNames().length;
return this.handlers.size();
}
@ManagedMetric(metricType = MetricType.COUNTER, displayName = "MessageSource Count")
public int getSourceCount() {
return this.managementConfigurer.getSourceNames().length;
return this.sources.size();
}
@ManagedAttribute
public String[] getHandlerNames() {
return this.managementConfigurer.getHandlerNames();
return this.handlers.values().stream()
.map(hand -> hand.getManagedName())
.toArray(n -> new String[n]);
}
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Active Handler Count")
@Deprecated
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "No longer supported")
public int getActiveHandlerCount() {
return (int) getActiveHandlerCountLong();
return 0;
}
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Active Handler Count")
@Deprecated
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "No longer supported")
public long getActiveHandlerCountLong() {
int count = 0;
for (org.springframework.integration.support.management.MessageHandlerMetrics monitor : this.handlers) {
count += monitor.getActiveCountLong();
}
return count;
return 0;
}
@ManagedMetric(metricType = MetricType.GAUGE, displayName = "Queued Message Count")
public int getQueuedMessageCount() {
return this.channels.stream()
return this.channels.values().stream()
.filter(QueueChannel.class::isInstance)
.map(QueueChannel.class::cast)
.mapToInt(QueueChannel::getQueueSize)
@@ -674,93 +640,51 @@ public class IntegrationMBeanExporter extends MBeanExporter
@ManagedAttribute
public String[] getChannelNames() {
return this.managementConfigurer.getChannelNames();
return this.channels.keySet().stream()
.toArray(n -> new String[n]);
}
public org.springframework.integration.support.management.MessageHandlerMetrics getHandlerMetrics(String name) {
return this.managementConfigurer.getHandlerMetrics(name);
@Nullable
@Deprecated
public AbstractMessageHandler getHandlerMetrics(String name) {
return null;
}
public org.springframework.integration.support.management.Statistics getHandlerDuration(String name) {
org.springframework.integration.support.management.MessageHandlerMetrics handlerMetrics = getHandlerMetrics(name);
return handlerMetrics != null ? handlerMetrics.getDuration() : null;
@Nullable
public IntegrationManagement getHandler(String name) {
return this.handlers.get(name);
}
@ManagedAttribute
public String[] getSourceNames() {
return this.managementConfigurer.getSourceNames();
return this.sources.keySet().stream()
.toArray(n -> new String[n]);
}
public org.springframework.integration.support.management.MessageSourceMetrics getSourceMetrics(String name) {
return this.managementConfigurer.getSourceMetrics(name);
@Deprecated
public IntegrationInboundManagement getSourceMetrics(String name) {
return this.sources.get(name);
}
public int getSourceMessageCount(String name) {
return (int) getSourceMessageCountLong(name);
@Deprecated
public IntegrationManagement getChannelMetrics(String name) {
return this.channels.get(name);
}
public long getSourceMessageCountLong(String name) {
org.springframework.integration.support.management.MessageSourceMetrics sourceMetrics = getSourceMetrics(name);
return sourceMetrics != null ? sourceMetrics.getMessageCountLong() : -1;
public IntegrationInboundManagement getSource(String name) {
return this.sources.get(name);
}
public org.springframework.integration.support.management.MessageChannelMetrics getChannelMetrics(String name) {
return this.managementConfigurer.getChannelMetrics(name);
}
public int getChannelSendCount(String name) {
return (int) getChannelSendCountLong(name);
}
public long getChannelSendCountLong(String name) {
org.springframework.integration.support.management.MessageChannelMetrics channelMetrics =
getChannelMetrics(name);
return channelMetrics != null ? channelMetrics.getSendCountLong() : -1;
}
public int getChannelSendErrorCount(String name) {
return (int) getChannelSendErrorCountLong(name);
}
public long getChannelSendErrorCountLong(String name) {
org.springframework.integration.support.management.MessageChannelMetrics channelMetrics = getChannelMetrics(name);
return channelMetrics != null ? channelMetrics.getSendErrorCountLong() : -1;
}
public int getChannelReceiveCount(String name) {
return (int) getChannelReceiveCountLong(name);
}
public long getChannelReceiveCountLong(String name) {
org.springframework.integration.support.management.MessageChannelMetrics channelMetrics =
getChannelMetrics(name);
if (channelMetrics instanceof org.springframework.integration.support.management.PollableChannelManagement) {
return ((org.springframework.integration.support.management.PollableChannelManagement) channelMetrics)
.getReceiveCountLong();
}
return -1;
}
@ManagedOperation
public org.springframework.integration.support.management.Statistics getChannelSendRate(String name) {
org.springframework.integration.support.management.MessageChannelMetrics channelMetrics =
getChannelMetrics(name);
return channelMetrics != null ? channelMetrics.getSendRate() : null;
}
public org.springframework.integration.support.management.Statistics getChannelErrorRate(String name) {
org.springframework.integration.support.management.MessageChannelMetrics channelMetrics =
getChannelMetrics(name);
return channelMetrics != null ? channelMetrics.getErrorRate() : null;
public IntegrationManagement getChannel(String name) {
return this.channels.get(name);
}
private void registerChannels() {
this.channels.forEach(this::registerChannel);
this.channels.values().forEach(this::registerChannel);
}
private void registerChannel(org.springframework.integration.support.management.MessageChannelMetrics monitor) {
String name = ((NamedComponent) monitor).getComponentName();
this.allChannelsByName.put(name, monitor);
private void registerChannel(IntegrationManagement monitor) {
String name = monitor.getComponentName();
if (matches(this.componentNamePatterns, name)) {
String beanKey = getChannelBeanKey(name);
if (logger.isInfoEnabled()) {
@@ -772,31 +696,30 @@ public class IntegrationMBeanExporter extends MBeanExporter
}
private void registerHandlers() {
this.handlers.forEach(this::registerHandler);
this.handlers.values().forEach(this::registerHandler);
}
private void registerHandler(org.springframework.integration.support.management.MessageHandlerMetrics handler) {
org.springframework.integration.support.management.MessageHandlerMetrics monitor = enhanceHandlerMonitor(handler);
String name = monitor.getManagedName();
if (!this.objectNames.containsKey(handler) && matches(this.componentNamePatterns, name)) {
private void registerHandler(IntegrationManagement monitor2) {
IntegrationManagement monitor = enhanceHandlerMonitor(monitor2);
String name = monitor.getComponentName();
if (!this.objectNames.containsKey(monitor2) && matches(this.componentNamePatterns, name)) {
String beanKey = getHandlerBeanKey(monitor);
if (logger.isInfoEnabled()) {
logger.info("Registering MessageHandler " + name);
}
ObjectName objectName = registerBeanNameOrInstance(monitor, beanKey);
this.objectNames.put(handler, objectName);
this.objectNames.put(monitor2, objectName);
}
}
private void registerSources() {
this.sources.forEach(this::registerSource);
this.sources.values().forEach(this::registerSource);
}
private void registerSource(org.springframework.integration.support.management.MessageSourceMetrics source) {
org.springframework.integration.support.management.MessageSourceMetrics monitor = enhanceSourceMonitor(source);
private void registerSource(IntegrationInboundManagement source) {
IntegrationInboundManagement monitor = enhanceSourceMonitor(source);
String name = monitor.getManagedName();
this.allSourcesByName.put(name, monitor);
if (!this.objectNames.containsKey(source) && matches(this.componentNamePatterns, name)) {
String beanKey = getSourceBeanKey(monitor);
if (logger.isInfoEnabled()) {
@@ -804,6 +727,14 @@ public class IntegrationMBeanExporter extends MBeanExporter
}
ObjectName objectName = registerBeanNameOrInstance(monitor, beanKey);
this.objectNames.put(source, objectName);
Lifecycle lifecycle = this.sourceLifecycles.get(source);
if (lifecycle != null) {
beanKey = getEndpointBeanKey(source.getManagedName() + ".adapter", source.getManagedType());
if (logger.isInfoEnabled()) {
logger.info("Registering Endpoint " + beanKey);
}
this.objectNames.put(lifecycle, registerBeanNameOrInstance(lifecycle, beanKey));
}
}
}
@@ -839,7 +770,7 @@ public class IntegrationMBeanExporter extends MBeanExporter
}
this.endpointNames.add(name);
beanKey = getEndpointBeanKey(name, source);
ObjectName objectName = registerBeanInstance(new ManagedEndpoint(endpoint), beanKey);
ObjectName objectName = registerBeanInstance(endpoint, beanKey);
this.objectNames.put(endpoint, objectName);
if (logger.isInfoEnabled()) {
logger.info("Registered endpoint without MessageSource: " + objectName);
@@ -882,16 +813,16 @@ public class IntegrationMBeanExporter extends MBeanExporter
quoteIfNecessary(channel), extra);
}
private String getHandlerBeanKey(org.springframework.integration.support.management.MessageHandlerMetrics handler) {
private String getHandlerBeanKey(IntegrationManagement monitor) {
// This ordering of keys seems to work with default settings of JConsole
return String.format(this.domain + ":type=MessageHandler,name=%s,bean=%s" + getStaticNames(),
quoteIfNecessary(handler.getManagedName()), quoteIfNecessary(handler.getManagedType()));
quoteIfNecessary(monitor.getManagedName()), quoteIfNecessary(monitor.getManagedType()));
}
private String getSourceBeanKey(org.springframework.integration.support.management.MessageSourceMetrics source) {
private String getSourceBeanKey(IntegrationInboundManagement monitor) {
// This ordering of keys seems to work with default settings of JConsole
return String.format(this.domain + ":type=MessageSource,name=%s,bean=%s" + getStaticNames(),
quoteIfNecessary(source.getManagedName()), quoteIfNecessary(source.getManagedType()));
quoteIfNecessary(monitor.getManagedName()), quoteIfNecessary(monitor.getManagedType()));
}
private String getEndpointBeanKey(String name, String source) {
@@ -925,11 +856,10 @@ public class IntegrationMBeanExporter extends MBeanExporter
}
@SuppressWarnings("unlikely-arg-type")
private org.springframework.integration.support.management.MessageHandlerMetrics enhanceHandlerMonitor(
org.springframework.integration.support.management.MessageHandlerMetrics monitor) {
private IntegrationManagement enhanceHandlerMonitor(IntegrationManagement monitor2) {
if (monitor.getManagedName() != null && monitor.getManagedType() != null) {
return monitor;
if (monitor2.getManagedName() != null && monitor2.getManagedType() != null) {
return monitor2;
}
// Assignment algorithm and bean id, with bean id pulled reflectively out of enclosing endpoint if possible
@@ -944,32 +874,32 @@ public class IntegrationMBeanExporter extends MBeanExporter
endpoint = this.applicationContext.getBean(beanName, IntegrationConsumer.class);
try {
MessageHandler handler = endpoint.getHandler();
if (handler.equals(monitor) ||
extractTarget(handlerInAnonymousWrapper(handler)).equals(monitor)) {
if (handler.equals(monitor2) ||
extractTarget(handlerInAnonymousWrapper(handler)).equals(monitor2)) {
name = beanName;
endpointName = beanName;
break;
}
}
catch (Exception e) {
logger.trace("Could not get handler from bean = " + beanName);
logger.trace("Could not get handler from bean = " + beanName, e);
endpoint = null;
}
}
org.springframework.integration.support.management.MessageHandlerMetrics messageHandlerMetrics =
buildMessageHandlerMetrics(monitor, name, source, endpoint);
IntegrationManagement messageHandlerMetrics =
buildMessageHandlerMetrics(monitor2, name, source, endpoint);
if (endpointName != null) {
this.endpointsByMonitor.put(messageHandlerMetrics, endpointName);
}
return messageHandlerMetrics;
}
private org.springframework.integration.support.management.MessageHandlerMetrics buildMessageHandlerMetrics(
org.springframework.integration.support.management.MessageHandlerMetrics monitor,
private IntegrationManagement buildMessageHandlerMetrics(
IntegrationManagement monitor2,
String name, String source, IntegrationConsumer endpoint) {
org.springframework.integration.support.management.MessageHandlerMetrics result = monitor;
IntegrationManagement result = monitor2;
String managedType = source;
String managedName = name;
@@ -985,16 +915,10 @@ public class IntegrationMBeanExporter extends MBeanExporter
}
}
if (endpoint instanceof Lifecycle) {
result = wrapMessageHandlerInLifecycleMetrics(monitor, (Lifecycle) endpoint);
}
if (managedName == null) {
if (monitor instanceof NamedComponent) {
managedName = ((NamedComponent) monitor).getComponentName();
}
managedName = ((NamedComponent) monitor2).getComponentName();
if (managedName == null) {
managedName = monitor.toString();
managedName = monitor2.toString();
}
managedType = "handler";
}
@@ -1020,52 +944,20 @@ public class IntegrationMBeanExporter extends MBeanExporter
return channelName + (total > 1 ? "#" + total : "");
}
/**
* Wrap the monitor in a lifecycle so it exposes the start/stop operations
*/
private org.springframework.integration.support.management.MessageHandlerMetrics
wrapMessageHandlerInLifecycleMetrics(
org.springframework.integration.support.management.MessageHandlerMetrics monitor,
Lifecycle endpoint) {
org.springframework.integration.support.management.MessageHandlerMetrics result;
if (monitor instanceof MappingMessageRouterManagement) {
if (monitor instanceof TrackableComponent) {
result = new org.springframework.integration.support.management.TrackableRouterMetrics(endpoint,
(MappingMessageRouterManagement) monitor);
}
else {
result = new org.springframework.integration.support.management.RouterMetrics(endpoint,
(MappingMessageRouterManagement) monitor);
}
}
else {
if (monitor instanceof TrackableComponent) {
result = new org.springframework.integration.support.management.
LifecycleTrackableMessageHandlerMetrics(endpoint, monitor);
}
else {
result = new org.springframework.integration.support.management.
LifecycleMessageHandlerMetrics(endpoint, monitor);
}
}
return result;
}
private String getInternalComponentName(String name) {
return name.substring(('_' + IntegrationConfigUtils.BASE_PACKAGE).length() + 1);
}
private org.springframework.integration.support.management.MessageSourceMetrics enhanceSourceMonitor(
org.springframework.integration.support.management.MessageSourceMetrics monitor) {
private IntegrationInboundManagement enhanceSourceMonitor(IntegrationInboundManagement source2) {
if (monitor.getManagedName() != null) {
return monitor;
if (source2.getManagedName() != null) {
return source2;
}
String endpointName = null;
String source = "endpoint";
AbstractEndpoint endpoint = getEndpointForMonitor(monitor);
AbstractEndpoint endpoint = getEndpointForMonitor(source2);
this.sourceLifecycles.put(source2, endpoint);
if (endpoint != null) {
endpointName = endpoint.getBeanName();
@@ -1075,8 +967,8 @@ public class IntegrationMBeanExporter extends MBeanExporter
source = "internal";
}
org.springframework.integration.support.management.MessageSourceMetrics messageSourceMetrics =
buildMessageSourceMetricsIfAny(monitor, endpointName, source, endpoint);
IntegrationInboundManagement messageSourceMetrics =
buildMessageSourceMetricsIfAny(source2, endpointName, source, endpoint);
if (endpointName != null) {
this.endpointsByMonitor.put(messageSourceMetrics, endpointName);
}
@@ -1084,29 +976,28 @@ public class IntegrationMBeanExporter extends MBeanExporter
}
@SuppressWarnings("unlikely-arg-type")
private AbstractEndpoint getEndpointForMonitor(
org.springframework.integration.support.management.MessageSourceMetrics monitor) {
private AbstractEndpoint getEndpointForMonitor(IntegrationInboundManagement source2) {
for (AbstractEndpoint endpoint : this.applicationContext.getBeansOfType(AbstractEndpoint.class).values()) {
Object target = null;
if (monitor instanceof MessagingGatewaySupport && endpoint.equals(monitor)) {
target = monitor;
if (source2 instanceof MessagingGatewaySupport && endpoint.equals(source2)) {
target = source2;
}
else if (endpoint instanceof SourcePollingChannelAdapter) {
target = ((SourcePollingChannelAdapter) endpoint).getMessageSource();
}
if (monitor.equals(target)) {
if (source2.equals(target)) {
return endpoint;
}
}
return null;
}
private org.springframework.integration.support.management.MessageSourceMetrics buildMessageSourceMetricsIfAny(
org.springframework.integration.support.management.MessageSourceMetrics monitor, String name,
private IntegrationInboundManagement buildMessageSourceMetricsIfAny(
IntegrationInboundManagement source2, String name,
String source, Object endpoint) {
org.springframework.integration.support.management.MessageSourceMetrics result = monitor;
IntegrationInboundManagement result = source2;
String managedType = source;
String managedName = name;
@@ -1136,10 +1027,6 @@ public class IntegrationMBeanExporter extends MBeanExporter
}
}
if (endpoint instanceof Lifecycle) {
result = wrapMessageSourceInLifecycleMetrics(result, endpoint);
}
if (managedName == null) {
managedName = result.toString();
managedType = "source";
@@ -1150,36 +1037,4 @@ public class IntegrationMBeanExporter extends MBeanExporter
return result;
}
/**
* Wrap the monitor in a lifecycle so it exposes the start/stop operations
*/
private org.springframework.integration.support.management.MessageSourceMetrics wrapMessageSourceInLifecycleMetrics(
org.springframework.integration.support.management.MessageSourceMetrics monitor, Object endpoint) {
org.springframework.integration.support.management.MessageSourceMetrics result;
if (endpoint instanceof TrackableComponent) {
if (monitor instanceof MessageSourceManagement) {
result = new org.springframework.integration.support.management.
LifecycleTrackableMessageSourceManagement((Lifecycle) endpoint,
(MessageSourceManagement) monitor);
}
else {
result = new org.springframework.integration.support.management.
LifecycleTrackableMessageSourceMetrics((Lifecycle) endpoint, monitor);
}
}
else {
if (monitor instanceof MessageSourceManagement) {
result = new org.springframework.integration.support.management.
LifecycleMessageSourceManagement((Lifecycle) endpoint,
(MessageSourceManagement) monitor);
}
else {
result = new org.springframework.integration.support.management.LifecycleMessageSourceMetrics(
(Lifecycle) endpoint, monitor);
}
}
return result;
}
}

View File

@@ -1,68 +0,0 @@
/*
* Copyright 2016-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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.monitor;
import javax.management.Descriptor;
import org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler;
import org.springframework.jmx.export.metadata.JmxAttributeSource;
/**
* The {@link MetadataMBeanInfoAssembler} extension to assemble metadata MBean info from
* the
* {@link org.springframework.integration.support.management.LifecycleMessageSourceMetrics}
* or
* {@link org.springframework.integration.support.management.LifecycleMessageHandlerMetrics}
* managed bean's delegate.
* <p>
* All other managed beans are left as is.
*
* @author Gary Russell
* @author Artem Bilan
*
* @since 4.3
*/
public class IntegrationMetadataMBeanInfoAssembler extends MetadataMBeanInfoAssembler {
public IntegrationMetadataMBeanInfoAssembler(JmxAttributeSource attributeSource) {
super(attributeSource);
}
@Override
protected String getDescription(Object managedBean, String beanKey) {
return super.getDescription(extractManagedBean(managedBean), beanKey);
}
@Override
protected void populateMBeanDescriptor(Descriptor desc, Object managedBean, String beanKey) {
super.populateMBeanDescriptor(desc, extractManagedBean(managedBean), beanKey);
}
@SuppressWarnings("deprecation")
private Object extractManagedBean(Object managedBean) {
if (managedBean instanceof org.springframework.integration.support.management.LifecycleMessageSourceMetrics) {
return ((org.springframework.integration.support.management.LifecycleMessageSourceMetrics) managedBean)
.getDelegate();
}
else if (managedBean instanceof org.springframework.integration.support.management.LifecycleMessageHandlerMetrics) {
return ((org.springframework.integration.support.management.LifecycleMessageHandlerMetrics) managedBean)
.getDelegate();
}
return managedBean;
}
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright 2016-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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.monitor;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import org.springframework.jmx.export.metadata.JmxAttributeSource;
import org.springframework.jmx.export.naming.MetadataNamingStrategy;
/**
* The {@link MetadataNamingStrategy} naming extension to extract an {@link ObjectName}
* from the
* {@link org.springframework.integration.support.management.LifecycleMessageSourceMetrics}
* or
* {@link org.springframework.integration.support.management.LifecycleMessageHandlerMetrics}
* managed bean's delegate.
* <p>
* Otherwise delegate to the {@link MetadataNamingStrategy#getObjectName} as is.
*
* @author Gary Russell
* @author Artem Bilan
*
* @since 4.3
*/
public class IntegrationMetadataNamingStrategy extends MetadataNamingStrategy {
public IntegrationMetadataNamingStrategy(JmxAttributeSource attributeSource) {
super(attributeSource);
}
@Override
public ObjectName getObjectName(Object managedBean, String beanKey) throws MalformedObjectNameException {
return super.getObjectName(extractManagedBean(managedBean), beanKey);
}
@SuppressWarnings("deprecation")
private Object extractManagedBean(Object managedBean) {
if (managedBean instanceof org.springframework.integration.support.management.LifecycleMessageSourceMetrics) {
return ((org.springframework.integration.support.management.LifecycleMessageSourceMetrics) managedBean)
.getDelegate();
}
else if (managedBean instanceof org.springframework.integration.support.management.LifecycleMessageHandlerMetrics) {
return ((org.springframework.integration.support.management.LifecycleMessageHandlerMetrics) managedBean)
.getDelegate();
}
return managedBean;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package org.springframework.integration.monitor;
import org.springframework.context.Lifecycle;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.support.management.IntegrationManagedResource;
import org.springframework.integration.support.management.ManageableLifecycle;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
@@ -28,7 +29,11 @@ import org.springframework.jmx.export.annotation.ManagedOperation;
* @author Dave Syer
* @author Gary Russell
*
* @deprecated this is no longer used by the framework. Replaced by
* {@link ManageableLifecycle}.
*
*/
@Deprecated
@IntegrationManagedResource
public class ManagedEndpoint implements Lifecycle {

View File

@@ -29,8 +29,8 @@
<bean class="org.springframework.integration.jmx.NamedFieldsMBeanAttributeFilter">
<constructor-arg>
<array>
<value type="java.lang.String">SendCount</value>
<value type="java.lang.String">SendErrorCount</value>
<value type="java.lang.String">QueueSize</value>
<value type="java.lang.String">RemainingCapacity</value>
</array>
</constructor-arg>
</bean>
@@ -47,7 +47,7 @@
</int:service-activator>
<int:channel id="out">
<int:queue/>
<int:queue capacity="10" />
</int:channel>
<int-jmx:tree-polling-channel-adapter id="adapterNot"

View File

@@ -76,11 +76,11 @@ public class MBeanAttributeFilterTests {
@SuppressWarnings("unchecked")
Map<String, Object> bean = (Map<String, Object>) payload
.get(domain + ":name=in,type=MessageChannel");
.get(this.domain + ":name=out,type=MessageChannel");
assertThat(bean.size()).isEqualTo(2);
assertThat(bean.containsKey("SendCount")).isTrue();
assertThat(bean.containsKey("SendErrorCount")).isTrue();
assertThat(bean.containsKey("QueueSize")).isTrue();
assertThat(bean.containsKey("RemainingCapacity")).isTrue();
adapter.stop();
}
@@ -106,10 +106,7 @@ public class MBeanAttributeFilterTests {
List<String> keys = new ArrayList<>(bean.keySet());
Collections.sort(keys);
assertThat(keys)
.containsExactly("LoggingEnabled", "MaxSendDuration", "MeanErrorRate", "MeanErrorRatio",
"MeanSendDuration", "MeanSendRate", "MinSendDuration", "StandardDeviationSendDuration",
"SubscriberCount", "TimeSinceLastSend");
assertThat(keys).containsExactly("LoggingEnabled", "SubscriberCount");
adapterNot.stop();
}

View File

@@ -16,7 +16,7 @@
<si:channel id="controlChannel"/>
<si:control-bus input-channel="controlChannel"/>
<si:control-bus id = "cb" input-channel="controlChannel"/>
<jmx:mbean-export id="integrationMbeanExporter" server="mbs" default-domain="tests.ControlBusParser"/>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author 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,9 +46,8 @@ public class ControlBusParserTests {
public void testControlMessageToChannelMetrics() {
MessageChannel control = this.context.getBean("controlChannel", MessageChannel.class);
MessagingTemplate messagingTemplate = new MessagingTemplate();
Object value = messagingTemplate.convertSendAndReceive(control,
"@integrationMbeanExporter.getChannelSendRate('testChannel').count", Object.class);
assertThat(value).isEqualTo(0);
Object value = messagingTemplate.convertSendAndReceive(control, "@cb.isRunning()", Object.class);
assertThat(value).isEqualTo(Boolean.TRUE);
}
}

View File

@@ -20,12 +20,7 @@
object-naming-strategy="keyNamer"
managed-components="\!excluded, f*, b*, q*, t*" />
<si:management
default-logging-enabled="false"
default-counts-enabled="false"
default-stats-enabled="false"
counts-enabled-patterns="foo, !baz, ba*"
stats-enabled-patterns="fiz, buz" />
<si:management default-logging-enabled="false"/>
<util:properties id="appProperties">
<prop key="foo">foo</prop>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -69,10 +69,6 @@ public class EnableMBeanExportTests {
@Autowired
private IntegrationManagementConfigurer configurer;
@SuppressWarnings("deprecation")
@Autowired
private org.springframework.integration.support.management.MetricsFactory myMetricsFactory;
@SuppressWarnings("unchecked")
@Test
public void testEnableMBeanExport() throws MalformedObjectNameException, ClassNotFoundException {
@@ -80,14 +76,7 @@ public class EnableMBeanExportTests {
assertThat(this.exporter.getServer()).isSameAs(this.mBeanServer);
String[] componentNamePatterns = TestUtils.getPropertyValue(this.exporter, "componentNamePatterns", String[].class);
assertThat(componentNamePatterns).containsExactly("input", "inputX", "in*");
String[] enabledCounts = TestUtils.getPropertyValue(this.configurer, "enabledCountsPatterns", String[].class);
assertThat(enabledCounts).containsExactly("foo", "bar", "baz");
String[] enabledStats = TestUtils.getPropertyValue(this.configurer, "enabledStatsPatterns", String[].class);
assertThat(enabledStats).containsExactly("qux", "!*");
assertThat(TestUtils.getPropertyValue(this.configurer, "defaultLoggingEnabled", Boolean.class)).isFalse();
assertThat(TestUtils.getPropertyValue(this.configurer, "defaultCountsEnabled", Boolean.class)).isTrue();
assertThat(TestUtils.getPropertyValue(this.configurer, "defaultStatsEnabled", Boolean.class)).isTrue();
assertThat(TestUtils.getPropertyValue(this.configurer, "metricsFactory")).isSameAs(this.myMetricsFactory);
Set<ObjectName> names = this.mBeanServer.queryNames(ObjectName.getInstance("FOO:type=MessageChannel,*"), null);
// Only one registered (out of >2 available)
@@ -118,12 +107,7 @@ public class EnableMBeanExportTests {
defaultDomain = "${managed.domain}",
managedComponents = {"input", "${managed.component}"})
@EnableIntegrationManagement(
defaultLoggingEnabled = "false",
defaultCountsEnabled = "true",
defaultStatsEnabled = "true",
countsEnabled = { "foo", "${count.patterns}" },
statsEnabled = { "qux", "!*" },
metricsFactory = "myMetricsFactory")
defaultLoggingEnabled = "false")
public static class ContextConfiguration {
@Bean
@@ -141,12 +125,6 @@ public class EnableMBeanExportTests {
return new QueueChannel();
}
@SuppressWarnings("deprecation")
@Bean
public org.springframework.integration.support.management.MetricsFactory myMetricsFactory() {
return new org.springframework.integration.support.management.DefaultMetricsFactory();
}
}
public static class EnvironmentApplicationContextInitializer

View File

@@ -1,102 +0,0 @@
/*
* Copyright 2009-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.monitor;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.support.context.NamedComponent;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageDeliveryException;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Dave Syer
* @author Gary Russell
* @author Artem Bilan
*
* @since 2.0
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
public class ChannelIntegrationTests {
@Autowired
private MessageChannel requests;
@Autowired
private PollableChannel intermediate;
@Autowired
private PollableChannel sourceChannel;
@Autowired
private IntegrationMBeanExporter messageChannelsMonitor;
@Test
public void testMessageChannelStatistics() {
this.requests.send(new GenericMessage<>("foo"));
String intermediateChannelName = ((NamedComponent) this.intermediate).getBeanName();
assertThat(messageChannelsMonitor.getChannelSendCount(intermediateChannelName)).isEqualTo(1);
double rate =
messageChannelsMonitor.getChannelSendRate(((NamedComponent) this.requests).getBeanName()).getMean();
assertThat(rate).as("No statistics for requests channel").isGreaterThanOrEqualTo(0);
rate = messageChannelsMonitor.getChannelSendRate(intermediateChannelName).getMean();
assertThat(rate).as("No statistics for intermediate channel").isGreaterThanOrEqualTo(0);
assertThat(intermediate.receive(100L)).isNotNull();
assertThat(messageChannelsMonitor.getChannelReceiveCount(intermediateChannelName)).isEqualTo(1);
requests.send(new GenericMessage<>("foo"));
try {
requests.send(new GenericMessage<>("foo"));
}
catch (@SuppressWarnings("unused") MessageDeliveryException e) {
}
assertThat(messageChannelsMonitor.getChannelSendCount(intermediateChannelName)).isEqualTo(3);
assertThat(messageChannelsMonitor.getChannelSendErrorCount(intermediateChannelName)).isEqualTo(1);
assertThat(messageChannelsMonitor.getChannelMetrics(intermediateChannelName)).isSameAs(intermediate);
@SuppressWarnings("deprecation")
org.springframework.integration.support.management.BaseHandlerMetrics handlerMetrics = messageChannelsMonitor
.getHandlerMetrics("bridge");
assertThat(handlerMetrics.handleCount()).isEqualTo(3);
assertThat(handlerMetrics.errorCount()).isEqualTo(1);
assertThat(this.sourceChannel.receive(10000)).isNotNull();
assertThat(messageChannelsMonitor.getSourceMessageCount("source")).isGreaterThan(0);
assertThat(messageChannelsMonitor.getSourceMetrics("source").getMessageCount()).isGreaterThan(0);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2009-2019 the original author or authors.
* Copyright 2009-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -88,10 +88,6 @@ public class HandlerMonitoringIntegrationTests {
int before = service.getCounter();
channel.send(new GenericMessage<>("bar"));
assertThat(service.getCounter()).isEqualTo(before + 1);
int count = messageHandlersMonitor.getHandlerDuration(monitor).getCount();
assertThat(count > 0).as("No statistics for input channel").isTrue();
}
finally {
context.close();
@@ -118,11 +114,13 @@ public class HandlerMonitoringIntegrationTests {
private int counter;
@Override
public void execute(String input) throws Exception {
Thread.sleep(10L); // make the duration non-zero
this.counter++;
}
@Override
public int getCounter() {
return counter;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2009-2019 the original author or authors.
* Copyright 2009-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -122,8 +122,8 @@ public class MBeanExporterIntegrationTests {
Set<ObjectName> names =
server.queryNames(
ObjectName.getInstance("org.springframework.integration:type=ManagedEndpoint,*"), null);
assertThat(names.size()).isEqualTo(2);
names = server.queryNames(ObjectName.getInstance("org.springframework.integration:name=explicit,*"), null);
assertThat(names.size()).isEqualTo(3);
names = server.queryNames(ObjectName.getInstance("org.springframework.integration:name=explicit.adapter,*"), null);
assertThat(names.size()).isEqualTo(1);
MBeanOperationInfo[] operations = server.getMBeanInfo(names.iterator().next()).getOperations();
String startName = null;

View File

@@ -1,228 +0,0 @@
/*
* Copyright 2009-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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.monitor;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.junit.Test;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.channel.AbstractMessageChannel;
import org.springframework.integration.channel.interceptor.WireTap;
import org.springframework.integration.support.context.NamedComponent;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.messaging.support.InterceptableChannel;
/**
* @author Dave Syer
* @author Gary Russell
* @author Artem Bilan
*
*/
public class MessageChannelsMonitorIntegrationTests {
private static Log logger = LogFactory.getLog(MessageChannelsMonitorIntegrationTests.class);
private AbstractMessageChannel channel;
private Service service;
private IntegrationMBeanExporter messageChannelsMonitor;
public void setMessageHandlersMonitor(IntegrationMBeanExporter messageChannelsMonitor) {
this.messageChannelsMonitor = messageChannelsMonitor;
}
public void setService(Service service) {
this.service = service;
}
@Test
public void testSendWithAnonymousHandler() throws Exception {
doTest("anonymous-channel.xml", "anonymous");
}
@Test
public void testSendWithProxiedChannel() throws Exception {
doTest("proxy-channel.xml", "anonymous");
}
@Test
public void testRates() throws Exception {
try (ClassPathXmlApplicationContext context = createContext("anonymous-channel.xml")) {
this.channel = context.getBean("anonymous", AbstractMessageChannel.class);
int before = service.getCounter();
CountDownLatch latch = new CountDownLatch(50);
service.setLatch(latch);
for (int i = 0; i < 50; i++) {
channel.send(new GenericMessage<>("bar"));
Thread.sleep(20L);
}
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(service.getCounter()).isEqualTo(before + 50);
// The handler monitor is registered under the endpoint id (since it is explicit)
int sends = messageChannelsMonitor.getChannelSendRate(this.channel.getBeanName()).getCount();
assertThat(sends).as("No send statistics for input channel").isEqualTo(50);
long sendsLong = messageChannelsMonitor.getChannelSendRate(this.channel.getBeanName()).getCountLong();
assertThat(sends).as("No send statistics for input channel").isEqualTo(sendsLong);
}
}
@Test
public void testErrors() throws Exception {
try (ClassPathXmlApplicationContext context = createContext("anonymous-channel.xml")) {
this.channel = context.getBean("anonymous", AbstractMessageChannel.class);
int before = service.getCounter();
CountDownLatch latch = new CountDownLatch(10);
service.setLatch(latch);
for (int i = 0; i < 5; i++) {
channel.send(new GenericMessage<>("bar"));
Thread.sleep(20L);
}
try {
channel.send(new GenericMessage<>("fail"));
}
catch (MessageHandlingException e) {
// ignore
}
for (int i = 0; i < 5; i++) {
channel.send(new GenericMessage<>("bar"));
Thread.sleep(20L);
}
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(service.getCounter()).isEqualTo(before + 10);
// The handler monitor is registered under the endpoint id (since it is explicit)
int sends = messageChannelsMonitor.getChannelSendRate(this.channel.getBeanName()).getCount();
assertThat(sends).as("No send statistics for input channel").isEqualTo(11);
int errors = messageChannelsMonitor.getChannelErrorRate(this.channel.getBeanName()).getCount();
assertThat(errors).as("No error statistics for input channel").isEqualTo(1);
}
}
@Test
public void testQueues() throws Exception {
try (ClassPathXmlApplicationContext context = createContext("queue-channel.xml")) {
this.channel = context.getBean("queue", AbstractMessageChannel.class);
int before = service.getCounter();
CountDownLatch latch = new CountDownLatch(10);
service.setLatch(latch);
for (int i = 0; i < 5; i++) {
channel.send(new GenericMessage<>("bar"));
Thread.sleep(20L);
}
try {
channel.send(new GenericMessage<>("fail"));
}
catch (MessageHandlingException e) {
// ignore
}
for (int i = 0; i < 5; i++) {
channel.send(new GenericMessage<>("bar"));
Thread.sleep(20L);
}
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(service.getCounter()).isEqualTo(before + 10);
// The handler monitor is registered under the endpoint id (since it is explicit)
int sends = messageChannelsMonitor.getChannelSendRate(this.channel.getBeanName()).getCount();
assertThat(sends).as("No send statistics for input channel").isEqualTo(11);
int receives = messageChannelsMonitor.getChannelReceiveCount(this.channel.getBeanName());
assertThat(receives).as("No send statistics for input channel").isEqualTo(11);
int errors = messageChannelsMonitor.getChannelErrorRate(this.channel.getBeanName()).getCount();
assertThat(errors).as("Expect no errors for input channel (handler fails)").isEqualTo(0);
}
}
private void doTest(String config, String channelName) throws Exception {
try (ClassPathXmlApplicationContext context = createContext(config)) {
MessageChannel channel = context.getBean(channelName, MessageChannel.class);
int before = service.getCounter();
CountDownLatch latch = new CountDownLatch(1);
service.setLatch(latch);
channel.send(new GenericMessage<>("bar"));
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(service.getCounter()).isEqualTo(before + 1);
// The handler monitor is registered under the endpoint id (since it is explicit)
int sends = messageChannelsMonitor.getChannelSendRate(((NamedComponent) channel).getBeanName()).getCount();
assertThat(sends).as("No statistics for input channel").isEqualTo(1);
assertThat(channel).isInstanceOf(InterceptableChannel.class);
List<ChannelInterceptor> channelInterceptors = ((InterceptableChannel) channel).getInterceptors();
assertThat(channelInterceptors.size()).isEqualTo(1);
assertThat(channelInterceptors.get(0)).isInstanceOf(WireTap.class);
}
}
private ClassPathXmlApplicationContext createContext(String config) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config, getClass());
context.getAutowireCapableBeanFactory()
.autowireBeanProperties(this, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
return context;
}
public static class Service {
private int counter;
private volatile CountDownLatch latch;
public void setLatch(CountDownLatch latch) {
this.latch = latch;
}
public void execute(String input) {
if ("fail".equals(input)) {
throw new RuntimeException("Planned");
}
counter++;
latch.countDown();
}
public int getCounter() {
return counter;
}
}
@Aspect
public static class TestChannelInterceptor {
@Before("execution(* *..MessageChannel+.send(*)) && args(input)")
public void around(Message<?> input) {
logger.debug("Handling: " + input);
}
}
}

View File

@@ -1,112 +0,0 @@
/*
* Copyright 2009-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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.monitor;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.messaging.PollableChannel;
/**
* @author Dave Syer
* @author Gary Russell
* @author Artem Bilan
*/
public class MessageSourceMonitoringIntegrationTests {
private PollableChannel channel;
private Service service;
private IntegrationMBeanExporter exporter;
public void setMessageHandlersMonitor(IntegrationMBeanExporter exporter) {
this.exporter = exporter;
}
public void setService(Service service) {
this.service = service;
}
@Test
public void testSendAndHandleWithEndpointName() throws Exception {
// The message source monitor is registered under the endpoint id (since it is explicit)
doTest("explicit-source.xml", "input", "explicit");
}
@Test
public void testSendAndHandleWithAnonymous() throws Exception {
// The message source monitor is registered under the channel name
doTest("anonymous-source.xml", "anonymous", "anonymous");
}
private void doTest(String config, String channelName, String monitor) throws Exception {
ClassPathXmlApplicationContext context = createContext(config, channelName);
try {
int before = service.getCounter();
channel.receive(1000L);
channel.receive(1000L);
assertThat(before < service.getCounter()).isTrue();
int count = exporter.getSourceMessageCount(monitor);
assertThat(count > 0).as("No statistics for input channel").isTrue();
}
finally {
context.close();
}
}
private ClassPathXmlApplicationContext createContext(String config, String channelName) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config, getClass());
context.getAutowireCapableBeanFactory()
.autowireBeanProperties(this, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
channel = context.getBean(channelName, PollableChannel.class);
return context;
}
public interface Service {
String execute() throws Exception;
int getCounter();
}
public static class SimpleService implements Service {
private int counter;
public String execute() throws Exception {
Thread.sleep(10L); // make the duration non-zero
counter++;
return "count=" + counter;
}
public int getCounter() {
return counter;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author 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,12 +47,12 @@ public class Int2307Tests {
int count = 0;
for (ObjectInstance mbean : mbeans) {
if (mbean.toString()
.startsWith("org.springframework.integration.support.management.LifecycleTrackableMessageHandlerMetrics[test.domain:type=MessageHandler,name=rlr,bean=endpoint,random=")) {
.startsWith("org.springframework.integration.router.RecipientListRouter[test.domain:type=MessageHandler,name=rlr,bean=endpoint,random=")) {
bits |= 2;
count++;
}
else if (mbean.toString()
.startsWith("org.springframework.integration.support.management.TrackableRouterMetrics[test.domain:type=MessageHandler,name=hvr,bean=endpoint,random=")) {
.startsWith("org.springframework.integration.router.HeaderValueRouter[test.domain:type=MessageHandler,name=hvr,bean=endpoint,random=")) {
bits |= 8;
count++;
}