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.mbean;
018
019import java.io.ByteArrayInputStream;
020import java.util.ArrayList;
021import java.util.Collection;
022import java.util.Comparator;
023import java.util.List;
024import java.util.Map;
025import java.util.Set;
026import java.util.concurrent.TimeUnit;
027
028import javax.management.MBeanServer;
029import javax.management.ObjectName;
030
031import org.w3c.dom.Document;
032
033import org.apache.camel.CamelContext;
034import org.apache.camel.Endpoint;
035import org.apache.camel.Exchange;
036import org.apache.camel.ManagementStatisticsLevel;
037import org.apache.camel.Producer;
038import org.apache.camel.ProducerTemplate;
039import org.apache.camel.Route;
040import org.apache.camel.TimerListener;
041import org.apache.camel.api.management.ManagedResource;
042import org.apache.camel.api.management.mbean.ManagedCamelContextMBean;
043import org.apache.camel.api.management.mbean.ManagedProcessorMBean;
044import org.apache.camel.api.management.mbean.ManagedRouteMBean;
045import org.apache.camel.api.management.mbean.ManagedStepMBean;
046import org.apache.camel.model.Model;
047import org.apache.camel.model.RouteDefinition;
048import org.apache.camel.model.RouteTemplateDefinition;
049import org.apache.camel.model.RouteTemplatesDefinition;
050import org.apache.camel.model.RoutesDefinition;
051import org.apache.camel.model.rest.RestDefinition;
052import org.apache.camel.model.rest.RestsDefinition;
053import org.apache.camel.spi.ManagementStrategy;
054import org.apache.camel.spi.UnitOfWork;
055import org.apache.camel.support.PluginHelper;
056
057@ManagedResource(description = "Managed CamelContext")
058public class ManagedCamelContext extends ManagedPerformanceCounter implements TimerListener, ManagedCamelContextMBean {
059
060    private final CamelContext context;
061    private final LoadTriplet load = new LoadTriplet();
062    private final LoadThroughput thp = new LoadThroughput();
063    private final String jmxDomain;
064
065    public ManagedCamelContext(CamelContext context) {
066        this.context = context;
067        this.jmxDomain = context.getManagementStrategy().getManagementAgent().getMBeanObjectDomainName();
068    }
069
070    @Override
071    public void init(ManagementStrategy strategy) {
072        super.init(strategy);
073        boolean enabled = context.getManagementStrategy().getManagementAgent() != null
074                && context.getManagementStrategy().getManagementAgent().getStatisticsLevel() != ManagementStatisticsLevel.Off;
075        setStatisticsEnabled(enabled);
076    }
077
078    @Override
079    public void completedExchange(Exchange exchange, long time) {
080        // the camel-context mbean is triggered for every route mbean
081        // so we must only trigger on the root level, otherwise the context mbean
082        // total counter will be incorrect. For example if an exchange is routed via 3 routes
083        // we should only count this as 1 instead of 3.
084        UnitOfWork uow = exchange.getUnitOfWork();
085        if (uow != null) {
086            int level = uow.routeStackLevel();
087            if (level <= 1) {
088                super.completedExchange(exchange, time);
089            }
090        } else {
091            super.completedExchange(exchange, time);
092        }
093    }
094
095    @Override
096    public void failedExchange(Exchange exchange) {
097        // the camel-context mbean is triggered for every route mbean
098        // so we must only trigger on the root level, otherwise the context mbean
099        // total counter will be incorrect. For example if an exchange is routed via 3 routes
100        // we should only count this as 1 instead of 3.
101        UnitOfWork uow = exchange.getUnitOfWork();
102        if (uow != null) {
103            int level = uow.routeStackLevel();
104            if (level <= 1) {
105                super.failedExchange(exchange);
106            }
107        } else {
108            super.failedExchange(exchange);
109        }
110    }
111
112    @Override
113    public void processExchange(Exchange exchange, String type) {
114        // the camel-context mbean is triggered for every route mbean
115        // so we must only trigger on the root level, otherwise the context mbean
116        // total counter will be incorrect. For example if an exchange is routed via 3 routes
117        // we should only count this as 1 instead of 3.
118        UnitOfWork uow = exchange.getUnitOfWork();
119        if (uow != null) {
120            int level = uow.routeStackLevel();
121            if (level <= 1) {
122                super.processExchange(exchange, type);
123            }
124        } else {
125            super.processExchange(exchange, type);
126        }
127    }
128
129    public CamelContext getContext() {
130        return context;
131    }
132
133    @Override
134    public String getCamelId() {
135        return context.getName();
136    }
137
138    @Override
139    public String getCamelDescription() {
140        return context.getDescription();
141    }
142
143    @Override
144    public String getManagementName() {
145        return context.getManagementName();
146    }
147
148    @Override
149    public String getCamelVersion() {
150        return context.getVersion();
151    }
152
153    @Override
154    public String getState() {
155        return context.getStatus().name();
156    }
157
158    @Override
159    public String getUptime() {
160        return context.getUptime();
161    }
162
163    @Override
164    public long getUptimeMillis() {
165        return context.getUptimeMillis();
166    }
167
168    @Override
169    public String getManagementStatisticsLevel() {
170        if (context.getManagementStrategy().getManagementAgent() != null) {
171            return context.getManagementStrategy().getManagementAgent().getStatisticsLevel().name();
172        } else {
173            return null;
174        }
175    }
176
177    @Override
178    public String getClassResolver() {
179        return context.getClassResolver().getClass().getName();
180    }
181
182    @Override
183    public String getPackageScanClassResolver() {
184        return PluginHelper.getPackageScanClassResolver(context).getClass().getName();
185    }
186
187    @Override
188    public String getApplicationContextClassName() {
189        if (context.getApplicationContextClassLoader() != null) {
190            return context.getApplicationContextClassLoader().getClass().getName();
191        } else {
192            return null;
193        }
194    }
195
196    @Override
197    public String getHeadersMapFactoryClassName() {
198        return context.getCamelContextExtension().getHeadersMapFactory().getClass().getName();
199    }
200
201    @Override
202    public Map<String, String> getGlobalOptions() {
203        if (context.getGlobalOptions().isEmpty()) {
204            return null;
205        }
206        return context.getGlobalOptions();
207    }
208
209    @Override
210    public String getGlobalOption(String key) throws Exception {
211        return context.getGlobalOption(key);
212    }
213
214    @Override
215    public void setGlobalOption(String key, String value) throws Exception {
216        context.getGlobalOptions().put(key, value);
217    }
218
219    @Override
220    public Boolean getTracing() {
221        return context.isTracing();
222    }
223
224    @Override
225    public void setTracing(Boolean tracing) {
226        context.setTracing(tracing);
227    }
228
229    public Integer getInflightExchanges() {
230        return (int) super.getExchangesInflight();
231    }
232
233    @Override
234    public Integer getTotalRoutes() {
235        return context.getRoutesSize();
236    }
237
238    @Override
239    public Integer getStartedRoutes() {
240        int started = 0;
241        for (Route route : context.getRoutes()) {
242            if (context.getRouteController().getRouteStatus(route.getId()).isStarted()) {
243                started++;
244            }
245        }
246        return started;
247    }
248
249    @Override
250    public void setTimeout(long timeout) {
251        context.getShutdownStrategy().setTimeout(timeout);
252    }
253
254    @Override
255    public long getTimeout() {
256        return context.getShutdownStrategy().getTimeout();
257    }
258
259    @Override
260    public void setTimeUnit(TimeUnit timeUnit) {
261        context.getShutdownStrategy().setTimeUnit(timeUnit);
262    }
263
264    @Override
265    public TimeUnit getTimeUnit() {
266        return context.getShutdownStrategy().getTimeUnit();
267    }
268
269    @Override
270    public void setShutdownNowOnTimeout(boolean shutdownNowOnTimeout) {
271        context.getShutdownStrategy().setShutdownNowOnTimeout(shutdownNowOnTimeout);
272    }
273
274    @Override
275    public boolean isShutdownNowOnTimeout() {
276        return context.getShutdownStrategy().isShutdownNowOnTimeout();
277    }
278
279    @Override
280    public String getLoad01() {
281        double load1 = load.getLoad1();
282        if (Double.isNaN(load1)) {
283            // empty string if load statistics is disabled
284            return "";
285        } else {
286            return String.format("%.2f", load1);
287        }
288    }
289
290    @Override
291    public String getLoad05() {
292        double load5 = load.getLoad5();
293        if (Double.isNaN(load5)) {
294            // empty string if load statistics is disabled
295            return "";
296        } else {
297            return String.format("%.2f", load5);
298        }
299    }
300
301    @Override
302    public String getLoad15() {
303        double load15 = load.getLoad15();
304        if (Double.isNaN(load15)) {
305            // empty string if load statistics is disabled
306            return "";
307        } else {
308            return String.format("%.2f", load15);
309        }
310    }
311
312    @Override
313    public String getThroughput() {
314        double d = thp.getThroughput();
315        if (Double.isNaN(d)) {
316            // empty string if load statistics is disabled
317            return "";
318        } else {
319            return String.format("%.2f", d);
320        }
321    }
322
323    @Override
324    public boolean isUseBreadcrumb() {
325        return context.isUseBreadcrumb();
326    }
327
328    @Override
329    public boolean isAllowUseOriginalMessage() {
330        return context.isAllowUseOriginalMessage();
331    }
332
333    @Override
334    public boolean isMessageHistory() {
335        return context.isMessageHistory() != null ? context.isMessageHistory() : false;
336    }
337
338    @Override
339    public boolean isLogMask() {
340        return context.isLogMask() != null ? context.isLogMask() : false;
341    }
342
343    @Override
344    public boolean isUseMDCLogging() {
345        return context.isUseMDCLogging();
346    }
347
348    @Override
349    public boolean isUseDataType() {
350        return context.isUseDataType();
351    }
352
353    @Override
354    public void onTimer() {
355        load.update(getInflightExchanges());
356        thp.update(getExchangesTotal());
357    }
358
359    @Override
360    public void start() throws Exception {
361        if (context.isSuspended()) {
362            context.resume();
363        } else {
364            context.start();
365        }
366    }
367
368    @Override
369    public void stop() throws Exception {
370        context.stop();
371    }
372
373    @Override
374    public void restart() throws Exception {
375        context.stop();
376        context.start();
377    }
378
379    @Override
380    public void suspend() throws Exception {
381        context.suspend();
382    }
383
384    @Override
385    public void resume() throws Exception {
386        if (context.isSuspended()) {
387            context.resume();
388        } else {
389            throw new IllegalStateException("CamelContext is not suspended");
390        }
391    }
392
393    @Override
394    public void startAllRoutes() throws Exception {
395        context.getRouteController().startAllRoutes();
396    }
397
398    @Override
399    public boolean canSendToEndpoint(String endpointUri) {
400        try {
401            Endpoint endpoint = context.getEndpoint(endpointUri);
402            if (endpoint != null) {
403                try (Producer producer = endpoint.createProducer()) {
404                    return producer != null;
405                }
406            }
407        } catch (Exception e) {
408            // ignore
409        }
410
411        return false;
412    }
413
414    @Override
415    public void sendBody(String endpointUri, Object body) throws Exception {
416        try (ProducerTemplate template = context.createProducerTemplate()) {
417            template.sendBody(endpointUri, body);
418        }
419    }
420
421    @Override
422    public void sendStringBody(String endpointUri, String body) throws Exception {
423        sendBody(endpointUri, body);
424    }
425
426    @Override
427    public void sendBodyAndHeaders(String endpointUri, Object body, Map<String, Object> headers) throws Exception {
428        try (ProducerTemplate template = context.createProducerTemplate()) {
429            template.sendBodyAndHeaders(endpointUri, body, headers);
430        }
431    }
432
433    @Override
434    public Object requestBody(String endpointUri, Object body) throws Exception {
435        try (ProducerTemplate template = context.createProducerTemplate()) {
436            return template.requestBody(endpointUri, body);
437        }
438    }
439
440    @Override
441    public Object requestStringBody(String endpointUri, String body) throws Exception {
442        return requestBody(endpointUri, body);
443    }
444
445    @Override
446    public Object requestBodyAndHeaders(String endpointUri, Object body, Map<String, Object> headers) throws Exception {
447        try (ProducerTemplate template = context.createProducerTemplate()) {
448            return template.requestBodyAndHeaders(endpointUri, body, headers);
449        }
450    }
451
452    @Override
453    public String dumpRestsAsXml() throws Exception {
454        return dumpRestsAsXml(false);
455    }
456
457    @Override
458    public String dumpRestsAsXml(boolean resolvePlaceholders) throws Exception {
459        List<RestDefinition> rests = context.getCamelContextExtension().getContextPlugin(Model.class).getRestDefinitions();
460        if (rests.isEmpty()) {
461            return null;
462        }
463
464        RestsDefinition def = new RestsDefinition();
465        def.setRests(rests);
466
467        return PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, resolvePlaceholders, true);
468    }
469
470    @Override
471    public String dumpRoutesAsXml() throws Exception {
472        return dumpRoutesAsXml(false, true);
473    }
474
475    @Override
476    public String dumpRoutesAsXml(boolean resolvePlaceholders) throws Exception {
477        return dumpRoutesAsXml(resolvePlaceholders, true);
478    }
479
480    @Override
481    public String dumpRoutesAsXml(boolean resolvePlaceholders, boolean generatedIds) throws Exception {
482        List<RouteDefinition> routes = context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinitions();
483        if (routes.isEmpty()) {
484            return null;
485        }
486
487        // use routes definition to dump the routes
488        RoutesDefinition def = new RoutesDefinition();
489        def.setRoutes(routes);
490
491        // if we are debugging then ids is needed for the debugger
492        if (context.isDebugging()) {
493            generatedIds = true;
494        }
495        return PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, resolvePlaceholders, generatedIds);
496    }
497
498    @Override
499    public String dumpRoutesAsYaml() throws Exception {
500        return dumpRoutesAsYaml(false, false);
501    }
502
503    @Override
504    public String dumpRoutesAsYaml(boolean resolvePlaceholders) throws Exception {
505        return dumpRoutesAsYaml(resolvePlaceholders, false, true);
506    }
507
508    @Override
509    public String dumpRoutesAsYaml(boolean resolvePlaceholders, boolean uriAsParameters) throws Exception {
510        return dumpRoutesAsYaml(resolvePlaceholders, uriAsParameters, true);
511    }
512
513    @Override
514    public String dumpRoutesAsYaml(boolean resolvePlaceholders, boolean uriAsParameters, boolean generatedIds)
515            throws Exception {
516        List<RouteDefinition> routes = context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinitions();
517        if (routes.isEmpty()) {
518            return null;
519        }
520
521        // use routes definition to dump the routes
522        RoutesDefinition def = new RoutesDefinition();
523        def.setRoutes(routes);
524
525        // if we are debugging then ids is needed for the debugger
526        if (context.isDebugging()) {
527            generatedIds = true;
528        }
529
530        return PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, def, resolvePlaceholders, uriAsParameters,
531                generatedIds);
532    }
533
534    @Override
535    public String dumpRouteTemplatesAsXml() throws Exception {
536        List<RouteTemplateDefinition> templates
537                = context.getCamelContextExtension().getContextPlugin(Model.class).getRouteTemplateDefinitions();
538        if (templates.isEmpty()) {
539            return null;
540        }
541
542        // use a route templates definition to dump the templates
543        RouteTemplatesDefinition def = new RouteTemplatesDefinition();
544        def.setRouteTemplates(templates);
545
546        return PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def);
547    }
548
549    @Override
550    public String dumpRoutesStatsAsXml(boolean fullStats, boolean includeProcessors) throws Exception {
551        StringBuilder sb = new StringBuilder();
552        sb.append("<camelContextStat").append(String.format(" id=\"%s\" state=\"%s\"", getCamelId(), getState()));
553        // use substring as we only want the attributes
554        String stat = dumpStatsAsXml(fullStats);
555        sb.append(" exchangesInflight=\"").append(getInflightExchanges()).append("\"");
556        sb.append(" ").append(stat, 7, stat.length() - 2).append(">\n");
557
558        MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer();
559        if (server != null) {
560            // gather all the routes for this CamelContext, which requires JMX
561            String prefix = getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() ? "*/" : "";
562            ObjectName query = ObjectName
563                    .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=routes,*");
564            Set<ObjectName> routes = server.queryNames(query, null);
565
566            List<ManagedProcessorMBean> processors = new ArrayList<>();
567            if (includeProcessors) {
568                // gather all the processors for this CamelContext, which requires JMX
569                query = ObjectName.getInstance(
570                        jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=processors,*");
571                Set<ObjectName> names = server.queryNames(query, null);
572                for (ObjectName on : names) {
573                    ManagedProcessorMBean processor = context.getManagementStrategy().getManagementAgent().newProxyClient(on,
574                            ManagedProcessorMBean.class);
575                    processors.add(processor);
576                }
577            }
578            processors.sort(new OrderProcessorMBeans());
579
580            // loop the routes, and append the processor stats if needed
581            sb.append("  <routeStats>\n");
582            for (ObjectName on : routes) {
583                ManagedRouteMBean route
584                        = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedRouteMBean.class);
585                sb.append("    <routeStat")
586                        .append(String.format(" id=\"%s\" state=\"%s\"", route.getRouteId(), route.getState()));
587                if (route.getSourceLocation() != null) {
588                    sb.append(String.format(" sourceLocation=\"%s\"", route.getSourceLocation()));
589                }
590
591                // use substring as we only want the attributes
592                stat = route.dumpStatsAsXml(fullStats);
593                sb.append(" exchangesInflight=\"").append(route.getExchangesInflight()).append("\"");
594                sb.append(" ").append(stat, 7, stat.length() - 2).append(">\n");
595
596                // add processor details if needed
597                if (includeProcessors) {
598                    sb.append("      <processorStats>\n");
599                    for (ManagedProcessorMBean processor : processors) {
600                        int line = processor.getSourceLineNumber() != null ? processor.getSourceLineNumber() : -1;
601                        // the processor must belong to this route
602                        if (route.getRouteId().equals(processor.getRouteId())) {
603                            sb.append("        <processorStat")
604                                    .append(String.format(" id=\"%s\" index=\"%s\" state=\"%s\" sourceLineNumber=\"%s\"",
605                                            processor.getProcessorId(), processor.getIndex(), processor.getState(), line));
606                            // use substring as we only want the attributes
607                            stat = processor.dumpStatsAsXml(fullStats);
608                            sb.append(" exchangesInflight=\"").append(processor.getExchangesInflight()).append("\"");
609                            sb.append(" ").append(stat, 7, stat.length()).append("\n");
610                        }
611                    }
612                    sb.append("      </processorStats>\n");
613                }
614                sb.append("    </routeStat>\n");
615            }
616            sb.append("  </routeStats>\n");
617        }
618
619        sb.append("</camelContextStat>");
620        return sb.toString();
621    }
622
623    @Override
624    public String dumpStepStatsAsXml(boolean fullStats) throws Exception {
625        StringBuilder sb = new StringBuilder();
626        sb.append("<camelContextStat").append(String.format(" id=\"%s\" state=\"%s\"", getCamelId(), getState()));
627        // use substring as we only want the attributes
628        String stat = dumpStatsAsXml(fullStats);
629        sb.append(" exchangesInflight=\"").append(getInflightExchanges()).append("\"");
630        sb.append(" ").append(stat, 7, stat.length() - 2).append(">\n");
631
632        MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer();
633        if (server != null) {
634            // gather all the routes for this CamelContext, which requires JMX
635            String prefix = getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() ? "*/" : "";
636            ObjectName query = ObjectName
637                    .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=routes,*");
638            Set<ObjectName> routes = server.queryNames(query, null);
639
640            List<ManagedProcessorMBean> steps = new ArrayList<>();
641            // gather all the steps for this CamelContext, which requires JMX
642            query = ObjectName
643                    .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=steps,*");
644            Set<ObjectName> names = server.queryNames(query, null);
645            for (ObjectName on : names) {
646                ManagedStepMBean step
647                        = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedStepMBean.class);
648                steps.add(step);
649            }
650            steps.sort(new OrderProcessorMBeans());
651
652            // loop the routes, and append the processor stats if needed
653            sb.append("  <routeStats>\n");
654            for (ObjectName on : routes) {
655                ManagedRouteMBean route
656                        = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedRouteMBean.class);
657                sb.append("    <routeStat")
658                        .append(String.format(" id=\"%s\" state=\"%s\"", route.getRouteId(), route.getState()));
659                if (route.getSourceLocation() != null) {
660                    sb.append(String.format(" sourceLocation=\"%s\"", route.getSourceLocation()));
661                }
662
663                // use substring as we only want the attributes
664                stat = route.dumpStatsAsXml(fullStats);
665                sb.append(" exchangesInflight=\"").append(route.getExchangesInflight()).append("\"");
666                sb.append(" ").append(stat, 7, stat.length() - 2).append(">\n");
667
668                // add steps details if needed
669                sb.append("      <stepStats>\n");
670                for (ManagedProcessorMBean step : steps) {
671                    // the step must belong to this route
672                    if (route.getRouteId().equals(step.getRouteId())) {
673                        int line = step.getSourceLineNumber() != null ? step.getSourceLineNumber() : -1;
674                        sb.append("        <stepStat")
675                                .append(String.format(" id=\"%s\" index=\"%s\" state=\"%s\" sourceLineNumber=\"%s\"",
676                                        step.getProcessorId(), step.getIndex(), step.getState(), line));
677                        // use substring as we only want the attributes
678                        stat = step.dumpStatsAsXml(fullStats);
679                        sb.append(" exchangesInflight=\"").append(step.getExchangesInflight()).append("\"");
680                        sb.append(" ").append(stat, 7, stat.length()).append("\n");
681                    }
682                    sb.append("      </stepStats>\n");
683                }
684                sb.append("    </stepStat>\n");
685            }
686            sb.append("  </routeStats>\n");
687        }
688
689        sb.append("</camelContextStat>");
690        return sb.toString();
691    }
692
693    @Override
694    public String dumpRoutesCoverageAsXml() throws Exception {
695        StringBuilder sb = new StringBuilder();
696        sb.append("<camelContextRouteCoverage")
697                .append(String.format(" id=\"%s\" exchangesTotal=\"%s\" totalProcessingTime=\"%s\"", getCamelId(),
698                        getExchangesTotal(), getTotalProcessingTime()))
699                .append(">\n");
700
701        String xml = dumpRoutesAsXml(false, false);
702        if (xml != null) {
703            // use the coverage xml parser to dump the routes and enrich with coverage stats
704            Document dom = RouteCoverageXmlParser.parseXml(context, new ByteArrayInputStream(xml.getBytes()));
705            // convert dom back to xml
706            String converted = context.getTypeConverter().convertTo(String.class, dom);
707            sb.append(converted);
708        }
709
710        sb.append("\n</camelContextRouteCoverage>");
711        return sb.toString();
712    }
713
714    @Override
715    public boolean createEndpoint(String uri) throws Exception {
716        if (context.hasEndpoint(uri) != null) {
717            // endpoint already exists
718            return false;
719        }
720
721        Endpoint endpoint = context.getEndpoint(uri);
722        if (endpoint != null) {
723            // ensure endpoint is registered, as the management strategy could have been configured to not always
724            // register new endpoints in JMX, so we need to check if its registered, and if not register it manually
725            ObjectName on
726                    = context.getManagementStrategy().getManagementObjectNameStrategy().getObjectNameForEndpoint(endpoint);
727            if (on != null && !context.getManagementStrategy().getManagementAgent().isRegistered(on)) {
728                // register endpoint as mbean
729                Object me = context.getManagementStrategy().getManagementObjectStrategy().getManagedObjectForEndpoint(context,
730                        endpoint);
731                context.getManagementStrategy().getManagementAgent().register(me, on);
732            }
733            return true;
734        } else {
735            return false;
736        }
737    }
738
739    @Override
740    public int removeEndpoints(String pattern) throws Exception {
741        // endpoints is always removed from JMX if removed from context
742        Collection<Endpoint> removed = context.removeEndpoints(pattern);
743        return removed.size();
744    }
745
746    @Override
747    public void reset(boolean includeRoutes) throws Exception {
748        reset();
749        load.reset();
750        thp.reset();
751
752        // and now reset all routes for this route
753        if (includeRoutes) {
754            MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer();
755            if (server != null) {
756                String prefix = getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() ? "*/" : "";
757                ObjectName query = ObjectName
758                        .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=routes,*");
759                Set<ObjectName> names = server.queryNames(query, null);
760                for (ObjectName name : names) {
761                    server.invoke(name, "reset", new Object[] { true }, new String[] { "boolean" });
762                }
763            }
764        }
765    }
766
767    @Override
768    public Set<String> componentNames() throws Exception {
769        return context.getComponentNames();
770    }
771
772    @Override
773    public Set<String> languageNames() throws Exception {
774        return context.getLanguageNames();
775    }
776
777    @Override
778    public Set<String> dataFormatNames() throws Exception {
779        return context.getDataFormatNames();
780    }
781
782    /**
783     * Used for sorting the processor mbeans accordingly to their index.
784     */
785    private static final class OrderProcessorMBeans implements Comparator<ManagedProcessorMBean> {
786
787        @Override
788        public int compare(ManagedProcessorMBean o1, ManagedProcessorMBean o2) {
789            return o1.getIndex().compareTo(o2.getIndex());
790        }
791    }
792
793    /**
794     * Used for sorting the routes mbeans accordingly to their ids.
795     */
796    private static final class RouteMBeans implements Comparator<ManagedRouteMBean> {
797
798        @Override
799        public int compare(ManagedRouteMBean o1, ManagedRouteMBean o2) {
800            return o1.getRouteId().compareToIgnoreCase(o2.getRouteId());
801        }
802    }
803
804}