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