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 */
017package org.apache.camel.management;
018
019import java.net.UnknownHostException;
020import java.util.concurrent.ThreadPoolExecutor;
021
022import javax.management.MalformedObjectNameException;
023import javax.management.ObjectName;
024
025import org.apache.camel.CamelContext;
026import org.apache.camel.CamelContextAware;
027import org.apache.camel.Component;
028import org.apache.camel.Consumer;
029import org.apache.camel.Endpoint;
030import org.apache.camel.ErrorHandlerFactory;
031import org.apache.camel.NamedNode;
032import org.apache.camel.Processor;
033import org.apache.camel.Producer;
034import org.apache.camel.Route;
035import org.apache.camel.Service;
036import org.apache.camel.StaticService;
037import org.apache.camel.builder.ErrorHandlerBuilderRef;
038import org.apache.camel.cluster.CamelClusterService;
039import org.apache.camel.management.mbean.ManagedBacklogDebugger;
040import org.apache.camel.management.mbean.ManagedBacklogTracer;
041import org.apache.camel.management.mbean.ManagedCamelContext;
042import org.apache.camel.management.mbean.ManagedCamelHealth;
043import org.apache.camel.management.mbean.ManagedClusterService;
044import org.apache.camel.management.mbean.ManagedComponent;
045import org.apache.camel.management.mbean.ManagedConsumer;
046import org.apache.camel.management.mbean.ManagedDataFormat;
047import org.apache.camel.management.mbean.ManagedEndpoint;
048import org.apache.camel.management.mbean.ManagedErrorHandler;
049import org.apache.camel.management.mbean.ManagedEventNotifier;
050import org.apache.camel.management.mbean.ManagedProcessor;
051import org.apache.camel.management.mbean.ManagedProducer;
052import org.apache.camel.management.mbean.ManagedRoute;
053import org.apache.camel.management.mbean.ManagedRouteController;
054import org.apache.camel.management.mbean.ManagedService;
055import org.apache.camel.management.mbean.ManagedStep;
056import org.apache.camel.management.mbean.ManagedSupervisingRouteController;
057import org.apache.camel.management.mbean.ManagedThreadPool;
058import org.apache.camel.management.mbean.ManagedTracer;
059import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
060import org.apache.camel.spi.DataFormat;
061import org.apache.camel.spi.EventNotifier;
062import org.apache.camel.spi.ManagementObjectNameStrategy;
063import org.apache.camel.spi.RouteController;
064import org.apache.camel.util.InetAddressUtil;
065import org.apache.camel.util.ObjectHelper;
066import org.apache.camel.util.URISupport;
067
068/**
069 * Naming strategy used when registering MBeans.
070 */
071public class DefaultManagementObjectNameStrategy implements ManagementObjectNameStrategy, CamelContextAware {
072    public static final String VALUE_UNKNOWN = "unknown";
073    public static final String KEY_NAME = "name";
074    public static final String KEY_TYPE = "type";
075    public static final String KEY_CONTEXT = "context";
076    public static final String TYPE_CONTEXT = "context";
077    public static final String TYPE_ROUTE_CONTROLLER = "routecontrollers";
078    public static final String TYPE_HEALTH = "health";
079    public static final String TYPE_ENDPOINT = "endpoints";
080    public static final String TYPE_DATAFORMAT = "dataformats";
081    public static final String TYPE_PROCESSOR = "processors";
082    public static final String TYPE_CONSUMER = "consumers";
083    public static final String TYPE_PRODUCER = "producers";
084    public static final String TYPE_ROUTE = "routes";
085    public static final String TYPE_COMPONENT = "components";
086    public static final String TYPE_STEP = "steps";
087    public static final String TYPE_TRACER = "tracer";
088    public static final String TYPE_EVENT_NOTIFIER = "eventnotifiers";
089    public static final String TYPE_ERRORHANDLER = "errorhandlers";
090    public static final String TYPE_THREAD_POOL = "threadpools";
091    public static final String TYPE_SERVICE = "services";
092    public static final String TYPE_HA = "clusterservices";
093
094    protected String domainName;
095    protected String hostName = "localhost";
096    protected CamelContext camelContext;
097
098    public DefaultManagementObjectNameStrategy() {
099        this(null);
100        // default constructor needed for <bean> style configuration
101    }
102
103    public DefaultManagementObjectNameStrategy(String domainName) {
104        this.domainName = domainName != null ? domainName : "org.apache.camel";
105        try {
106            hostName = InetAddressUtil.getLocalHostName();
107        } catch (UnknownHostException ex) {
108            // ignore, use the default "localhost"
109        }
110    }
111
112    @Override
113    public CamelContext getCamelContext() {
114        return camelContext;
115    }
116
117    @Override
118    public void setCamelContext(CamelContext camelContext) {
119        this.camelContext = camelContext;
120    }
121
122    @Override
123    public ObjectName getObjectName(Object managedObject) throws MalformedObjectNameException {
124        if (managedObject == null) {
125            return null;
126        }
127        ObjectName objectName = null;
128        if (managedObject instanceof ManagedCamelContext) {
129            ManagedCamelContext mcc = (ManagedCamelContext) managedObject;
130            objectName = getObjectNameForCamelContext(mcc.getContext());
131        } else if (managedObject instanceof ManagedCamelHealth) {
132            ManagedCamelHealth mch = (ManagedCamelHealth) managedObject;
133            objectName = getObjectNameForCamelHealth(mch.getContext());
134        } else if (managedObject instanceof ManagedRouteController) {
135            ManagedRouteController mrc = (ManagedRouteController) managedObject;
136            objectName = getObjectNameForRouteController(mrc.getContext(), mrc.getRouteController());
137        } else if (managedObject instanceof ManagedSupervisingRouteController) {
138            ManagedSupervisingRouteController mrc = (ManagedSupervisingRouteController) managedObject;
139            objectName = getObjectNameForRouteController(mrc.getContext(), mrc.getRouteController());
140        } else if (managedObject instanceof ManagedComponent) {
141            ManagedComponent mc = (ManagedComponent) managedObject;
142            objectName = getObjectNameForComponent(mc.getComponent(), mc.getComponentName());
143        } else if (managedObject instanceof ManagedDataFormat) {
144            ManagedDataFormat md = (ManagedDataFormat) managedObject;
145            objectName = getObjectNameForDataFormat(md.getContext(), md.getDataFormat());
146        } else if (managedObject instanceof ManagedEndpoint) {
147            ManagedEndpoint me = (ManagedEndpoint) managedObject;
148            objectName = getObjectNameForEndpoint(me.getEndpoint());
149        } else if (managedObject instanceof Endpoint) {
150            objectName = getObjectNameForEndpoint((Endpoint) managedObject);
151        } else if (managedObject instanceof ManagedRoute) {
152            ManagedRoute mr = (ManagedRoute) managedObject;
153            objectName = getObjectNameForRoute(mr.getRoute());
154        } else if (managedObject instanceof ManagedErrorHandler) {
155            ManagedErrorHandler meh = (ManagedErrorHandler) managedObject;
156            objectName = getObjectNameForErrorHandler(meh.getRoute(), meh.getErrorHandler(), meh.getErrorHandlerBuilder());
157        } else if (managedObject instanceof ManagedStep) {
158            ManagedStep mp = (ManagedStep) managedObject;
159            objectName = getObjectNameForStep(mp.getContext(), mp.getProcessor(), mp.getDefinition());
160        } else if (managedObject instanceof ManagedProcessor) {
161            ManagedProcessor mp = (ManagedProcessor) managedObject;
162            objectName = getObjectNameForProcessor(mp.getContext(), mp.getProcessor(), mp.getDefinition());
163        } else if (managedObject instanceof ManagedConsumer) {
164            ManagedConsumer ms = (ManagedConsumer) managedObject;
165            objectName = getObjectNameForConsumer(ms.getContext(), ms.getConsumer());
166        } else if (managedObject instanceof ManagedProducer) {
167            ManagedProducer ms = (ManagedProducer) managedObject;
168            objectName = getObjectNameForProducer(ms.getContext(), ms.getProducer());
169        } else if (managedObject instanceof ManagedBacklogTracer) {
170            ManagedBacklogTracer mt = (ManagedBacklogTracer) managedObject;
171            objectName = getObjectNameForTracer(mt.getContext(), mt.getBacklogTracer());
172        } else if (managedObject instanceof ManagedBacklogDebugger) {
173            ManagedBacklogDebugger md = (ManagedBacklogDebugger) managedObject;
174            objectName = getObjectNameForTracer(md.getContext(), md.getBacklogDebugger());
175        } else if (managedObject instanceof ManagedEventNotifier) {
176            ManagedEventNotifier men = (ManagedEventNotifier) managedObject;
177            objectName = getObjectNameForEventNotifier(men.getContext(), men.getEventNotifier());
178        } else if (managedObject instanceof ManagedTracer) {
179            ManagedTracer mt = (ManagedTracer) managedObject;
180            objectName = getObjectNameForTracer(mt.getContext(), mt.getTracer());
181        } else if (managedObject instanceof ManagedThreadPool) {
182            ManagedThreadPool mes = (ManagedThreadPool) managedObject;
183            objectName = getObjectNameForThreadPool(mes.getContext(), mes.getThreadPool(), mes.getId(), mes.getSourceId());
184        } else if (managedObject instanceof ManagedClusterService) {
185            ManagedClusterService mcs = (ManagedClusterService) managedObject;
186            objectName = getObjectNameForClusterService(mcs.getContext(), mcs.getService());
187        } else if (managedObject instanceof ManagedService) {
188            // check for managed service should be last
189            ManagedService ms = (ManagedService) managedObject;
190            // skip endpoints as they are already managed
191            if (ms.getService() instanceof Endpoint) {
192                return null;
193            }
194            objectName = getObjectNameForService(ms.getContext(), ms.getService());
195        }
196
197        return objectName;
198    }
199
200    @Override
201    public ObjectName getObjectNameForCamelContext(String managementName, String name) throws MalformedObjectNameException {
202        StringBuilder buffer = new StringBuilder();
203        buffer.append(domainName).append(":");
204        buffer.append(KEY_CONTEXT + "=").append(getContextId(managementName)).append(",");
205        buffer.append(KEY_TYPE + "=" + TYPE_CONTEXT + ",");
206        buffer.append(KEY_NAME + "=").append(ObjectName.quote(name));
207        return createObjectName(buffer);
208    }
209
210    @Override
211    public ObjectName getObjectNameForCamelContext(CamelContext context) throws MalformedObjectNameException {
212        // prefer to use the given management name if previously assigned
213        String managementName = context.getManagementName();
214        if (managementName == null) {
215            managementName = context.getManagementNameStrategy().getName();
216        }
217        String name = context.getName();
218        return getObjectNameForCamelContext(managementName, name);
219    }
220
221    @Override
222    public ObjectName getObjectNameForCamelHealth(CamelContext context) throws MalformedObjectNameException {
223        // prefer to use the given management name if previously assigned
224        String managementName = context.getManagementName();
225        if (managementName == null) {
226            managementName = context.getManagementNameStrategy().getName();
227        }
228
229        StringBuilder buffer = new StringBuilder();
230        buffer.append(domainName).append(":");
231        buffer.append(KEY_CONTEXT + "=").append(getContextId(managementName)).append(",");
232        buffer.append(KEY_TYPE + "=" + TYPE_HEALTH + ",");
233        buffer.append(KEY_NAME + "=").append("DefaultHealthCheck");
234
235        return createObjectName(buffer);
236    }
237
238    @Override
239    public ObjectName getObjectNameForRouteController(CamelContext context, RouteController routeController)
240            throws MalformedObjectNameException {
241        // prefer to use the given management name if previously assigned
242        String managementName = context.getManagementName();
243        if (managementName == null) {
244            managementName = context.getManagementNameStrategy().getName();
245        }
246
247        StringBuilder buffer = new StringBuilder();
248        buffer.append(domainName).append(":");
249        buffer.append(KEY_CONTEXT + "=").append(getContextId(managementName)).append(",");
250        buffer.append(KEY_TYPE + "=" + TYPE_ROUTE_CONTROLLER + ",");
251        buffer.append(KEY_NAME + "=").append(routeController.getClass().getSimpleName());
252
253        return createObjectName(buffer);
254    }
255
256    @Override
257    public ObjectName getObjectNameForEndpoint(Endpoint endpoint) throws MalformedObjectNameException {
258        StringBuilder buffer = new StringBuilder();
259        buffer.append(domainName).append(":");
260        buffer.append(KEY_CONTEXT + "=").append(getContextId(endpoint.getCamelContext())).append(",");
261        buffer.append(KEY_TYPE + "=" + TYPE_ENDPOINT + ",");
262        buffer.append(KEY_NAME + "=").append(ObjectName.quote(getEndpointId(endpoint)));
263        return createObjectName(buffer);
264    }
265
266    @Override
267    public ObjectName getObjectNameForDataFormat(CamelContext context, DataFormat dataFormat)
268            throws MalformedObjectNameException {
269        StringBuilder buffer = new StringBuilder();
270        buffer.append(domainName).append(":");
271        buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
272        buffer.append(KEY_TYPE + "=" + TYPE_DATAFORMAT + ",");
273        buffer.append(KEY_NAME + "=").append(dataFormat.getClass().getSimpleName());
274        if (!(dataFormat instanceof StaticService)) {
275            buffer.append("(").append(ObjectHelper.getIdentityHashCode(dataFormat)).append(")");
276        }
277        return createObjectName(buffer);
278    }
279
280    @Override
281    public ObjectName getObjectNameForComponent(Component component, String name) throws MalformedObjectNameException {
282        StringBuilder buffer = new StringBuilder();
283        buffer.append(domainName).append(":");
284        buffer.append(KEY_CONTEXT + "=").append(getContextId(component.getCamelContext())).append(",");
285        buffer.append(KEY_TYPE + "=" + TYPE_COMPONENT + ",");
286        buffer.append(KEY_NAME + "=").append(ObjectName.quote(name));
287        return createObjectName(buffer);
288    }
289
290    @Override
291    public ObjectName getObjectNameForProcessor(CamelContext context, Processor processor, NamedNode definition)
292            throws MalformedObjectNameException {
293        StringBuilder buffer = new StringBuilder();
294        buffer.append(domainName).append(":");
295        buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
296        buffer.append(KEY_TYPE + "=").append(TYPE_PROCESSOR).append(",");
297        buffer.append(KEY_NAME + "=").append(ObjectName.quote(definition.getId()));
298        return createObjectName(buffer);
299    }
300
301    @Override
302    public ObjectName getObjectNameForStep(CamelContext context, Processor processor, NamedNode definition)
303            throws MalformedObjectNameException {
304        StringBuilder buffer = new StringBuilder();
305        buffer.append(domainName).append(":");
306        buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
307        buffer.append(KEY_TYPE + "=").append(TYPE_STEP).append(",");
308        buffer.append(KEY_NAME + "=").append(ObjectName.quote(definition.getId()));
309        return createObjectName(buffer);
310    }
311
312    @Override
313    public ObjectName getObjectNameForErrorHandler(Route route, Processor errorHandler, ErrorHandlerFactory builder)
314            throws MalformedObjectNameException {
315        StringBuilder buffer = new StringBuilder();
316        buffer.append(domainName).append(":");
317        buffer.append(KEY_CONTEXT + "=").append(getContextId(route.getCamelContext())).append(",");
318        buffer.append(KEY_TYPE + "=").append(TYPE_ERRORHANDLER + ",");
319
320        // we want to only register one instance of the various error handler types and thus do some lookup
321        // if its a ErrorHandlerBuildRef. We need a bit of work to do that as there are potential indirection.
322        String ref = null;
323        if (builder instanceof ErrorHandlerBuilderRef) {
324            ErrorHandlerBuilderRef builderRef = (ErrorHandlerBuilderRef) builder;
325
326            // it has not then its an indirection and we should do some work to lookup the real builder
327            ref = builderRef.getRef();
328            ErrorHandlerFactory refBuilder = ErrorHandlerReifier.lookupErrorHandlerFactory(route, builderRef.getRef(), false);
329            if (refBuilder != null) {
330                builder = refBuilder;
331            }
332
333            // must do a 2nd lookup in case this is also a reference
334            // (this happens with spring DSL using errorHandlerRef on <route> as it gets a bit
335            // complex with indirections for error handler references
336            if (builder instanceof ErrorHandlerBuilderRef) {
337                builderRef = (ErrorHandlerBuilderRef) builder;
338                // does it refer to a non default error handler then do a 2nd lookup
339                if (!builderRef.getRef().equals(ErrorHandlerBuilderRef.DEFAULT_ERROR_HANDLER_BUILDER)) {
340                    refBuilder = ErrorHandlerReifier.lookupErrorHandlerFactory(route, builderRef.getRef(), false);
341                    if (refBuilder != null) {
342                        ref = builderRef.getRef();
343                        builder = refBuilder;
344                    }
345                }
346            }
347        }
348
349        if (ref != null) {
350            String name = builder.getClass().getSimpleName() + "(ref:" + ref + ")";
351            buffer.append(KEY_NAME + "=").append(ObjectName.quote(name));
352        } else {
353            // create a name based on its instance
354            buffer.append(KEY_NAME + "=")
355                    .append(builder.getClass().getSimpleName())
356                    .append("(").append(ObjectHelper.getIdentityHashCode(builder)).append(")");
357        }
358
359        return createObjectName(buffer);
360    }
361
362    @Override
363    public ObjectName getObjectNameForConsumer(CamelContext context, Consumer consumer) throws MalformedObjectNameException {
364        StringBuilder buffer = new StringBuilder();
365        buffer.append(domainName).append(":");
366        buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
367        buffer.append(KEY_TYPE + "=").append(TYPE_CONSUMER).append(",");
368
369        String name = consumer.getClass().getSimpleName();
370        if (ObjectHelper.isEmpty(name)) {
371            name = "Consumer";
372        }
373        buffer.append(KEY_NAME + "=")
374                .append(name)
375                .append("(").append(ObjectHelper.getIdentityHashCode(consumer)).append(")");
376        return createObjectName(buffer);
377    }
378
379    @Override
380    public ObjectName getObjectNameForProducer(CamelContext context, Producer producer) throws MalformedObjectNameException {
381        StringBuilder buffer = new StringBuilder();
382        buffer.append(domainName).append(":");
383        buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
384        buffer.append(KEY_TYPE + "=").append(TYPE_PRODUCER).append(",");
385
386        String name = producer.getClass().getSimpleName();
387        if (ObjectHelper.isEmpty(name)) {
388            name = "Producer";
389        }
390        buffer.append(KEY_NAME + "=")
391                .append(name)
392                .append("(").append(ObjectHelper.getIdentityHashCode(producer)).append(")");
393        return createObjectName(buffer);
394    }
395
396    @Override
397    public ObjectName getObjectNameForTracer(CamelContext context, Service tracer) throws MalformedObjectNameException {
398        // use the simple name of the class as the mbean name (eg Tracer, BacklogTracer, BacklogDebugger)
399        String name = tracer.getClass().getSimpleName();
400
401        StringBuilder buffer = new StringBuilder();
402        buffer.append(domainName).append(":");
403        buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
404        buffer.append(KEY_TYPE + "=" + TYPE_TRACER + ",");
405        buffer.append(KEY_NAME + "=").append(name);
406        return createObjectName(buffer);
407    }
408
409    @Override
410    public ObjectName getObjectNameForEventNotifier(CamelContext context, EventNotifier eventNotifier)
411            throws MalformedObjectNameException {
412        StringBuilder buffer = new StringBuilder();
413        buffer.append(domainName).append(":");
414        buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
415        buffer.append(KEY_TYPE + "=" + TYPE_EVENT_NOTIFIER + ",");
416
417        if (eventNotifier instanceof JmxNotificationEventNotifier) {
418            // JMX notifier shall have an easy to use name
419            buffer.append(KEY_NAME + "=").append("JmxEventNotifier");
420        } else {
421            // others can be per instance
422            buffer.append(KEY_NAME + "=")
423                    .append("EventNotifier")
424                    .append("(").append(ObjectHelper.getIdentityHashCode(eventNotifier)).append(")");
425        }
426        return createObjectName(buffer);
427    }
428
429    @Override
430    public ObjectName getObjectNameForRoute(org.apache.camel.Route route) throws MalformedObjectNameException {
431        Endpoint ep = route.getEndpoint();
432        String id = route.getId();
433
434        StringBuilder buffer = new StringBuilder();
435        buffer.append(domainName).append(":");
436        buffer.append(KEY_CONTEXT + "=").append(getContextId(ep.getCamelContext())).append(",");
437        buffer.append(KEY_TYPE + "=" + TYPE_ROUTE + ",");
438        buffer.append(KEY_NAME + "=").append(ObjectName.quote(id));
439        return createObjectName(buffer);
440    }
441
442    @Override
443    public ObjectName getObjectNameForService(CamelContext context, Service service) throws MalformedObjectNameException {
444        StringBuilder buffer = new StringBuilder();
445        buffer.append(domainName).append(":");
446        buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
447        buffer.append(KEY_TYPE + "=" + TYPE_SERVICE + ",");
448        buffer.append(KEY_NAME + "=").append(service.getClass().getSimpleName());
449        if (!(service instanceof StaticService)) {
450            buffer.append("(").append(ObjectHelper.getIdentityHashCode(service)).append(")");
451        }
452        return createObjectName(buffer);
453    }
454
455    @Override
456    public ObjectName getObjectNameForClusterService(CamelContext context, CamelClusterService service)
457            throws MalformedObjectNameException {
458        StringBuilder buffer = new StringBuilder();
459        buffer.append(domainName).append(":");
460        buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
461        buffer.append(KEY_TYPE + "=" + TYPE_HA + ",");
462        buffer.append(KEY_NAME + "=").append(service.getClass().getSimpleName());
463        if (!(service instanceof StaticService)) {
464            buffer.append("(").append(ObjectHelper.getIdentityHashCode(service)).append(")");
465        }
466        return createObjectName(buffer);
467    }
468
469    @Override
470    public ObjectName getObjectNameForThreadPool(
471            CamelContext context, ThreadPoolExecutor threadPool, String id, String sourceId)
472            throws MalformedObjectNameException {
473        StringBuilder buffer = new StringBuilder();
474        buffer.append(domainName).append(":");
475        buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
476        buffer.append(KEY_TYPE + "=" + TYPE_THREAD_POOL + ",");
477
478        String name = id;
479        if (sourceId != null) {
480            // provide source id if we know it, this helps end user to know where the pool is used
481            name = name + "(" + sourceId + ")";
482        }
483        buffer.append(KEY_NAME + "=").append(ObjectName.quote(name));
484        return createObjectName(buffer);
485    }
486
487    public String getDomainName() {
488        return domainName;
489    }
490
491    public void setDomainName(String domainName) {
492        this.domainName = domainName;
493    }
494
495    public String getHostName() {
496        return hostName;
497    }
498
499    public void setHostName(String hostName) {
500        this.hostName = hostName;
501    }
502
503    protected String getContextId(CamelContext context) {
504        if (context == null) {
505            return getContextId(VALUE_UNKNOWN);
506        } else {
507            String name = context.getManagementName() != null ? context.getManagementName() : context.getName();
508            return getContextId(name);
509        }
510    }
511
512    protected String getContextId(String name) {
513        boolean includeHostName
514                = camelContext != null && camelContext.getManagementStrategy().getManagementAgent().getIncludeHostName();
515        if (includeHostName) {
516            return hostName + "/" + (name != null ? name : VALUE_UNKNOWN);
517        } else {
518            return name != null ? name : VALUE_UNKNOWN;
519        }
520    }
521
522    protected String getEndpointId(Endpoint ep) {
523        String answer = doGetEndpointId(ep);
524        boolean sanitize = camelContext != null && camelContext.getManagementStrategy().getManagementAgent().getMask();
525        if (sanitize) {
526            // use xxxxxx as replacements as * has to be quoted for MBean names
527            answer = URISupport.sanitizeUri(answer);
528        }
529        return answer;
530    }
531
532    private String doGetEndpointId(Endpoint ep) {
533        if (ep.isSingleton()) {
534            return ep.getEndpointKey();
535        } else {
536            // non singleton then add hashcoded id
537            String uri = ep.getEndpointKey();
538            int pos = uri.indexOf('?');
539            String id = (pos == -1) ? uri : uri.substring(0, pos);
540            id += "?id=" + ObjectHelper.getIdentityHashCode(ep);
541            return id;
542        }
543    }
544
545    /**
546     * Factory method to create an ObjectName escaping any required characters
547     */
548    protected ObjectName createObjectName(StringBuilder buffer) throws MalformedObjectNameException {
549        String text = buffer.toString();
550        try {
551            return new ObjectName(text);
552        } catch (MalformedObjectNameException e) {
553            throw new MalformedObjectNameException("Could not create ObjectName from: " + text + ". Reason: " + e);
554        }
555    }
556}