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