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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user