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