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