001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.jmx;
018    
019    import javax.management.MBeanServer;
020    import javax.management.Notification;
021    import javax.management.ObjectName;
022    import javax.management.monitor.CounterMonitor;
023    
024    import org.apache.camel.Consumer;
025    import org.apache.camel.ExchangePattern;
026    import org.apache.camel.Processor;
027    import org.apache.camel.Producer;
028    import org.apache.camel.impl.DefaultEndpoint;
029    import org.apache.commons.logging.Log;
030    import org.apache.commons.logging.LogFactory;
031    
032    /**
033     * JMXEndpoint for monitoring JMX attributs using {@link CounterMonitor}.
034     *
035     * @version $Revision: 585 $
036     */
037    public class JMXEndpoint extends DefaultEndpoint<JMXExchange> {
038        private static final transient Log LOG = LogFactory.getLog(JMXEndpoint.class);
039        private String name;
040        private ObjectName ourName;
041        private String observedObjectName;
042        private String attributeName;
043        private long granularityPeriod = 5000;
044        private Number threshold;
045        private Number offset;
046        private MBeanServer mbeanServer;
047        private CounterMonitor counterMonitor = new CounterMonitor();
048    
049        protected JMXEndpoint(String endpointUri, JMXComponent component) {
050            super(endpointUri, component);
051            observedObjectName = endpointUri;
052        }
053    
054        public JMXEndpoint(String endpointUri) {
055            super(endpointUri);
056        }
057    
058        public Producer<JMXExchange> createProducer() throws Exception {
059            throw new UnsupportedOperationException("Producer not supported");
060        }
061    
062        public Consumer<JMXExchange> createConsumer(Processor proc) throws Exception {
063            ObjectName observedName = new ObjectName(observedObjectName);
064            if (name == null) {
065                String type = observedName.getKeyProperty("type");
066                type = type != null ? type : "UNKNOWN";
067                name = mbeanServer.getDefaultDomain() + ":type=CounterMonitor_" + type;
068            }
069    
070            JMXConsumer result = new JMXConsumer(this, proc);
071            ourName = new ObjectName(name);
072            counterMonitor.setNotify(true);
073            counterMonitor.addObservedObject(observedName);
074            counterMonitor.setObservedAttribute(attributeName);
075            counterMonitor.setGranularityPeriod(granularityPeriod);
076            counterMonitor.setDifferenceMode(false);
077            counterMonitor.setInitThreshold(threshold);
078            counterMonitor.setOffset(offset);
079    
080            if (LOG.isDebugEnabled()) {
081                LOG.debug("Registering and adding notification listener for [" + counterMonitor + "] with name [" + ourName + "]");
082            }
083            mbeanServer.registerMBean(counterMonitor, ourName);
084            // TODO: How do we remove the listener?
085            mbeanServer.addNotificationListener(ourName, result, null, new Object());
086            return result;
087        }
088    
089        public boolean isSingleton() {
090            return true;
091        }
092    
093        public JMXExchange createExchange(Notification notification) {
094            return new JMXExchange(getCamelContext(), getExchangePattern(), notification);
095        }
096    
097        public JMXExchange createExchange() {
098            return new JMXExchange(getCamelContext(), getExchangePattern(), null);
099        }
100    
101        public JMXExchange createExchange(ExchangePattern pattern) {
102            return new JMXExchange(getCamelContext(), pattern, null);
103        }
104    
105        public String getAttributeName() {
106            return attributeName;
107        }
108    
109        public void setAttributeName(String attributeName) {
110            this.attributeName = attributeName;
111        }
112    
113        public long getGranularityPeriod() {
114            return granularityPeriod;
115        }
116    
117        public void setGranularityPeriod(long granularityPeriod) {
118            this.granularityPeriod = granularityPeriod;
119        }
120    
121        public String getName() {
122            return name;
123        }
124    
125        public void setName(String name) {
126            this.name = name;
127        }
128    
129        public Number getOffset() {
130            return offset;
131        }
132    
133        public void setOffset(Number offset) {
134            this.offset = offset;
135        }
136    
137        public Number getThreshold() {
138            return threshold;
139        }
140    
141        public void setThreshold(Number threshold) {
142            this.threshold = threshold;
143        }
144    
145        public MBeanServer getMbeanServer() {
146            return mbeanServer;
147        }
148    
149        public void setMbeanServer(MBeanServer mbeanServer) {
150            this.mbeanServer = mbeanServer;
151        }
152    }