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