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 import javax.management.MalformedObjectNameException;
022 import javax.management.ObjectName;
023
024 import org.apache.camel.CamelContext;
025 import org.apache.camel.Component;
026 import org.apache.camel.Consumer;
027 import org.apache.camel.Endpoint;
028 import org.apache.camel.Processor;
029 import org.apache.camel.Producer;
030 import org.apache.camel.Route;
031 import org.apache.camel.Service;
032 import org.apache.camel.builder.ErrorHandlerBuilder;
033 import org.apache.camel.builder.ErrorHandlerBuilderRef;
034 import org.apache.camel.model.ProcessorDefinition;
035 import org.apache.camel.spi.InterceptStrategy;
036 import org.apache.camel.spi.ManagementNamingStrategy;
037 import org.apache.camel.spi.RouteContext;
038 import org.apache.camel.util.ObjectHelper;
039
040 /**
041 * Naming strategy used when registering MBeans.
042 */
043 public class DefaultManagementNamingStrategy implements ManagementNamingStrategy {
044 public static final String VALUE_UNKNOWN = "unknown";
045 public static final String KEY_NAME = "name";
046 public static final String KEY_TYPE = "type";
047 public static final String KEY_CONTEXT = "context";
048 public static final String TYPE_CONTEXT = "context";
049 public static final String TYPE_ENDPOINT = "endpoints";
050 public static final String TYPE_PROCESSOR = "processors";
051 public static final String TYPE_CONSUMER = "consumers";
052 public static final String TYPE_PRODUCER = "producers";
053 public static final String TYPE_ROUTE = "routes";
054 public static final String TYPE_COMPONENT = "components";
055 public static final String TYPE_TRACER = "tracer";
056 public static final String TYPE_ERRORHANDLER = "errorhandlers";
057 public static final String TYPE_SERVICE = "services";
058
059 protected String domainName;
060 protected String hostName = "localhost";
061
062 public DefaultManagementNamingStrategy() {
063 this("org.apache.camel");
064 }
065
066 public DefaultManagementNamingStrategy(String domainName) {
067 if (domainName != null) {
068 this.domainName = domainName;
069 }
070 try {
071 hostName = InetAddress.getLocalHost().getHostName();
072 } catch (UnknownHostException ex) {
073 // ignore, use the default "localhost"
074 }
075 }
076
077 public ObjectName getObjectNameForCamelContext(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_TYPE + "=" + TYPE_CONTEXT + ",");
082 buffer.append(KEY_NAME + "=").append(ObjectName.quote(context.getName()));
083 return createObjectName(buffer);
084 }
085
086 public ObjectName getObjectNameForEndpoint(Endpoint endpoint) throws MalformedObjectNameException {
087 StringBuffer buffer = new StringBuffer();
088 buffer.append(domainName).append(":");
089 buffer.append(KEY_CONTEXT + "=").append(getContextId(endpoint.getCamelContext())).append(",");
090 buffer.append(KEY_TYPE + "=" + TYPE_ENDPOINT + ",");
091 buffer.append(KEY_NAME + "=").append(ObjectName.quote(getEndpointId(endpoint)));
092 return createObjectName(buffer);
093 }
094
095 public ObjectName getObjectNameForComponent(Component component, String name) throws MalformedObjectNameException {
096 StringBuffer buffer = new StringBuffer();
097 buffer.append(domainName).append(":");
098 buffer.append(KEY_CONTEXT + "=").append(getContextId(component.getCamelContext())).append(",");
099 buffer.append(KEY_TYPE + "=" + TYPE_COMPONENT + ",");
100 buffer.append(KEY_NAME + "=").append(ObjectName.quote(name));
101 return createObjectName(buffer);
102 }
103
104 public ObjectName getObjectNameForProcessor(CamelContext context, Processor processor, ProcessorDefinition<?> definition) throws MalformedObjectNameException {
105 StringBuffer buffer = new StringBuffer();
106 buffer.append(domainName).append(":");
107 buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
108 buffer.append(KEY_TYPE + "=").append(TYPE_PROCESSOR).append(",");
109
110 if (definition.hasCustomIdAssigned()) {
111 // use id in name
112 String nodeId = definition.getId();
113 buffer.append(KEY_NAME + "=").append(ObjectName.quote(nodeId));
114 } else {
115 // create a name based on its instance
116 buffer.append(KEY_NAME + "=")
117 .append(processor.getClass().getSimpleName())
118 .append("(").append(ObjectHelper.getIdentityHashCode(processor)).append(")");
119 }
120 return createObjectName(buffer);
121 }
122
123 public ObjectName getObjectNameForErrorHandler(RouteContext routeContext, Processor errorHandler, ErrorHandlerBuilder builder) throws MalformedObjectNameException {
124 StringBuffer buffer = new StringBuffer();
125 buffer.append(domainName).append(":");
126 buffer.append(KEY_CONTEXT + "=").append(getContextId(routeContext.getCamelContext())).append(",");
127 buffer.append(KEY_TYPE + "=").append(TYPE_ERRORHANDLER).append(",");
128
129 // we want to only register one instance of the various error handler types and thus do some lookup
130 // if its a ErrorHandlerBuildRef. We need a bit of work to do that as there are potential indirection.
131 String ref = null;
132 if (builder instanceof ErrorHandlerBuilderRef) {
133 ErrorHandlerBuilderRef builderRef = (ErrorHandlerBuilderRef) builder;
134
135 // it has not then its an indirection and we should do some work to lookup the real builder
136 ref = builderRef.getRef();
137 builder = ErrorHandlerBuilderRef.lookupErrorHandlerBuilder(routeContext, builderRef.getRef());
138
139 // must do a 2nd lookup in case this is also a reference
140 // (this happens with spring DSL using errorHandlerRef on <route> as it gets a bit
141 // complex with indirections for error handler references
142 if (builder instanceof ErrorHandlerBuilderRef) {
143 builderRef = (ErrorHandlerBuilderRef) builder;
144 // does it refer to a non default error handler then do a 2nd lookup
145 if (!builderRef.getRef().equals(ErrorHandlerBuilderRef.DEFAULT_ERROR_HANDLER_BUILDER)) {
146 builder = ErrorHandlerBuilderRef.lookupErrorHandlerBuilder(routeContext, builderRef.getRef());
147 ref = builderRef.getRef();
148 }
149 }
150 }
151
152 if (ref != null) {
153 String name = builder.getClass().getSimpleName() + "(ref:" + ref + ")";
154 buffer.append(KEY_NAME + "=").append(ObjectName.quote(name));
155 } else {
156 // create a name based on its instance
157 buffer.append(KEY_NAME + "=")
158 .append(builder.getClass().getSimpleName())
159 .append("(").append(ObjectHelper.getIdentityHashCode(builder)).append(")");
160 }
161
162 return createObjectName(buffer);
163 }
164
165 public ObjectName getObjectNameForConsumer(CamelContext context, Consumer consumer) throws MalformedObjectNameException {
166 StringBuffer buffer = new StringBuffer();
167 buffer.append(domainName).append(":");
168 buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
169 buffer.append(KEY_TYPE + "=").append(TYPE_CONSUMER).append(",");
170
171 String name = consumer.getClass().getSimpleName();
172 if (ObjectHelper.isEmpty(name)) {
173 name = "Consumer";
174 }
175 buffer.append(KEY_NAME + "=")
176 .append(name)
177 .append("(").append(ObjectHelper.getIdentityHashCode(consumer)).append(")");
178 return createObjectName(buffer);
179 }
180
181 public ObjectName getObjectNameForProducer(CamelContext context, Producer producer) throws MalformedObjectNameException {
182 StringBuffer buffer = new StringBuffer();
183 buffer.append(domainName).append(":");
184 buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
185 buffer.append(KEY_TYPE + "=").append(TYPE_PRODUCER).append(",");
186
187 String name = producer.getClass().getSimpleName();
188 if (ObjectHelper.isEmpty(name)) {
189 name = "Producer";
190 }
191 buffer.append(KEY_NAME + "=")
192 .append(name)
193 .append("(").append(ObjectHelper.getIdentityHashCode(producer)).append(")");
194 return createObjectName(buffer);
195 }
196
197 public ObjectName getObjectNameForTracer(CamelContext context, InterceptStrategy tracer) throws MalformedObjectNameException {
198 StringBuffer buffer = new StringBuffer();
199 buffer.append(domainName).append(":");
200 buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
201 buffer.append(KEY_TYPE + "=" + TYPE_TRACER + ",");
202 buffer.append(KEY_NAME + "=")
203 .append("Tracer")
204 .append("(").append(ObjectHelper.getIdentityHashCode(tracer)).append(")");
205 return createObjectName(buffer);
206 }
207
208 public ObjectName getObjectNameForRoute(Route route) throws MalformedObjectNameException {
209 Endpoint ep = route.getEndpoint();
210 String id = route.getId();
211
212 StringBuffer buffer = new StringBuffer();
213 buffer.append(domainName).append(":");
214 buffer.append(KEY_CONTEXT + "=").append(getContextId(ep.getCamelContext())).append(",");
215 buffer.append(KEY_TYPE + "=" + TYPE_ROUTE + ",");
216 buffer.append(KEY_NAME + "=").append(ObjectName.quote(id));
217 return createObjectName(buffer);
218 }
219
220 public ObjectName getObjectNameForService(CamelContext context, Service service) throws MalformedObjectNameException {
221 StringBuffer buffer = new StringBuffer();
222 buffer.append(domainName).append(":");
223 buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
224 buffer.append(KEY_TYPE + "=" + TYPE_SERVICE + ",");
225 buffer.append(KEY_NAME + "=")
226 .append(service.getClass().getSimpleName())
227 .append("(").append(ObjectHelper.getIdentityHashCode(service)).append(")");
228 return createObjectName(buffer);
229 }
230
231 public String getDomainName() {
232 return domainName;
233 }
234
235 public void setDomainName(String domainName) {
236 this.domainName = domainName;
237 }
238
239 public String getHostName() {
240 return hostName;
241 }
242
243 public void setHostName(String hostName) {
244 this.hostName = hostName;
245 }
246
247 protected String getContextId(CamelContext context) {
248 return hostName + "/" + (context != null ? context.getName() : VALUE_UNKNOWN);
249 }
250
251 protected String getEndpointId(Endpoint ep) {
252 if (ep.isSingleton()) {
253 return ep.getEndpointKey();
254 } else {
255 // non singleton then add hashcoded id
256 String uri = ep.getEndpointKey();
257 int pos = uri.indexOf('?');
258 String id = (pos == -1) ? uri : uri.substring(0, pos);
259 id += "?id=" + ObjectHelper.getIdentityHashCode(ep);
260 return id;
261 }
262 }
263
264 /**
265 * Factory method to create an ObjectName escaping any required characters
266 */
267 protected ObjectName createObjectName(StringBuffer buffer) throws MalformedObjectNameException {
268 String text = buffer.toString();
269 try {
270 return new ObjectName(text);
271 } catch (MalformedObjectNameException e) {
272 throw new MalformedObjectNameException("Could not create ObjectName from: " + text + ". Reason: " + e);
273 }
274 }
275 }