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.management; 018 019 import java.net.InetAddress; 020 import java.net.UnknownHostException; 021 022 import javax.management.MalformedObjectNameException; 023 import javax.management.ObjectName; 024 025 import org.apache.camel.CamelContext; 026 import org.apache.camel.Consumer; 027 import org.apache.camel.Endpoint; 028 import org.apache.camel.Route; 029 import org.apache.camel.Service; 030 import org.apache.camel.model.ProcessorDefinition; 031 import org.apache.camel.spi.RouteContext; 032 033 /** 034 * Naming strategy used when registering MBeans. 035 */ 036 public class CamelNamingStrategy { 037 public static final String VALUE_UNKNOWN = "unknown"; 038 public static final String KEY_NAME = "name"; 039 public static final String KEY_TYPE = "type"; 040 public static final String KEY_CONTEXT = "context"; 041 public static final String KEY_GROUP = "group"; 042 public static final String KEY_ROUTE = "route"; 043 public static final String KEY_NODE_ID = "nodeid"; 044 public static final String TYPE_CONTEXT = "context"; 045 public static final String TYPE_ENDPOINT = "endpoints"; 046 public static final String TYPE_PROCESSOR = "processors"; 047 public static final String TYPE_CONSUMER = "consumers"; 048 public static final String TYPE_ROUTE = "routes"; 049 050 protected String domainName; 051 protected String hostName = "localhost"; 052 053 public CamelNamingStrategy() { 054 this("org.apache.camel"); 055 } 056 057 public CamelNamingStrategy(String domainName) { 058 if (domainName != null) { 059 this.domainName = domainName; 060 } 061 try { 062 hostName = InetAddress.getLocalHost().getHostName(); 063 } catch (UnknownHostException ex) { 064 // ignore, use the default "locahost" 065 } 066 } 067 068 /** 069 * Implements the naming strategy for a {@link CamelContext}. 070 * The convention used for a {@link CamelContext} ObjectName is: 071 * <tt><domain>:context=<context-name>,type=context,name=<context-name></tt> 072 * 073 * @param context the camel context 074 * @return generated ObjectName 075 * @throws MalformedObjectNameException can be thrown 076 */ 077 public ObjectName getObjectName(CamelContext context) throws MalformedObjectNameException { 078 StringBuffer buffer = new StringBuffer(); 079 buffer.append(domainName).append(":"); 080 buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(","); 081 buffer.append(KEY_NAME + "=").append("context"); 082 return createObjectName(buffer); 083 } 084 085 /** 086 * Implements the naming strategy for a {@link ManagedEndpoint}. 087 * The convention used for a {@link ManagedEndpoint} ObjectName is: 088 * <tt><domain>:context=<context-name>,type=endpoint,component=<component-name>name=<endpoint-name></tt> 089 */ 090 public ObjectName getObjectName(ManagedEndpoint mbean) throws MalformedObjectNameException { 091 Endpoint ep = mbean.getEndpoint(); 092 093 StringBuffer buffer = new StringBuffer(); 094 buffer.append(domainName).append(":"); 095 buffer.append(KEY_CONTEXT + "=").append(getContextId(ep.getCamelContext())).append(","); 096 buffer.append(KEY_TYPE + "=" + TYPE_ENDPOINT + ","); 097 buffer.append(KEY_NAME + "=").append(ObjectName.quote(getEndpointId(ep))); 098 return createObjectName(buffer); 099 } 100 101 /** 102 * Implements the naming strategy for a {@link org.apache.camel.impl.ServiceSupport Service}. 103 * The convention used for a {@link org.apache.camel.Service Service} ObjectName is 104 * <tt><domain>:context=<context-name>,type=service,name=<service-name></tt> 105 */ 106 public ObjectName getObjectName(CamelContext context, ManagedService mbean) throws MalformedObjectNameException { 107 String serviceBranch; 108 Service service = mbean.getService(); 109 if (service instanceof Consumer) { 110 serviceBranch = TYPE_CONSUMER; 111 } else { 112 return null; 113 } 114 115 StringBuffer buffer = new StringBuffer(); 116 buffer.append(domainName).append(":"); 117 buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(","); 118 buffer.append(KEY_TYPE + "=" + serviceBranch + ","); 119 buffer.append(KEY_NAME + "=") 120 .append(service.getClass().getSimpleName()) 121 .append("(0x").append(Integer.toHexString(mbean.getService().hashCode())).append(")"); 122 return createObjectName(buffer); 123 } 124 125 126 /** 127 * Implements the naming strategy for a {@link ManagedRoute}. 128 * The convention used for a {@link ManagedRoute} ObjectName is: 129 * <tt><domain>:context=<context-name>,route=<route-name>,type=route,name=<route-name></tt> 130 */ 131 public ObjectName getObjectName(ManagedRoute mbean) throws MalformedObjectNameException { 132 Route route = mbean.getRoute(); 133 Endpoint ep = route.getEndpoint(); 134 String id = (String)route.getProperties().get(Route.ID_PROPERTY); 135 136 StringBuffer buffer = new StringBuffer(); 137 buffer.append(domainName).append(":"); 138 buffer.append(KEY_CONTEXT + "=").append(getContextId(ep.getCamelContext())).append(","); 139 buffer.append(KEY_TYPE + "=" + TYPE_ROUTE + ","); 140 buffer.append(KEY_NAME + "=").append(ObjectName.quote(id == null ? ("0x" + Integer.toHexString(route.hashCode())) : id)); 141 return createObjectName(buffer); 142 } 143 144 /** 145 * Implements the naming strategy for a {@link ProcessorDefinition}. 146 * The convention used for a {@link ProcessorDefinition} ObjectName is: 147 * <tt><domain>:context=<context-name>,route=<route-name>,type=processor,name=<processor-name>,nodeid=<node-id></tt> 148 */ 149 public ObjectName getObjectName(RouteContext routeContext, ProcessorDefinition processor) 150 throws MalformedObjectNameException { 151 Endpoint ep = routeContext.getEndpoint(); 152 String ctxid; 153 String cid; 154 if (ep != null) { 155 ctxid = getContextId(ep.getCamelContext()); 156 cid = ObjectName.quote(ep.getEndpointUri()); 157 } else { 158 ctxid = VALUE_UNKNOWN; 159 cid = null; 160 } 161 //String id = VALUE_UNKNOWN.equals(cid) ? ObjectName.quote(getEndpointId(ep) : "[" + cid + "]" + ObjectName.quote(getEndpointId(ep); 162 String nodeId = processor.idOrCreate(); 163 164 StringBuffer buffer = new StringBuffer(); 165 buffer.append(domainName).append(":"); 166 buffer.append(KEY_CONTEXT + "=").append(ctxid).append(","); 167 // buffer.append(KEY_ROUTE + "=").append(id).append(","); 168 buffer.append(KEY_TYPE + "=" + TYPE_PROCESSOR + ","); 169 buffer.append(KEY_NODE_ID + "=").append(nodeId).append(","); 170 buffer.append(KEY_NAME + "=").append(ObjectName.quote(processor.toString())); 171 return createObjectName(buffer); 172 } 173 174 public String getDomainName() { 175 return domainName; 176 } 177 178 public void setDomainName(String domainName) { 179 this.domainName = domainName; 180 } 181 182 public String getHostName() { 183 return hostName; 184 } 185 186 public void setHostName(String hostName) { 187 this.hostName = hostName; 188 } 189 190 protected String getContextId(CamelContext context) { 191 return hostName + "/" + (context != null ? context.getName() : VALUE_UNKNOWN); 192 } 193 194 protected String getEndpointId(Endpoint ep) { 195 if (ep.isSingleton()) { 196 return ep.getEndpointKey(); 197 } else { 198 // non singleton then add hashcoded id 199 String uri = ep.getEndpointKey(); 200 int pos = uri.indexOf('?'); 201 String id = (pos == -1) ? uri : uri.substring(0, pos); 202 id += "?id=0x" + Integer.toHexString(ep.hashCode()); 203 return id; 204 } 205 } 206 207 /** 208 * Factory method to create an ObjectName escaping any required characters 209 */ 210 protected ObjectName createObjectName(StringBuffer buffer) throws MalformedObjectNameException { 211 String text = buffer.toString(); 212 try { 213 return new ObjectName(text); 214 } catch (MalformedObjectNameException e) { 215 throw new MalformedObjectNameException("Could not create ObjectName from: " + text + ". Reason: " + e); 216 } 217 } 218 }