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 }