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        RestsDefinition def = new RestsDefinition();
416        def.setRests(rests);
417
418        ExtendedCamelContext ecc = context.adapt(ExtendedCamelContext.class);
419        return ecc.getModelToXMLDumper().dumpModelAsXml(context, def, resolvePlaceholders, false);
420    }
421
422    @Override
423    public String dumpRoutesAsXml() throws Exception {
424        return dumpRoutesAsXml(false, false);
425    }
426
427    @Override
428    public String dumpRoutesAsXml(boolean resolvePlaceholders) throws Exception {
429        return dumpRoutesAsXml(resolvePlaceholders, false);
430    }
431
432    @Override
433    public String dumpRoutesAsXml(boolean resolvePlaceholders, boolean resolveDelegateEndpoints) throws Exception {
434        List<RouteDefinition> routes = context.getExtension(Model.class).getRouteDefinitions();
435        if (routes.isEmpty()) {
436            return null;
437        }
438
439        // use a routes definition to dump the routes
440        RoutesDefinition def = new RoutesDefinition();
441        def.setRoutes(routes);
442
443        ExtendedCamelContext ecc = context.adapt(ExtendedCamelContext.class);
444        return ecc.getModelToXMLDumper().dumpModelAsXml(context, def, resolvePlaceholders, resolveDelegateEndpoints);
445    }
446
447    @Override
448    public String dumpRouteTemplatesAsXml() throws Exception {
449        List<RouteTemplateDefinition> templates = context.getExtension(Model.class).getRouteTemplateDefinitions();
450        if (templates.isEmpty()) {
451            return null;
452        }
453
454        // use a route templates definition to dump the templates
455        RouteTemplatesDefinition def = new RouteTemplatesDefinition();
456        def.setRouteTemplates(templates);
457
458        ExtendedCamelContext ecc = context.adapt(ExtendedCamelContext.class);
459        return ecc.getModelToXMLDumper().dumpModelAsXml(context, def);
460    }
461
462    @Override
463    public void addOrUpdateRoutesFromXml(String xml) throws Exception {
464        // do not decode so we function as before
465        addOrUpdateRoutesFromXml(xml, false);
466    }
467
468    @Override
469    public void addOrUpdateRoutesFromXml(String xml, boolean urlDecode) throws Exception {
470        // decode String as it may have been encoded, from its xml source
471        if (urlDecode) {
472            xml = URLDecoder.decode(xml, "UTF-8");
473        }
474
475        InputStream is = context.getTypeConverter().mandatoryConvertTo(InputStream.class, xml);
476        try {
477            // add will remove existing route first
478            ExtendedCamelContext ecc = context.adapt(ExtendedCamelContext.class);
479            RoutesDefinition routes = (RoutesDefinition) ecc.getXMLRoutesDefinitionLoader().loadRoutesDefinition(ecc, is);
480            context.getExtension(Model.class).addRouteDefinitions(routes.getRoutes());
481        } catch (Exception e) {
482            // log the error as warn as the management api may be invoked remotely over JMX which does not propagate such exception
483            String msg = "Error updating routes from xml: " + xml + " due: " + e.getMessage();
484            LOG.warn(msg, e);
485            throw e;
486        }
487    }
488
489    @Override
490    public String dumpRoutesStatsAsXml(boolean fullStats, boolean includeProcessors) throws Exception {
491        StringBuilder sb = new StringBuilder();
492        sb.append("<camelContextStat").append(String.format(" id=\"%s\" state=\"%s\"", getCamelId(), getState()));
493        // use substring as we only want the attributes
494        String stat = dumpStatsAsXml(fullStats);
495        sb.append(" exchangesInflight=\"").append(getInflightExchanges()).append("\"");
496        sb.append(" ").append(stat, 7, stat.length() - 2).append(">\n");
497
498        MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer();
499        if (server != null) {
500            // gather all the routes for this CamelContext, which requires JMX
501            String prefix = getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() ? "*/" : "";
502            ObjectName query = ObjectName
503                    .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=routes,*");
504            Set<ObjectName> routes = server.queryNames(query, null);
505
506            List<ManagedProcessorMBean> processors = new ArrayList<>();
507            if (includeProcessors) {
508                // gather all the processors for this CamelContext, which requires JMX
509                query = ObjectName.getInstance(
510                        jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=processors,*");
511                Set<ObjectName> names = server.queryNames(query, null);
512                for (ObjectName on : names) {
513                    ManagedProcessorMBean processor = context.getManagementStrategy().getManagementAgent().newProxyClient(on,
514                            ManagedProcessorMBean.class);
515                    processors.add(processor);
516                }
517            }
518            processors.sort(new OrderProcessorMBeans());
519
520            // loop the routes, and append the processor stats if needed
521            sb.append("  <routeStats>\n");
522            for (ObjectName on : routes) {
523                ManagedRouteMBean route
524                        = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedRouteMBean.class);
525                sb.append("    <routeStat")
526                        .append(String.format(" id=\"%s\" state=\"%s\"", route.getRouteId(), route.getState()));
527                // use substring as we only want the attributes
528                stat = route.dumpStatsAsXml(fullStats);
529                sb.append(" exchangesInflight=\"").append(route.getExchangesInflight()).append("\"");
530                sb.append(" ").append(stat, 7, stat.length() - 2).append(">\n");
531
532                // add processor details if needed
533                if (includeProcessors) {
534                    sb.append("      <processorStats>\n");
535                    for (ManagedProcessorMBean processor : processors) {
536                        // the processor must belong to this route
537                        if (route.getRouteId().equals(processor.getRouteId())) {
538                            sb.append("        <processorStat").append(String.format(" id=\"%s\" index=\"%s\" state=\"%s\"",
539                                    processor.getProcessorId(), processor.getIndex(), processor.getState()));
540                            // use substring as we only want the attributes
541                            stat = processor.dumpStatsAsXml(fullStats);
542                            sb.append(" exchangesInflight=\"").append(processor.getExchangesInflight()).append("\"");
543                            sb.append(" ").append(stat, 7, stat.length()).append("\n");
544                        }
545                    }
546                    sb.append("      </processorStats>\n");
547                }
548                sb.append("    </routeStat>\n");
549            }
550            sb.append("  </routeStats>\n");
551        }
552
553        sb.append("</camelContextStat>");
554        return sb.toString();
555    }
556
557    @Override
558    public String dumpStepStatsAsXml(boolean fullStats) throws Exception {
559        StringBuilder sb = new StringBuilder();
560        sb.append("<camelContextStat").append(String.format(" id=\"%s\" state=\"%s\"", getCamelId(), getState()));
561        // use substring as we only want the attributes
562        String stat = dumpStatsAsXml(fullStats);
563        sb.append(" exchangesInflight=\"").append(getInflightExchanges()).append("\"");
564        sb.append(" ").append(stat, 7, stat.length() - 2).append(">\n");
565
566        MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer();
567        if (server != null) {
568            // gather all the routes for this CamelContext, which requires JMX
569            String prefix = getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() ? "*/" : "";
570            ObjectName query = ObjectName
571                    .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=routes,*");
572            Set<ObjectName> routes = server.queryNames(query, null);
573
574            List<ManagedProcessorMBean> steps = new ArrayList<>();
575            // gather all the steps for this CamelContext, which requires JMX
576            query = ObjectName
577                    .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=steps,*");
578            Set<ObjectName> names = server.queryNames(query, null);
579            for (ObjectName on : names) {
580                ManagedStepMBean step
581                        = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedStepMBean.class);
582                steps.add(step);
583            }
584            steps.sort(new OrderProcessorMBeans());
585
586            // loop the routes, and append the processor stats if needed
587            sb.append("  <routeStats>\n");
588            for (ObjectName on : routes) {
589                ManagedRouteMBean route
590                        = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedRouteMBean.class);
591                sb.append("    <routeStat")
592                        .append(String.format(" id=\"%s\" state=\"%s\"", route.getRouteId(), route.getState()));
593                // use substring as we only want the attributes
594                stat = route.dumpStatsAsXml(fullStats);
595                sb.append(" exchangesInflight=\"").append(route.getExchangesInflight()).append("\"");
596                sb.append(" ").append(stat, 7, stat.length() - 2).append(">\n");
597
598                // add steps details if needed
599                sb.append("      <stepStats>\n");
600                for (ManagedProcessorMBean processor : steps) {
601                    // the step must belong to this route
602                    if (route.getRouteId().equals(processor.getRouteId())) {
603                        sb.append("        <stepStat").append(String.format(" id=\"%s\" index=\"%s\" state=\"%s\"",
604                                processor.getProcessorId(), processor.getIndex(), processor.getState()));
605                        // use substring as we only want the attributes
606                        stat = processor.dumpStatsAsXml(fullStats);
607                        sb.append(" exchangesInflight=\"").append(processor.getExchangesInflight()).append("\"");
608                        sb.append(" ").append(stat, 7, stat.length()).append("\n");
609                    }
610                    sb.append("      </stepStats>\n");
611                }
612                sb.append("    </stepStat>\n");
613            }
614            sb.append("  </routeStats>\n");
615        }
616
617        sb.append("</camelContextStat>");
618        return sb.toString();
619    }
620
621    @Override
622    public String dumpRoutesCoverageAsXml() throws Exception {
623        StringBuilder sb = new StringBuilder();
624        sb.append("<camelContextRouteCoverage")
625                .append(String.format(" id=\"%s\" exchangesTotal=\"%s\" totalProcessingTime=\"%s\"", getCamelId(),
626                        getExchangesTotal(), getTotalProcessingTime()))
627                .append(">\n");
628
629        String xml = dumpRoutesAsXml();
630        if (xml != null) {
631            // use the coverage xml parser to dump the routes and enrich with coverage stats
632            Document dom = RouteCoverageXmlParser.parseXml(context, new ByteArrayInputStream(xml.getBytes()));
633            // convert dom back to xml
634            String converted = context.getTypeConverter().convertTo(String.class, dom);
635            sb.append(converted);
636        }
637
638        sb.append("\n</camelContextRouteCoverage>");
639        return sb.toString();
640    }
641
642    @Override
643    public boolean createEndpoint(String uri) throws Exception {
644        if (context.hasEndpoint(uri) != null) {
645            // endpoint already exists
646            return false;
647        }
648
649        Endpoint endpoint = context.getEndpoint(uri);
650        if (endpoint != null) {
651            // ensure endpoint is registered, as the management strategy could have been configured to not always
652            // register new endpoints in JMX, so we need to check if its registered, and if not register it manually
653            ObjectName on
654                    = context.getManagementStrategy().getManagementObjectNameStrategy().getObjectNameForEndpoint(endpoint);
655            if (on != null && !context.getManagementStrategy().getManagementAgent().isRegistered(on)) {
656                // register endpoint as mbean
657                Object me = context.getManagementStrategy().getManagementObjectStrategy().getManagedObjectForEndpoint(context,
658                        endpoint);
659                context.getManagementStrategy().getManagementAgent().register(me, on);
660            }
661            return true;
662        } else {
663            return false;
664        }
665    }
666
667    @Override
668    public int removeEndpoints(String pattern) throws Exception {
669        // endpoints is always removed from JMX if removed from context
670        Collection<Endpoint> removed = context.removeEndpoints(pattern);
671        return removed.size();
672    }
673
674    @Override
675    public String componentParameterJsonSchema(String componentName) throws Exception {
676        return context.adapt(CatalogCamelContext.class).getComponentParameterJsonSchema(componentName);
677    }
678
679    @Override
680    public String dataFormatParameterJsonSchema(String dataFormatName) throws Exception {
681        return context.adapt(CatalogCamelContext.class).getDataFormatParameterJsonSchema(dataFormatName);
682    }
683
684    @Override
685    public String languageParameterJsonSchema(String languageName) throws Exception {
686        return context.adapt(CatalogCamelContext.class).getLanguageParameterJsonSchema(languageName);
687    }
688
689    @Override
690    public String eipParameterJsonSchema(String eipName) throws Exception {
691        return context.adapt(CatalogCamelContext.class).getEipParameterJsonSchema(eipName);
692    }
693
694    @Override
695    public void reset(boolean includeRoutes) throws Exception {
696        reset();
697
698        // and now reset all routes for this route
699        if (includeRoutes) {
700            MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer();
701            if (server != null) {
702                String prefix = getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() ? "*/" : "";
703                ObjectName query = ObjectName
704                        .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=routes,*");
705                Set<ObjectName> names = server.queryNames(query, null);
706                for (ObjectName name : names) {
707                    server.invoke(name, "reset", new Object[] { true }, new String[] { "boolean" });
708                }
709            }
710        }
711    }
712
713    /**
714     * Used for sorting the processor mbeans accordingly to their index.
715     */
716    private static final class OrderProcessorMBeans implements Comparator<ManagedProcessorMBean> {
717
718        @Override
719        public int compare(ManagedProcessorMBean o1, ManagedProcessorMBean o2) {
720            return o1.getIndex().compareTo(o2.getIndex());
721        }
722    }
723
724}