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 }