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