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