001 /**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements. See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package org.apache.camel.management;
019
020 import java.util.HashSet;
021 import java.util.Set;
022
023 import javax.management.InstanceAlreadyExistsException;
024 import javax.management.JMException;
025 import javax.management.MBeanServer;
026 import javax.management.NotCompliantMBeanException;
027 import javax.management.ObjectInstance;
028 import javax.management.ObjectName;
029 import javax.management.modelmbean.InvalidTargetObjectTypeException;
030 import javax.management.modelmbean.ModelMBeanInfo;
031 import javax.management.modelmbean.RequiredModelMBean;
032
033 import org.apache.camel.CamelContext;
034 import org.apache.camel.CamelContextAware;
035 import org.apache.camel.InstrumentationAgent;
036 import org.apache.camel.impl.DefaultCamelContext;
037 import org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource;
038 import org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler;
039
040 public class InstrumentationAgentImpl implements InstrumentationAgent, CamelContextAware {
041
042 private MBeanServer server;
043 private CamelContext context;
044 private Set<ObjectName> mbeans = new HashSet<ObjectName>();
045 MetadataMBeanInfoAssembler assembler;
046
047 public InstrumentationAgentImpl() {
048 assembler = new MetadataMBeanInfoAssembler();
049 assembler.setAttributeSource(new AnnotationJmxAttributeSource());
050 }
051 public CamelContext getCamelContext() {
052 return context;
053 }
054
055 public void setCamelContext(CamelContext camelContext) {
056 context = camelContext;
057 }
058
059 public void setMBeanServer(MBeanServer server) {
060 this.server = server;
061 }
062
063 public MBeanServer getMBeanServer() {
064 return server;
065 }
066
067 public void register(Object obj, ObjectName name) throws JMException {
068 register(obj, name, false);
069 }
070
071 public void register(Object obj, ObjectName name, boolean forceRegistration) throws JMException {
072 try {
073 registerMBeanWithServer(obj, name, forceRegistration);
074 } catch (NotCompliantMBeanException e) {
075 //If this is not a "normal" MBean, then try to deploy it using JMX annotations
076 ModelMBeanInfo mbi = null;
077 mbi = assembler.getMBeanInfo(obj, name.toString());
078 RequiredModelMBean mbean = (RequiredModelMBean)server.instantiate(RequiredModelMBean.class.getName());
079 mbean.setModelMBeanInfo(mbi);
080 try {
081 mbean.setManagedResource(obj, "ObjectReference");
082 } catch (InvalidTargetObjectTypeException itotex) {
083 throw new JMException(itotex.getMessage());
084 }
085 registerMBeanWithServer(mbean, name, forceRegistration);
086 }
087 }
088
089 public void unregister(ObjectName name) throws JMException {
090 }
091
092 public void start() {
093 if (context == null) {
094 // LOG warning
095 return;
096 }
097
098 if (context instanceof DefaultCamelContext) {
099 DefaultCamelContext dc = (DefaultCamelContext)context;
100 InstrumentationLifecycleStrategy ls = new InstrumentationLifecycleStrategy(this);
101 dc.setLifecycleStrategy(ls);
102 ls.onContextCreate(context);
103 }
104 }
105
106 public void stop() {
107 //Using the array to hold the busMBeans to avoid the CurrentModificationException
108 Object[] mBeans = mbeans.toArray();
109 for (Object name : mBeans) {
110 mbeans.remove((ObjectName)name);
111 try {
112 unregister((ObjectName)name);
113 } catch (JMException jmex) {
114 // log
115 }
116 }
117 }
118
119 private void registerMBeanWithServer(Object obj, ObjectName name, boolean forceRegistration)
120 throws JMException {
121
122 ObjectInstance instance = null;
123 try {
124 instance = server.registerMBean(obj, name);
125 } catch (InstanceAlreadyExistsException e) {
126 if (forceRegistration) {
127 server.unregisterMBean(name);
128 instance = server.registerMBean(obj, name);
129 } else {
130 throw e;
131 }
132 }
133
134 if (instance != null) {
135 mbeans.add(name);
136 }
137 }
138 }