Fix new Sonar smell and some other in JMX module (#2716)

* Fix new Sonar smell and some other in JMX module

* * Fix issues after testing
This commit is contained in:
Artem Bilan
2019-01-24 11:55:46 -05:00
committed by Gary Russell
parent bac3565dfd
commit 9ab6779dc2
7 changed files with 350 additions and 277 deletions

View File

@@ -79,18 +79,28 @@ public abstract class IntegrationComponentSpec<S extends IntegrationComponentSpe
}
@Override
protected T createInstance() throws Exception {
protected T createInstance() {
T instance = get();
if (instance instanceof InitializingBean) {
((InitializingBean) instance).afterPropertiesSet();
try {
((InitializingBean) instance).afterPropertiesSet();
}
catch (Exception e) {
throw new IllegalStateException("Cannot initialize bean: " + instance, e);
}
}
return instance;
}
@Override
protected void destroyInstance(T instance) throws Exception {
protected void destroyInstance(T instance) {
if (instance instanceof DisposableBean) {
((DisposableBean) instance).destroy();
try {
((DisposableBean) instance).destroy();
}
catch (Exception e) {
throw new IllegalStateException("Cannot destroy bean: " + instance, e);
}
}
}
@@ -145,7 +155,7 @@ public abstract class IntegrationComponentSpec<S extends IntegrationComponentSpe
}
@SuppressWarnings("unchecked")
protected final S _this() {
protected final S _this() { // NOSONAR
return (S) this;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,14 +35,18 @@ import javax.management.openmbean.TabularData;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
/**
* @author Stuart Williams
* @author Artem Bilan
*
* @since 3.0
*
*/
public class DefaultMBeanObjectConverter implements MBeanObjectConverter {
private static final Log log = LogFactory.getLog(DefaultMBeanObjectConverter.class);
private static final Log LOGGER = LogFactory.getLog(DefaultMBeanObjectConverter.class);
private final MBeanAttributeFilter filter;
@@ -51,12 +55,13 @@ public class DefaultMBeanObjectConverter implements MBeanObjectConverter {
}
public DefaultMBeanObjectConverter(MBeanAttributeFilter filter) {
Assert.notNull(filter, "'filter' must not be null.");
this.filter = filter;
}
@Override
public Object convert(MBeanServerConnection connection, ObjectInstance instance) {
Map<String, Object> attributeMap = new HashMap<String, Object>();
Map<String, Object> attributeMap = new HashMap<>();
try {
ObjectName objName = instance.getObjectName();
@@ -81,8 +86,8 @@ public class DefaultMBeanObjectConverter implements MBeanObjectConverter {
// N.B. standard MemoryUsage MBeans will throw an exception when some
// measurement is unsupported. Logging at trace rather than debug to
// avoid confusion.
if (log.isTraceEnabled()) {
log.trace("Error getting attribute '" + attrInfo.getName() + "' on '" + objName + "'", e);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Error getting attribute '" + attrInfo.getName() + "' on '" + objName + "'", e);
}
// try to unwrap the exception somewhat; not sure this is ideal
@@ -104,90 +109,95 @@ public class DefaultMBeanObjectConverter implements MBeanObjectConverter {
return attributeMap;
}
/**
* @param input
* @return recursively mapped object
*/
private Object checkAndConvert(Object input) {
if (input == null) {
return input;
}
else if (input.getClass().isArray()) {
if (CompositeData.class.isAssignableFrom(input.getClass().getComponentType())) {
List<Object> converted = new ArrayList<Object>();
int length = Array.getLength(input);
for (int i = 0; i < length; i++) {
Object value = checkAndConvert(Array.get(input, i));
converted.add(value);
}
return converted;
}
if (TabularData.class.isAssignableFrom(input.getClass().getComponentType())) {
// TODO haven't hit this yet, but expect to
log.warn("TabularData.isAssignableFrom(getComponentType) for " + input.toString());
}
}
else if (input instanceof CompositeData) {
CompositeData data = (CompositeData) input;
if (data.getCompositeType().isArray()) {
// TODO? I haven't found an example where this gets thrown - but need to test it on Tomcat/Jetty or
// something
log.warn("(data.getCompositeType().isArray for " + input.toString());
}
else {
Map<String, Object> returnable = new HashMap<String, Object>();
Set<String> keys = data.getCompositeType().keySet();
for (String key : keys) {
// we don't need to repeat name of this as an attribute
if ("ObjectName".equals(key)) {
continue;
}
Object value = checkAndConvert(data.get(key));
returnable.put(key, value);
}
return returnable;
}
Object converted = null;
if (input instanceof CompositeData) {
converted = convertFromCompositeData((CompositeData) input);
}
else if (input instanceof TabularData) {
TabularData data = (TabularData) input;
if (data.getTabularType().isArray()) {
// TODO? I haven't found an example where this gets thrown, so might not be required
log.warn("TabularData.isArray for " + input.toString());
}
else {
Map<Object, Object> returnable = new HashMap<Object, Object>();
@SuppressWarnings("unchecked")
Set<List<?>> keySet = (Set<List<?>>) data.keySet();
for (List<?> keys : keySet) {
CompositeData cd = data.get(keys.toArray());
Object value = checkAndConvert(cd);
if (keys.size() == 1 && (value instanceof Map) && ((Map<?, ?>) value).size() == 2) {
Object actualKey = keys.get(0);
Map<?, ?> valueMap = (Map<?, ?>) value;
if (valueMap.containsKey("key") && valueMap.containsKey("value")
&& actualKey.equals(valueMap.get("key"))) {
returnable.put(valueMap.get("key"), valueMap.get("value"));
}
else {
returnable.put(actualKey, value);
}
}
else {
returnable.put(keys, value);
}
}
return returnable;
}
converted = convertFromTabularData((TabularData) input);
}
else if (input != null && input.getClass().isArray()) {
converted = convertFromArray(input);
}
return input;
if (converted != null) {
return converted;
}
else {
return input;
}
}
private Object convertFromArray(Object input) {
if (CompositeData.class.isAssignableFrom(input.getClass().getComponentType())) {
List<Object> converted = new ArrayList<>();
int length = Array.getLength(input);
for (int i = 0; i < length; i++) {
Object value = checkAndConvert(Array.get(input, i));
converted.add(value);
}
return converted;
}
if (TabularData.class.isAssignableFrom(input.getClass().getComponentType())) {
// TODO haven't hit this yet, but expect to
LOGGER.warn("TabularData.isAssignableFrom(getComponentType) for " + input.toString());
}
return null;
}
private Object convertFromCompositeData(CompositeData data) {
if (data.getCompositeType().isArray()) {
// TODO? I haven't found an example where this gets thrown - but need to test it on Tomcat/Jetty or
// something
LOGGER.warn("(data.getCompositeType().isArray for " + data.toString());
return null;
}
else {
Map<String, Object> returnable = new HashMap<>();
Set<String> keys = data.getCompositeType().keySet();
for (String key : keys) {
// we don't need to repeat name of this as an attribute
if ("ObjectName".equals(key)) {
continue;
}
Object value = checkAndConvert(data.get(key));
returnable.put(key, value);
}
return returnable;
}
}
private Object convertFromTabularData(TabularData data) {
if (data.getTabularType().isArray()) {
// TODO? I haven't found an example where this gets thrown, so might not be required
LOGGER.warn("TabularData.isArray for " + data.toString());
return null;
}
else {
Map<Object, Object> returnable = new HashMap<>();
@SuppressWarnings("unchecked")
Set<List<?>> keySet = (Set<List<?>>) data.keySet();
for (List<?> keys : keySet) {
CompositeData cd = data.get(keys.toArray());
Object value = checkAndConvert(cd);
if (keys.size() == 1 && (value instanceof Map) && ((Map<?, ?>) value).size() == 2) {
Object actualKey = keys.get(0);
Map<?, ?> valueMap = (Map<?, ?>) value;
if (valueMap.containsKey("key") && valueMap.containsKey("value")
&& actualKey.equals(valueMap.get("key"))) {
returnable.put(valueMap.get("key"), valueMap.get("value"));
}
else {
returnable.put(actualKey, value);
}
}
else {
returnable.put(keys, value);
}
}
return returnable;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-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.
@@ -22,6 +22,7 @@ import javax.management.Notification;
import javax.management.ObjectName;
import org.springframework.integration.mapping.OutboundMessageMapper;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.util.Assert;
@@ -32,32 +33,34 @@ import org.springframework.util.Assert;
* 'userData' of the Notification instance.
*
* @author Mark Fisher
* @author Artem Bilan
*
* @since 2.0
*/
class DefaultNotificationMapper implements OutboundMessageMapper<Notification> {
private final ObjectName sourceObjectName;
@Nullable
private final String defaultNotificationType;
private final AtomicLong sequence = new AtomicLong();
DefaultNotificationMapper(ObjectName sourceObjectName, String defaultNotificationType) {
DefaultNotificationMapper(ObjectName sourceObjectName, @Nullable String defaultNotificationType) {
this.sourceObjectName = sourceObjectName;
this.defaultNotificationType = defaultNotificationType;
}
public Notification fromMessage(Message<?> message) throws Exception {
String type = this.resolveNotificationType(message);
Assert.hasText(type,
"No notification type header is available, and no default has been provided.");
Object payload = (message != null) ? message.getPayload() : null;
public Notification fromMessage(Message<?> message) {
String type = resolveNotificationType(message);
Assert.hasText(type, "No notification type header is available, and no default has been provided.");
Object payload = message.getPayload();
String notificationMessage = (payload instanceof String) ? (String) payload : null;
Notification notification = new Notification(type, this.sourceObjectName,
this.sequence.incrementAndGet(), System.currentTimeMillis(), notificationMessage);
if (payload != null && !(payload instanceof String)) {
if (!(payload instanceof String)) {
notification.setUserData(payload);
}
return notification;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@ import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.jmx.export.notification.NotificationPublisher;
import org.springframework.jmx.export.notification.NotificationPublisherAware;
import org.springframework.jmx.support.ObjectNameManager;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.util.Assert;
@@ -55,11 +56,12 @@ public class NotificationPublishingMessageHandler extends AbstractMessageHandler
private final PublisherDelegate delegate = new PublisherDelegate();
private volatile OutboundMessageMapper<Notification> notificationMapper;
private final ObjectName objectName;
private volatile String defaultNotificationType;
private String defaultNotificationType;
@Nullable
private OutboundMessageMapper<Notification> notificationMapper;
public NotificationPublishingMessageHandler(ObjectName objectName) {
@@ -85,7 +87,7 @@ public class NotificationPublishingMessageHandler extends AbstractMessageHandler
* will be passed as the 'userData' of the Notification.
* @param notificationMapper The notification mapper.
*/
public void setNotificationMapper(OutboundMessageMapper<Notification> notificationMapper) {
public void setNotificationMapper(@Nullable OutboundMessageMapper<Notification> notificationMapper) {
this.notificationMapper = notificationMapper;
}
@@ -108,8 +110,9 @@ public class NotificationPublishingMessageHandler extends AbstractMessageHandler
@Override
public final void onInit() {
Assert.isTrue(this.getBeanFactory() instanceof ListableBeanFactory, "A ListableBeanFactory is required.");
Map<String, MBeanExporter> exporters = BeanFactoryUtils.beansOfTypeIncludingAncestors(
(ListableBeanFactory) this.getBeanFactory(), MBeanExporter.class);
Map<String, MBeanExporter> exporters =
BeanFactoryUtils.beansOfTypeIncludingAncestors((ListableBeanFactory) getBeanFactory(),
MBeanExporter.class);
Assert.isTrue(exporters.size() > 0, "No MBeanExporter is available in the current context.");
MBeanExporter exporter = null;
for (MBeanExporter exp : exporters.values()) {
@@ -128,7 +131,7 @@ public class NotificationPublishingMessageHandler extends AbstractMessageHandler
}
@Override
protected void handleMessageInternal(Message<?> message) throws Exception {
protected void handleMessageInternal(Message<?> message) throws Exception { // NOSONAR
this.delegate.publish(this.notificationMapper.fromMessage(message));
}
@@ -141,7 +144,7 @@ public class NotificationPublishingMessageHandler extends AbstractMessageHandler
@IntegrationManagedResource
public static class PublisherDelegate implements NotificationPublisherAware {
private volatile NotificationPublisher notificationPublisher;
private NotificationPublisher notificationPublisher;
@Override
public void setNotificationPublisher(NotificationPublisher notificationPublisher) {

View File

@@ -191,25 +191,9 @@ public class OperationInvokingMessageHandler extends AbstractReplyProducingMessa
hasNoArgOption = true;
}
if (paramInfoArray.length == paramsFromMessage.size()) {
int index = 0;
Object[] values = new Object[paramInfoArray.length];
String[] signature = new String[paramInfoArray.length];
for (MBeanParameterInfo paramInfo : paramInfoArray) {
Object value = paramsFromMessage.get(paramInfo.getName());
if (value == null) {
/*
* With Spring 3.2.3 and greater, the parameter names are
* registered instead of the JVM's default p1, p2 etc.
* Fall back to that naming style if not found.
*/
value = paramsFromMessage.get("p" + (index + 1));
}
if (value != null && valueTypeMatchesParameterType(value, paramInfo)) {
values[index] = value;
signature[index] = paramInfo.getType();
index++;
}
}
int index = populateValuesAndSignature(paramsFromMessage, paramInfoArray, values, signature);
if (index == paramInfoArray.length) {
return this.server.invoke(objectName, operation, values, signature);
}
@@ -226,6 +210,29 @@ public class OperationInvokingMessageHandler extends AbstractReplyProducingMessa
}
}
private int populateValuesAndSignature(Map<String, Object> paramsFromMessage, MBeanParameterInfo[] paramInfoArray,
Object[] values, String[] signature) {
int index = 0;
for (MBeanParameterInfo paramInfo : paramInfoArray) {
Object value = paramsFromMessage.get(paramInfo.getName());
if (value == null) {
/*
* With Spring 3.2.3 and greater, the parameter names are
* registered instead of the JVM's default p1, p2 etc.
* Fall back to that naming style if not found.
*/
value = paramsFromMessage.get("p" + (index + 1));
}
if (value != null && valueTypeMatchesParameterType(value, paramInfo)) {
values[index] = value;
signature[index] = paramInfo.getType();
index++;
}
}
return index;
}
private boolean valueTypeMatchesParameterType(Object value, MBeanParameterInfo paramInfo) {
Class<?> valueClass = value.getClass();
if (valueClass.getName().equals(paramInfo.getType())) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,6 +37,8 @@ import org.springframework.util.StringUtils;
*
* @author Mark Fisher
* @author Gary Russell
* @author Artem Bilan
*
* @since 2.0
*/
public class MBeanExporterParser extends AbstractSingleBeanDefinitionParser {
@@ -56,17 +58,19 @@ public class MBeanExporterParser extends AbstractSingleBeanDefinitionParser {
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
Object mbeanServer = getMBeanServer(element, parserContext);
Object mbeanServer = getMBeanServer(element);
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "default-domain");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "object-name-static-properties");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "managed-components", "componentNamePatterns");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "object-naming-strategy", "namingStrategy");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "managed-components",
"componentNamePatterns");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "object-naming-strategy",
"namingStrategy");
builder.addPropertyValue("server", mbeanServer);
}
private Object getMBeanServer(Element element, ParserContext parserContext) {
private Object getMBeanServer(Element element) {
String mbeanServer = element.getAttribute("server");
if (StringUtils.hasText(mbeanServer)) {
return new RuntimeBeanReference(mbeanServer);
@@ -77,12 +81,14 @@ public class MBeanExporterParser extends AbstractSingleBeanDefinitionParser {
}
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException {
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
throws BeanDefinitionStoreException {
String id = super.resolveId(element, definition, parserContext);
if (MBEAN_EXPORTER_NAME.equals(id)) {
parserContext.getReaderContext().error(
"Illegal bean id for <jmx:mbean-export/>: " + MBEAN_EXPORTER_NAME +
" (clashes with <context:mbean-export/> default). Please choose another bean id.",
" (clashes with <context:mbean-export/> default). Please choose another bean id.",
definition);
}
if (id.matches(IntegrationMBeanExporter.class.getName() + "#[0-9]+")) {

View File

@@ -34,9 +34,6 @@ import javax.management.JMException;
import javax.management.ObjectName;
import javax.management.modelmbean.ModelMBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.Advised;
import org.springframework.beans.BeansException;
@@ -120,9 +117,9 @@ import org.springframework.util.StringValueResolver;
public class IntegrationMBeanExporter extends MBeanExporter implements ApplicationContextAware,
EmbeddedValueResolverAware, DestructionAwareBeanPostProcessor {
private static final Log logger = LogFactory.getLog(IntegrationMBeanExporter.class);
private static final String SI_PACKAGE = "org.springframework.integration";
public static final String DEFAULT_DOMAIN = "org.springframework.integration";
public static final String DEFAULT_DOMAIN = SI_PACKAGE;
private final IntegrationJmxAttributeSource attributeSource = new IntegrationJmxAttributeSource();
@@ -227,48 +224,11 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
@Override
public void afterSingletonsInstantiated() {
Map<String, MessageHandlerMetrics> messageHandlers =
this.applicationContext.getBeansOfType(MessageHandlerMetrics.class);
for (Entry<String, MessageHandlerMetrics> entry : messageHandlers.entrySet()) {
String beanName = entry.getKey();
MessageHandlerMetrics bean = entry.getValue();
if (this.handlerInAnonymousWrapper(bean) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping " + beanName + " because it wraps another handler");
}
continue;
}
// If the handler is proxied, we have to extract the target to expose as an MBean.
// The MetadataMBeanInfoAssembler does not support JDK dynamic proxies.
MessageHandlerMetrics monitor = (MessageHandlerMetrics) extractTarget(bean);
this.handlers.add(monitor);
}
populateMessageHandlers();
populateMessageSources();
populateMessageChannels();
populateMessageProducers();
Map<String, MessageSourceMetrics> messageSources =
this.applicationContext.getBeansOfType(MessageSourceMetrics.class);
for (Entry<String, MessageSourceMetrics> entry : messageSources.entrySet()) {
// If the source is proxied, we have to extract the target to expose as an MBean.
// The MetadataMBeanInfoAssembler does not support JDK dynamic proxies.
MessageSourceMetrics monitor = (MessageSourceMetrics) extractTarget(entry.getValue());
this.sources.add(monitor);
}
Map<String, MessageChannelMetrics> messageChannels =
this.applicationContext.getBeansOfType(MessageChannelMetrics.class);
for (Entry<String, MessageChannelMetrics> entry : messageChannels.entrySet()) {
// If the channel is proxied, we have to extract the target to expose as an MBean.
// The MetadataMBeanInfoAssembler does not support JDK dynamic proxies.
MessageChannelMetrics monitor = (MessageChannelMetrics) extractTarget(entry.getValue());
this.channels.add(monitor);
}
Map<String, MessageProducer> messageProducers =
this.applicationContext.getBeansOfType(MessageProducer.class);
for (Entry<String, MessageProducer> entry : messageProducers.entrySet()) {
MessageProducer messageProducer = entry.getValue();
if (messageProducer instanceof Lifecycle) {
registerProducer(messageProducer);
}
}
super.afterSingletonsInstantiated();
try {
registerChannels();
@@ -285,19 +245,8 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
IntegrationContextUtils.INTEGRATION_MESSAGE_HISTORY_CONFIGURER_BEAN_NAME);
}
}
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();
}
else {
this.managementConfigurer =
this.applicationContext.getBean(IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME,
IntegrationManagementConfigurer.class);
}
configureManagementConfigurer();
this.singletonsInstantiated = true;
}
@@ -307,6 +256,71 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
}
}
private void populateMessageHandlers() {
Map<String, MessageHandlerMetrics> messageHandlers =
this.applicationContext.getBeansOfType(MessageHandlerMetrics.class);
for (Entry<String, MessageHandlerMetrics> entry : messageHandlers.entrySet()) {
String beanName = entry.getKey();
MessageHandlerMetrics bean = entry.getValue();
if (this.handlerInAnonymousWrapper(bean) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping " + beanName + " because it wraps another handler");
}
continue;
}
// If the handler is proxied, we have to extract the target to expose as an MBean.
// The MetadataMBeanInfoAssembler does not support JDK dynamic proxies.
MessageHandlerMetrics monitor = (MessageHandlerMetrics) extractTarget(bean);
this.handlers.add(monitor);
}
}
private void populateMessageSources() {
this.applicationContext.getBeansOfType(MessageSourceMetrics.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(MessageSourceMetrics.class::cast)
.forEach(this.sources::add);
}
private void populateMessageChannels() {
this.applicationContext.getBeansOfType(MessageChannelMetrics.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(MessageChannelMetrics.class::cast)
.forEach(this.channels::add);
}
private void populateMessageProducers() {
this.applicationContext.getBeansOfType(MessageProducer.class)
.values()
.stream()
.filter(Lifecycle.class::isInstance)
.forEach(this::registerProducer);
}
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();
}
else {
this.managementConfigurer =
this.applicationContext.getBean(IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME,
IntegrationManagementConfigurer.class);
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (this.singletonsInstantiated) {
@@ -322,33 +336,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
this.runtimeBeans.add(bean);
}
else if (bean instanceof AbstractEndpoint) {
if (bean instanceof IntegrationConsumer) {
IntegrationConsumer integrationConsumer = (IntegrationConsumer) bean;
MessageHandler handler = integrationConsumer.getHandler();
if (handler instanceof MessageHandlerMetrics) {
MessageHandlerMetrics messageHandlerMetrics =
(MessageHandlerMetrics) extractTarget(handler);
registerHandler(messageHandlerMetrics);
this.handlers.add(messageHandlerMetrics);
this.runtimeBeans.add(messageHandlerMetrics);
return bean;
}
}
else if (bean instanceof SourcePollingChannelAdapter) {
SourcePollingChannelAdapter pollingChannelAdapter = (SourcePollingChannelAdapter) bean;
MessageSource<?> messageSource = pollingChannelAdapter.getMessageSource();
if (messageSource instanceof MessageSourceMetrics) {
MessageSourceMetrics messageSourceMetrics =
(MessageSourceMetrics) extractTarget(messageSource);
registerSource(messageSourceMetrics);
this.sources.add(messageSourceMetrics);
this.runtimeBeans.add(messageSourceMetrics);
return bean;
}
}
registerEndpoint((AbstractEndpoint) bean);
this.runtimeBeans.add(bean);
postProcessAbstractEndpoint(bean);
}
}
catch (Exception e) {
@@ -358,6 +346,36 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
return bean;
}
private void postProcessAbstractEndpoint(Object bean) {
if (bean instanceof IntegrationConsumer) {
IntegrationConsumer integrationConsumer = (IntegrationConsumer) bean;
MessageHandler handler = integrationConsumer.getHandler();
if (handler instanceof MessageHandlerMetrics) {
MessageHandlerMetrics messageHandlerMetrics =
(MessageHandlerMetrics) extractTarget(handler);
registerHandler(messageHandlerMetrics);
this.handlers.add(messageHandlerMetrics);
this.runtimeBeans.add(messageHandlerMetrics);
return;
}
}
else if (bean instanceof SourcePollingChannelAdapter) {
SourcePollingChannelAdapter pollingChannelAdapter = (SourcePollingChannelAdapter) bean;
MessageSource<?> messageSource = pollingChannelAdapter.getMessageSource();
if (messageSource instanceof MessageSourceMetrics) {
MessageSourceMetrics messageSourceMetrics =
(MessageSourceMetrics) extractTarget(messageSource);
registerSource(messageSourceMetrics);
this.sources.add(messageSourceMetrics);
this.runtimeBeans.add(messageSourceMetrics);
return;
}
}
registerEndpoint((AbstractEndpoint) bean);
this.runtimeBeans.add(bean);
}
private void registerProducer(MessageProducer messageProducer) {
Lifecycle target = (Lifecycle) extractTarget(messageProducer);
if (!(target instanceof AbstractMessageProducingHandler)) {
@@ -367,7 +385,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
@Override
public boolean requiresDestruction(Object bean) {
return bean instanceof MessageChannelMetrics ||
return bean instanceof MessageChannelMetrics || // NOSONAR
bean instanceof MessageHandlerMetrics ||
bean instanceof MessageSourceMetrics ||
(bean instanceof MessageProducer && bean instanceof Lifecycle) ||
@@ -803,7 +821,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
String beanKey;
String name = endpoint.getComponentName();
String source;
if (name.startsWith("_org.springframework.integration")) {
if (name.startsWith('_' + SI_PACKAGE)) {
name = getInternalComponentName(name);
source = "internal";
}
@@ -820,7 +838,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
name = unique;
}
this.endpointNames.add(name);
beanKey = getEndpointBeanKey(endpoint, name, source);
beanKey = getEndpointBeanKey(name, source);
ObjectName objectName = registerBeanInstance(new ManagedEndpoint(endpoint), beanKey);
this.objectNames.put(endpoint, objectName);
if (logger.isInfoEnabled()) {
@@ -857,7 +875,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
private String getChannelBeanKey(String channel) {
String extra = "";
if (channel.startsWith("org.springframework.integration")) {
if (channel.startsWith(SI_PACKAGE)) {
extra = ",source=anonymous";
}
return String.format(this.domain + ":type=MessageChannel,name=%s%s" + getStaticNames(),
@@ -876,7 +894,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
quoteIfNecessary(source.getManagedName()), quoteIfNecessary(source.getManagedType()));
}
private String getEndpointBeanKey(AbstractEndpoint endpoint, String name, String source) {
private String getEndpointBeanKey(String name, String source) {
// This ordering of keys seems to work with default settings of JConsole
return String.format(this.domain + ":type=ManagedEndpoint,name=%s,bean=%s" + getStaticNames(),
quoteIfNecessary(name), source);
@@ -908,7 +926,6 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
}
private MessageHandlerMetrics enhanceHandlerMonitor(MessageHandlerMetrics monitor) {
MessageHandlerMetrics result = monitor;
if (monitor.getManagedName() != null && monitor.getManagedType() != null) {
@@ -927,8 +944,8 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
endpoint = this.applicationContext.getBean(beanName, IntegrationConsumer.class);
try {
MessageHandler handler = endpoint.getHandler();
if (handler == monitor ||
extractTarget(handlerInAnonymousWrapper(handler)) == monitor) {
if (handler.equals(monitor) ||
extractTarget(handlerInAnonymousWrapper(handler)).equals(monitor)) {
name = beanName;
endpointName = beanName;
break;
@@ -939,11 +956,11 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
endpoint = null;
}
}
if (name != null && endpoint != null && name.startsWith("_org.springframework.integration")) {
if (name != null && name.startsWith('_' + SI_PACKAGE)) {
name = getInternalComponentName(name);
source = "internal";
}
if (name != null && endpoint != null && name.startsWith("org.springframework.integration")) {
if (name != null && name.startsWith(SI_PACKAGE)) {
MessageChannel inputChannel = endpoint.getInputChannel();
if (inputChannel != null) {
if (!this.anonymousHandlerCounters.containsKey(inputChannel)) {
@@ -965,24 +982,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
}
if (endpoint instanceof Lifecycle) {
// Wrap the monitor in a lifecycle so it exposes the start/stop operations
if (monitor instanceof MappingMessageRouterManagement) {
if (monitor instanceof TrackableComponent) {
result = new TrackableRouterMetrics((Lifecycle) endpoint,
(MappingMessageRouterManagement) monitor);
}
else {
result = new RouterMetrics((Lifecycle) endpoint, (MappingMessageRouterManagement) monitor);
}
}
else {
if (monitor instanceof TrackableComponent) {
result = new LifecycleTrackableMessageHandlerMetrics((Lifecycle) endpoint, monitor);
}
else {
result = new LifecycleMessageHandlerMetrics((Lifecycle) endpoint, monitor);
}
}
result = wrapMessageHandlerInLifecycleMetrics(monitor, (Lifecycle) endpoint);
}
if (name == null) {
@@ -1006,8 +1006,35 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
}
/**
* Wrap the monitor in a lifecycle so it exposes the start/stop operations
*/
private MessageHandlerMetrics wrapMessageHandlerInLifecycleMetrics(MessageHandlerMetrics monitor,
Lifecycle endpoint) {
MessageHandlerMetrics result;
if (monitor instanceof MappingMessageRouterManagement) {
if (monitor instanceof TrackableComponent) {
result = new TrackableRouterMetrics(endpoint,
(MappingMessageRouterManagement) monitor);
}
else {
result = new RouterMetrics(endpoint, (MappingMessageRouterManagement) monitor);
}
}
else {
if (monitor instanceof TrackableComponent) {
result = new LifecycleTrackableMessageHandlerMetrics(endpoint, monitor);
}
else {
result = new LifecycleMessageHandlerMetrics(endpoint, monitor);
}
}
return result;
}
private String getInternalComponentName(String name) {
return name.substring("_org.springframework.integration".length() + 1);
return name.substring(('_' + SI_PACKAGE).length() + 1);
}
private MessageSourceMetrics enhanceSourceMonitor(MessageSourceMetrics monitor) {
@@ -1028,7 +1055,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
for (String beanName : names) {
endpoint = this.applicationContext.getBean(beanName);
Object field = null;
if (monitor instanceof MessagingGatewaySupport && endpoint == monitor) {
if (monitor instanceof MessagingGatewaySupport && endpoint.equals(monitor)) {
field = monitor;
}
else {
@@ -1041,30 +1068,29 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
}
}
if (field == monitor) {
if (monitor.equals(field)) {
name = beanName;
endpointName = beanName;
break;
}
}
if (endpointName == null) {
endpoint = null;
}
if (name != null && endpoint != null && name.startsWith("_org.springframework.integration")) {
if (name != null && name.startsWith('_' + SI_PACKAGE)) {
name = getInternalComponentName(name);
source = "internal";
}
if (name != null && endpoint != null && name.startsWith("org.springframework.integration")) {
if (name != null && name.startsWith(SI_PACKAGE)) {
Object target = endpoint;
if (endpoint instanceof Advised) {
TargetSource targetSource = ((Advised) endpoint).getTargetSource();
if (targetSource != null) {
try {
target = targetSource.getTarget();
}
catch (Exception e) {
logger.error("Could not get handler from bean = " + name);
}
try {
target = targetSource.getTarget();
}
catch (Exception e) {
logger.error("Could not get handler from bean = " + name);
}
}
@@ -1096,25 +1122,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
}
if (endpoint instanceof Lifecycle) {
// Wrap the monitor in a lifecycle so it exposes the start/stop operations
if (endpoint instanceof TrackableComponent) {
if (monitor instanceof MessageSourceManagement) {
result = new LifecycleTrackableMessageSourceManagement((Lifecycle) endpoint,
(MessageSourceManagement) monitor);
}
else {
result = new LifecycleTrackableMessageSourceMetrics((Lifecycle) endpoint, monitor);
}
}
else {
if (monitor instanceof MessageSourceManagement) {
result = new LifecycleMessageSourceManagement((Lifecycle) endpoint,
(MessageSourceManagement) monitor);
}
else {
result = new LifecycleMessageSourceMetrics((Lifecycle) endpoint, monitor);
}
}
result = wrapMessageSourceInLifecycleMetrics(monitor, endpoint);
}
if (name == null) {
@@ -1132,7 +1140,33 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati
return result;
}
private static Object getField(Object target, String name) {
/**
* Wrap the monitor in a lifecycle so it exposes the start/stop operations
*/
private MessageSourceMetrics wrapMessageSourceInLifecycleMetrics(MessageSourceMetrics monitor, Object endpoint) {
MessageSourceMetrics result;
if (endpoint instanceof TrackableComponent) {
if (monitor instanceof MessageSourceManagement) {
result = new LifecycleTrackableMessageSourceManagement((Lifecycle) endpoint,
(MessageSourceManagement) monitor);
}
else {
result = new LifecycleTrackableMessageSourceMetrics((Lifecycle) endpoint, monitor);
}
}
else {
if (monitor instanceof MessageSourceManagement) {
result = new LifecycleMessageSourceManagement((Lifecycle) endpoint,
(MessageSourceManagement) monitor);
}
else {
result = new LifecycleMessageSourceMetrics((Lifecycle) endpoint, monitor);
}
}
return result;
}
private Object getField(Object target, String name) {
Assert.notNull(target, "Target object must not be null");
Field field = ReflectionUtils.findField(target.getClass(), name);
if (field == null) {