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