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