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