org.springframework.integration.jmx.NotificationPublishingMessageHandler Maven / Gradle / Ivy
/*
* Copyright 2002-2016 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
*
* http://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.jmx;
import java.util.Map;
import javax.management.MalformedObjectNameException;
import javax.management.Notification;
import javax.management.ObjectName;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.integration.handler.AbstractMessageHandler;
import org.springframework.integration.mapping.OutboundMessageMapper;
import org.springframework.integration.monitor.IntegrationMBeanExporter;
import org.springframework.integration.support.management.IntegrationManagedResource;
import org.springframework.jmx.export.MBeanExporter;
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.messaging.Message;
import org.springframework.util.Assert;
/**
* An {@link AbstractMessageHandler} implementation to publish an incoming message
* as a JMX {@link Notification}.
* The {@link OutboundMessageMapper} is used to convert a {@link Message} to the {@link Notification}.
*
* @author Mark Fisher
* @author Oleg Zhurakousky
* @author Gary Russell
* @author Artem Bilan
*
* @since 2.0
*/
public class NotificationPublishingMessageHandler extends AbstractMessageHandler
implements BeanFactoryAware, InitializingBean {
private final PublisherDelegate delegate = new PublisherDelegate();
private volatile OutboundMessageMapper notificationMapper;
private final ObjectName objectName;
private volatile String defaultNotificationType;
public NotificationPublishingMessageHandler(ObjectName objectName) {
Assert.notNull(objectName, "JMX ObjectName is required");
this.objectName = objectName;
}
public NotificationPublishingMessageHandler(String objectName) {
Assert.notNull(objectName, "JMX ObjectName is required");
try {
this.objectName = ObjectNameManager.getInstance(objectName);
}
catch (MalformedObjectNameException e) {
throw new IllegalArgumentException(e);
}
}
/**
* Set a mapper for creating Notifications from a Message. If not provided,
* a default implementation will be used such that String-typed payloads will be
* passed as the 'message' of the Notification and all other payload types
* will be passed as the 'userData' of the Notification.
* @param notificationMapper The notification mapper.
*/
public void setNotificationMapper(OutboundMessageMapper notificationMapper) {
this.notificationMapper = notificationMapper;
}
/**
* Specify a dot-delimited String representing the Notification type to
* use by default when no explicit Notification mapper
* has been configured. If not provided, then a notification type header will
* be required for each message being mapped into a Notification.
* @param defaultNotificationType The default notification type.
*/
public void setDefaultNotificationType(String defaultNotificationType) {
this.defaultNotificationType = defaultNotificationType;
}
@Override
public String getComponentType() {
return "jmx:notification-publishing-channel-adapter";
}
@Override
public final void onInit() throws Exception {
Assert.isTrue(this.getBeanFactory() instanceof ListableBeanFactory, "A ListableBeanFactory is required.");
Map exporters = BeanFactoryUtils.beansOfTypeIncludingAncestors(
(ListableBeanFactory) this.getBeanFactory(), MBeanExporter.class);
Assert.isTrue(exporters.size() > 0, "No MBeanExporter is available in the current context.");
MBeanExporter exporter = null;
for (MBeanExporter exp : exporters.values()) {
exporter = exp;
if (exporter instanceof IntegrationMBeanExporter) {
break;
}
}
if (this.notificationMapper == null) {
this.notificationMapper = new DefaultNotificationMapper(this.objectName, this.defaultNotificationType);
}
exporter.registerManagedResource(this.delegate, this.objectName);
if (this.logger.isInfoEnabled()) {
this.logger.info("Registered JMX notification publisher as MBean with ObjectName: " + this.objectName);
}
}
@Override
protected void handleMessageInternal(Message> message) throws Exception {
this.delegate.publish(this.notificationMapper.fromMessage(message));
}
/**
* Simple class used for the actual MBean instances to be registered.
* Exposed to standard MBEs as well as the IMBE for backwards compatibility.
*/
@ManagedResource
@IntegrationManagedResource
public static class PublisherDelegate implements NotificationPublisherAware {
private volatile NotificationPublisher notificationPublisher;
@Override
public void setNotificationPublisher(NotificationPublisher notificationPublisher) {
this.notificationPublisher = notificationPublisher;
}
private void publish(Notification notification) {
Assert.state(this.notificationPublisher != null, "NotificationPublisher must not be null.");
this.notificationPublisher.sendNotification(notification);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy