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.Exchange;
026    import org.apache.camel.Processor;
027    import org.apache.camel.Producer;
028    import org.apache.camel.impl.DefaultEndpoint;
029    import org.apache.camel.util.ObjectHelper;
030    import org.apache.commons.logging.Log;
031    import org.apache.commons.logging.LogFactory;
032    
033    /**
034     * JMXEndpoint for monitoring JMX attributs using {@link CounterMonitor}.
035     *
036     * @version $Revision: 736322 $
037     */
038    public class JMXEndpoint extends DefaultEndpoint {
039        private static final transient Log LOG = LogFactory.getLog(JMXEndpoint.class);
040        private String name;
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        public JMXEndpoint() {
050        }
051    
052        public JMXEndpoint(String endpointUri, JMXComponent component) {
053            super(endpointUri, component);
054            observedObjectName = endpointUri;
055        }
056    
057        public JMXEndpoint(String endpointUri) {
058            super(endpointUri);
059        }
060    
061        public Producer createProducer() throws Exception {
062            throw new UnsupportedOperationException("Producer not supported");
063        }
064    
065        public Consumer createConsumer(Processor proc) throws Exception {
066            ObjectHelper.notNull(mbeanServer, "mbeanServer");
067    
068            ObjectName observedName = new ObjectName(observedObjectName);
069            if (name == null) {
070                String type = observedName.getKeyProperty("type");
071                type = type != null ? type : "UNKNOWN";
072                name = mbeanServer.getDefaultDomain() + ":type=CounterMonitor_" + type;
073            }
074    
075            JMXConsumer result = new JMXConsumer(this, proc);
076            ObjectName ourName = new ObjectName(name);
077            counterMonitor.setNotify(true);
078            counterMonitor.addObservedObject(observedName);
079            counterMonitor.setObservedAttribute(attributeName);
080            counterMonitor.setGranularityPeriod(granularityPeriod);
081            counterMonitor.setDifferenceMode(false);
082            counterMonitor.setInitThreshold(threshold);
083            counterMonitor.setOffset(offset);
084    
085            if (LOG.isDebugEnabled()) {
086                LOG.debug("Registering and adding notification listener for [" + counterMonitor + "] with name [" + ourName + "]");
087            }
088            mbeanServer.registerMBean(counterMonitor, ourName);
089            // TODO: How do we remove the listener?
090            mbeanServer.addNotificationListener(ourName, result, null, new Object());
091            return result;
092        }
093    
094        public boolean isSingleton() {
095            return true;
096        }
097    
098        public Exchange createExchange(Notification notification) {
099            Exchange exchange = createExchange();
100            exchange.setIn(new JMXMessage(notification));
101            return exchange;
102        }
103    
104        public String getAttributeName() {
105            return attributeName;
106        }
107    
108        public void setAttributeName(String attributeName) {
109            this.attributeName = attributeName;
110        }
111    
112        public long getGranularityPeriod() {
113            return granularityPeriod;
114        }
115    
116        public void setGranularityPeriod(long granularityPeriod) {
117            this.granularityPeriod = granularityPeriod;
118        }
119    
120        public String getName() {
121            return name;
122        }
123    
124        public void setName(String name) {
125            this.name = name;
126        }
127    
128        public Number getOffset() {
129            return offset;
130        }
131    
132        public void setOffset(Number offset) {
133            this.offset = offset;
134        }
135    
136        public Number getThreshold() {
137            return threshold;
138        }
139    
140        public void setThreshold(Number threshold) {
141            this.threshold = threshold;
142        }
143    
144        public MBeanServer getMbeanServer() {
145            return mbeanServer;
146        }
147    
148        public void setMbeanServer(MBeanServer mbeanServer) {
149            this.mbeanServer = mbeanServer;
150        }
151    }