/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.camel.component.jmx; import java.io.StringWriter; import java.util.ArrayList; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import javax.management.AttributeChangeNotification; import javax.management.MBeanServerNotification; import javax.management.Notification; import javax.management.ObjectName; import javax.management.monitor.MonitorNotification; import javax.management.relation.RelationNotification; import javax.management.remote.JMXConnectionNotification; import javax.management.timer.TimerNotification; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import org.apache.camel.component.jmx.jaxb.NotificationEventType; import org.apache.camel.component.jmx.jaxb.ObjectFactory; import org.apache.camel.component.jmx.jaxb.ObjectNamesType; import org.apache.camel.support.ServiceSupport; import org.apache.camel.util.ObjectHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Converts the Notification into an XML stream. */ public class NotificationXmlFormatter extends ServiceSupport { private static final Logger LOG = LoggerFactory.getLogger(NotificationXmlFormatter.class); private final ObjectFactory mObjectFactory = new ObjectFactory(); private JAXBContext jaxbContext; private DatatypeFactory mDatatypeFactory; public String format(Notification aNotification) throws NotificationFormatException { ObjectHelper.notNull(jaxbContext, "jaxbContext"); NotificationEventType jaxb; boolean wrap = false; if (aNotification instanceof AttributeChangeNotification) { AttributeChangeNotification ac = (AttributeChangeNotification) aNotification; jaxb = mObjectFactory.createAttributeChangeNotification() .withAttributeName(ac.getAttributeName()) .withAttributeType(ac.getAttributeType()) .withNewValue(ac.getNewValue() == null ? null : String.valueOf(ac.getNewValue())) .withOldValue(ac.getOldValue() == null ? null : String.valueOf(ac.getOldValue())); } else if (aNotification instanceof JMXConnectionNotification) { jaxb = mObjectFactory.createJMXConnectionNotification() .withConnectionId(((JMXConnectionNotification) aNotification).getConnectionId()); } else if (aNotification instanceof MBeanServerNotification) { jaxb = mObjectFactory.createMBeanServerNotification() .withMBeanName(String.valueOf(((MBeanServerNotification) aNotification).getMBeanName())); } else if (aNotification instanceof MonitorNotification) { MonitorNotification mn = (MonitorNotification) aNotification; jaxb = mObjectFactory.createMonitorNotification() .withDerivedGauge(String.valueOf(mn.getDerivedGauge())) .withObservedAttribute(mn.getObservedAttribute()) .withObservedObject(String.valueOf(mn.getObservedObject())) .withTrigger(String.valueOf(mn.getTrigger())); } else if (aNotification instanceof RelationNotification) { RelationNotification rn = (RelationNotification) aNotification; jaxb = mObjectFactory.createRelationNotification() .withObjectName(String.valueOf(rn.getObjectName())) .withRelationId(rn.getRelationId()) .withRelationTypeName(rn.getRelationTypeName()) .withRoleName(rn.getRoleName()); if (rn.getNewRoleValue() != null) { ObjectNamesType ont = toObjectNamesType(rn.getNewRoleValue()); ((org.apache.camel.component.jmx.jaxb.RelationNotification) jaxb).withNewRoleValue(ont); } if (rn.getOldRoleValue() != null) { ObjectNamesType ont = toObjectNamesType(rn.getOldRoleValue()); ((org.apache.camel.component.jmx.jaxb.RelationNotification) jaxb).withOldRoleValue(ont); } if (rn.getMBeansToUnregister() != null) { ObjectNamesType ont = toObjectNamesType(rn.getMBeansToUnregister()); ((org.apache.camel.component.jmx.jaxb.RelationNotification) jaxb).withMBeansToUnregister(ont); } } else if (aNotification instanceof TimerNotification) { jaxb = mObjectFactory.createTimerNotification().withNotificationId(((TimerNotification) aNotification).getNotificationID()); } else { jaxb = mObjectFactory.createNotificationEventType(); wrap = true; } // add all of the common properties jaxb.withMessage(aNotification.getMessage()) .withSequence(aNotification.getSequenceNumber()) .withSource(String.valueOf(aNotification.getSource())) .withTimestamp(aNotification.getTimeStamp()) .withType(aNotification.getType()); if (aNotification.getUserData() != null) { jaxb.withUserData(String.valueOf(aNotification.getUserData())); } try { DatatypeFactory df = getDatatypeFactory(); Date date = new Date(aNotification.getTimeStamp()); GregorianCalendar gc = new GregorianCalendar(); gc.setTime(date); jaxb.withDateTime(df.newXMLGregorianCalendar(gc)); Object bean = wrap ? mObjectFactory.createNotificationEvent(jaxb) : jaxb; StringWriter sw = new StringWriter(); // must create a new marshaller as its not thread safe Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.marshal(bean, sw); return sw.toString(); } catch (JAXBException e) { throw new NotificationFormatException(e); } catch (DatatypeConfigurationException e) { throw new NotificationFormatException(e); } } private ObjectNamesType toObjectNamesType(List<ObjectName> objectNameList) { List<String> roles = toStringList(objectNameList); ObjectNamesType ont = mObjectFactory.createObjectNamesType(); ont.withObjectName(roles); return ont; } private DatatypeFactory getDatatypeFactory() throws DatatypeConfigurationException { if (mDatatypeFactory == null) { mDatatypeFactory = DatatypeFactory.newInstance(); } return mDatatypeFactory; } private List<String> toStringList(List<ObjectName> objectNames) { List<String> roles = new ArrayList<String>(objectNames.size()); for (ObjectName on : objectNames) { roles.add(on.toString()); } return roles; } /** * Strategy to create JAXB context */ protected JAXBContext createContext(String contextPath) throws JAXBException { ClassLoader cl = NotificationXmlFormatter.class.getClassLoader(); try { LOG.info("Creating JAXBContext with contextPath: " + contextPath + " and classloader: " + cl); return JAXBContext.newInstance(contextPath, cl); } catch (Exception e) { LOG.info("Creating JAXBContext with contextPath: " + contextPath); return JAXBContext.newInstance(contextPath); } } @Override protected void doStart() throws Exception { jaxbContext = createContext("org.apache.camel.component.jmx.jaxb"); } @Override protected void doStop() throws Exception { } }