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.util.ArrayList; 021import java.util.Collection; 022import java.util.Comparator; 023import java.util.List; 024import java.util.Map; 025import java.util.Set; 026import java.util.concurrent.TimeUnit; 027 028import javax.management.MBeanServer; 029import javax.management.ObjectName; 030 031import org.w3c.dom.Document; 032 033import org.apache.camel.CamelContext; 034import org.apache.camel.Endpoint; 035import org.apache.camel.Exchange; 036import org.apache.camel.ExtendedCamelContext; 037import org.apache.camel.ManagementStatisticsLevel; 038import org.apache.camel.Producer; 039import org.apache.camel.ProducerTemplate; 040import org.apache.camel.Route; 041import org.apache.camel.TimerListener; 042import org.apache.camel.api.management.ManagedResource; 043import org.apache.camel.api.management.mbean.ManagedCamelContextMBean; 044import org.apache.camel.api.management.mbean.ManagedProcessorMBean; 045import org.apache.camel.api.management.mbean.ManagedRouteMBean; 046import org.apache.camel.api.management.mbean.ManagedStepMBean; 047import org.apache.camel.model.Model; 048import org.apache.camel.model.ModelCamelContext; 049import org.apache.camel.model.RouteDefinition; 050import org.apache.camel.model.RouteTemplateDefinition; 051import org.apache.camel.model.RouteTemplatesDefinition; 052import org.apache.camel.model.RoutesDefinition; 053import org.apache.camel.model.rest.RestDefinition; 054import org.apache.camel.model.rest.RestsDefinition; 055import org.apache.camel.spi.ManagementStrategy; 056import org.apache.camel.spi.UnitOfWork; 057 058@ManagedResource(description = "Managed CamelContext") 059public class ManagedCamelContext extends ManagedPerformanceCounter implements TimerListener, ManagedCamelContextMBean { 060 061 private final CamelContext context; 062 private final LoadTriplet load = new LoadTriplet(); 063 private final LoadThroughput thp = new LoadThroughput(); 064 private final String jmxDomain; 065 066 public ManagedCamelContext(CamelContext context) { 067 this.context = context; 068 this.jmxDomain = context.getManagementStrategy().getManagementAgent().getMBeanObjectDomainName(); 069 } 070 071 @Override 072 public void init(ManagementStrategy strategy) { 073 super.init(strategy); 074 boolean enabled = context.getManagementStrategy().getManagementAgent() != null 075 && context.getManagementStrategy().getManagementAgent().getStatisticsLevel() != ManagementStatisticsLevel.Off; 076 setStatisticsEnabled(enabled); 077 } 078 079 @Override 080 public void completedExchange(Exchange exchange, long time) { 081 // the camel-context mbean is triggered for every route mbean 082 // so we must only trigger on the root level, otherwise the context mbean 083 // total counter will be incorrect. For example if an exchange is routed via 3 routes 084 // we should only count this as 1 instead of 3. 085 UnitOfWork uow = exchange.getUnitOfWork(); 086 if (uow != null) { 087 int level = uow.routeStackLevel(); 088 if (level <= 1) { 089 super.completedExchange(exchange, time); 090 } 091 } else { 092 super.completedExchange(exchange, time); 093 } 094 } 095 096 @Override 097 public void failedExchange(Exchange exchange) { 098 // the camel-context mbean is triggered for every route mbean 099 // so we must only trigger on the root level, otherwise the context mbean 100 // total counter will be incorrect. For example if an exchange is routed via 3 routes 101 // we should only count this as 1 instead of 3. 102 UnitOfWork uow = exchange.getUnitOfWork(); 103 if (uow != null) { 104 int level = uow.routeStackLevel(); 105 if (level <= 1) { 106 super.failedExchange(exchange); 107 } 108 } else { 109 super.failedExchange(exchange); 110 } 111 } 112 113 @Override 114 public void processExchange(Exchange exchange, String type) { 115 // the camel-context mbean is triggered for every route mbean 116 // so we must only trigger on the root level, otherwise the context mbean 117 // total counter will be incorrect. For example if an exchange is routed via 3 routes 118 // we should only count this as 1 instead of 3. 119 UnitOfWork uow = exchange.getUnitOfWork(); 120 if (uow != null) { 121 int level = uow.routeStackLevel(); 122 if (level <= 1) { 123 super.processExchange(exchange, type); 124 } 125 } else { 126 super.processExchange(exchange, type); 127 } 128 } 129 130 public CamelContext getContext() { 131 return context; 132 } 133 134 @Override 135 public String getCamelId() { 136 return context.getName(); 137 } 138 139 @Override 140 public String getCamelDescription() { 141 return context.getDescription(); 142 } 143 144 @Override 145 public String getManagementName() { 146 return context.getManagementName(); 147 } 148 149 @Override 150 public String getCamelVersion() { 151 return context.getVersion(); 152 } 153 154 @Override 155 public String getState() { 156 return context.getStatus().name(); 157 } 158 159 @Override 160 public String getUptime() { 161 return context.getUptime(); 162 } 163 164 @Override 165 public long getUptimeMillis() { 166 return context.getUptimeMillis(); 167 } 168 169 @Override 170 public String getManagementStatisticsLevel() { 171 if (context.getManagementStrategy().getManagementAgent() != null) { 172 return context.getManagementStrategy().getManagementAgent().getStatisticsLevel().name(); 173 } else { 174 return null; 175 } 176 } 177 178 @Override 179 public String getClassResolver() { 180 return context.getClassResolver().getClass().getName(); 181 } 182 183 @Override 184 public String getPackageScanClassResolver() { 185 return context.adapt(ExtendedCamelContext.class).getPackageScanClassResolver().getClass().getName(); 186 } 187 188 @Override 189 public String getApplicationContextClassName() { 190 if (context.getApplicationContextClassLoader() != null) { 191 return context.getApplicationContextClassLoader().getClass().getName(); 192 } else { 193 return null; 194 } 195 } 196 197 @Override 198 public String getHeadersMapFactoryClassName() { 199 return context.adapt(ExtendedCamelContext.class).getHeadersMapFactory().getClass().getName(); 200 } 201 202 @Override 203 public Map<String, String> getGlobalOptions() { 204 if (context.getGlobalOptions().isEmpty()) { 205 return null; 206 } 207 return context.getGlobalOptions(); 208 } 209 210 @Override 211 public String getGlobalOption(String key) throws Exception { 212 return context.getGlobalOption(key); 213 } 214 215 @Override 216 public void setGlobalOption(String key, String value) throws Exception { 217 context.getGlobalOptions().put(key, value); 218 } 219 220 @Override 221 public Boolean getTracing() { 222 return context.isTracing(); 223 } 224 225 @Override 226 public void setTracing(Boolean tracing) { 227 context.setTracing(tracing); 228 } 229 230 public Integer getInflightExchanges() { 231 return (int) super.getExchangesInflight(); 232 } 233 234 @Override 235 public Integer getTotalRoutes() { 236 return context.getRoutesSize(); 237 } 238 239 @Override 240 public Integer getStartedRoutes() { 241 int started = 0; 242 for (Route route : context.getRoutes()) { 243 if (context.getRouteController().getRouteStatus(route.getId()).isStarted()) { 244 started++; 245 } 246 } 247 return started; 248 } 249 250 @Override 251 public void setTimeout(long timeout) { 252 context.getShutdownStrategy().setTimeout(timeout); 253 } 254 255 @Override 256 public long getTimeout() { 257 return context.getShutdownStrategy().getTimeout(); 258 } 259 260 @Override 261 public void setTimeUnit(TimeUnit timeUnit) { 262 context.getShutdownStrategy().setTimeUnit(timeUnit); 263 } 264 265 @Override 266 public TimeUnit getTimeUnit() { 267 return context.getShutdownStrategy().getTimeUnit(); 268 } 269 270 @Override 271 public void setShutdownNowOnTimeout(boolean shutdownNowOnTimeout) { 272 context.getShutdownStrategy().setShutdownNowOnTimeout(shutdownNowOnTimeout); 273 } 274 275 @Override 276 public boolean isShutdownNowOnTimeout() { 277 return context.getShutdownStrategy().isShutdownNowOnTimeout(); 278 } 279 280 @Override 281 public String getLoad01() { 282 double load1 = load.getLoad1(); 283 if (Double.isNaN(load1)) { 284 // empty string if load statistics is disabled 285 return ""; 286 } else { 287 return String.format("%.2f", load1); 288 } 289 } 290 291 @Override 292 public String getLoad05() { 293 double load5 = load.getLoad5(); 294 if (Double.isNaN(load5)) { 295 // empty string if load statistics is disabled 296 return ""; 297 } else { 298 return String.format("%.2f", load5); 299 } 300 } 301 302 @Override 303 public String getLoad15() { 304 double load15 = load.getLoad15(); 305 if (Double.isNaN(load15)) { 306 // empty string if load statistics is disabled 307 return ""; 308 } else { 309 return String.format("%.2f", load15); 310 } 311 } 312 313 @Override 314 public String getThroughput() { 315 double d = thp.getThroughput(); 316 if (Double.isNaN(d)) { 317 // empty string if load statistics is disabled 318 return ""; 319 } else { 320 return String.format("%.2f", d); 321 } 322 } 323 324 @Override 325 public boolean isUseBreadcrumb() { 326 return context.isUseBreadcrumb(); 327 } 328 329 @Override 330 public boolean isAllowUseOriginalMessage() { 331 return context.isAllowUseOriginalMessage(); 332 } 333 334 @Override 335 public boolean isMessageHistory() { 336 return context.isMessageHistory() != null ? context.isMessageHistory() : false; 337 } 338 339 @Override 340 public boolean isLogMask() { 341 return context.isLogMask() != null ? context.isLogMask() : false; 342 } 343 344 @Override 345 public boolean isUseMDCLogging() { 346 return context.isUseMDCLogging(); 347 } 348 349 @Override 350 public boolean isUseDataType() { 351 return context.isUseDataType(); 352 } 353 354 @Override 355 public void onTimer() { 356 load.update(getInflightExchanges()); 357 thp.update(getExchangesTotal()); 358 } 359 360 @Override 361 public void start() throws Exception { 362 if (context.isSuspended()) { 363 context.resume(); 364 } else { 365 context.start(); 366 } 367 } 368 369 @Override 370 public void stop() throws Exception { 371 context.stop(); 372 } 373 374 @Override 375 public void restart() throws Exception { 376 context.stop(); 377 context.start(); 378 } 379 380 @Override 381 public void suspend() throws Exception { 382 context.suspend(); 383 } 384 385 @Override 386 public void resume() throws Exception { 387 if (context.isSuspended()) { 388 context.resume(); 389 } else { 390 throw new IllegalStateException("CamelContext is not suspended"); 391 } 392 } 393 394 @Override 395 public void startAllRoutes() throws Exception { 396 context.getRouteController().startAllRoutes(); 397 } 398 399 @Override 400 public boolean canSendToEndpoint(String endpointUri) { 401 try { 402 Endpoint endpoint = context.getEndpoint(endpointUri); 403 if (endpoint != null) { 404 Producer producer = endpoint.createProducer(); 405 return producer != null; 406 } 407 } catch (Exception e) { 408 // ignore 409 } 410 411 return false; 412 } 413 414 @Override 415 public void sendBody(String endpointUri, Object body) throws Exception { 416 ProducerTemplate template = context.createProducerTemplate(); 417 try { 418 template.sendBody(endpointUri, body); 419 } finally { 420 template.stop(); 421 } 422 } 423 424 @Override 425 public void sendStringBody(String endpointUri, String body) throws Exception { 426 sendBody(endpointUri, body); 427 } 428 429 @Override 430 public void sendBodyAndHeaders(String endpointUri, Object body, Map<String, Object> headers) throws Exception { 431 ProducerTemplate template = context.createProducerTemplate(); 432 try { 433 template.sendBodyAndHeaders(endpointUri, body, headers); 434 } finally { 435 template.stop(); 436 } 437 } 438 439 @Override 440 public Object requestBody(String endpointUri, Object body) throws Exception { 441 ProducerTemplate template = context.createProducerTemplate(); 442 Object answer = null; 443 try { 444 answer = template.requestBody(endpointUri, body); 445 } finally { 446 template.stop(); 447 } 448 return answer; 449 } 450 451 @Override 452 public Object requestStringBody(String endpointUri, String body) throws Exception { 453 return requestBody(endpointUri, body); 454 } 455 456 @Override 457 public Object requestBodyAndHeaders(String endpointUri, Object body, Map<String, Object> headers) throws Exception { 458 ProducerTemplate template = context.createProducerTemplate(); 459 Object answer = null; 460 try { 461 answer = template.requestBodyAndHeaders(endpointUri, body, headers); 462 } finally { 463 template.stop(); 464 } 465 return answer; 466 } 467 468 @Override 469 public String dumpRestsAsXml() throws Exception { 470 return dumpRestsAsXml(false); 471 } 472 473 @Override 474 public String dumpRestsAsXml(boolean resolvePlaceholders) throws Exception { 475 List<RestDefinition> rests = context.getExtension(Model.class).getRestDefinitions(); 476 if (rests.isEmpty()) { 477 return null; 478 } 479 480 RestsDefinition def = new RestsDefinition(); 481 def.setRests(rests); 482 483 ExtendedCamelContext ecc = context.adapt(ExtendedCamelContext.class); 484 return ecc.getModelToXMLDumper().dumpModelAsXml(context, def, resolvePlaceholders, false); 485 } 486 487 @Override 488 public String dumpRoutesAsXml() throws Exception { 489 return dumpRoutesAsXml(false, false); 490 } 491 492 @Override 493 public String dumpRoutesAsXml(boolean resolvePlaceholders) throws Exception { 494 return dumpRoutesAsXml(resolvePlaceholders, false); 495 } 496 497 @Override 498 public String dumpRoutesAsXml(boolean resolvePlaceholders, boolean resolveDelegateEndpoints) throws Exception { 499 List<RouteDefinition> routes = context.getExtension(Model.class).getRouteDefinitions(); 500 if (routes.isEmpty()) { 501 return null; 502 } 503 504 // use routes definition to dump the routes 505 RoutesDefinition def = new RoutesDefinition(); 506 def.setRoutes(routes); 507 508 ExtendedCamelContext ecc = context.adapt(ExtendedCamelContext.class); 509 return ecc.getModelToXMLDumper().dumpModelAsXml(context, def, resolvePlaceholders, resolveDelegateEndpoints); 510 } 511 512 @Override 513 public String dumpRouteTemplatesAsXml() throws Exception { 514 List<RouteTemplateDefinition> templates = context.getExtension(Model.class).getRouteTemplateDefinitions(); 515 if (templates.isEmpty()) { 516 return null; 517 } 518 519 // use a route templates definition to dump the templates 520 RouteTemplatesDefinition def = new RouteTemplatesDefinition(); 521 def.setRouteTemplates(templates); 522 523 ExtendedCamelContext ecc = context.adapt(ExtendedCamelContext.class); 524 return ecc.getModelToXMLDumper().dumpModelAsXml(context, def); 525 } 526 527 @Override 528 public String dumpRoutesStatsAsXml(boolean fullStats, boolean includeProcessors) throws Exception { 529 StringBuilder sb = new StringBuilder(); 530 sb.append("<camelContextStat").append(String.format(" id=\"%s\" state=\"%s\"", getCamelId(), getState())); 531 // use substring as we only want the attributes 532 String stat = dumpStatsAsXml(fullStats); 533 sb.append(" exchangesInflight=\"").append(getInflightExchanges()).append("\""); 534 sb.append(" ").append(stat, 7, stat.length() - 2).append(">\n"); 535 536 MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer(); 537 if (server != null) { 538 // gather all the routes for this CamelContext, which requires JMX 539 String prefix = getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() ? "*/" : ""; 540 ObjectName query = ObjectName 541 .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=routes,*"); 542 Set<ObjectName> routes = server.queryNames(query, null); 543 544 List<ManagedProcessorMBean> processors = new ArrayList<>(); 545 if (includeProcessors) { 546 // gather all the processors for this CamelContext, which requires JMX 547 query = ObjectName.getInstance( 548 jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=processors,*"); 549 Set<ObjectName> names = server.queryNames(query, null); 550 for (ObjectName on : names) { 551 ManagedProcessorMBean processor = context.getManagementStrategy().getManagementAgent().newProxyClient(on, 552 ManagedProcessorMBean.class); 553 processors.add(processor); 554 } 555 } 556 processors.sort(new OrderProcessorMBeans()); 557 558 // loop the routes, and append the processor stats if needed 559 sb.append(" <routeStats>\n"); 560 for (ObjectName on : routes) { 561 ManagedRouteMBean route 562 = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedRouteMBean.class); 563 sb.append(" <routeStat") 564 .append(String.format(" id=\"%s\" state=\"%s\"", route.getRouteId(), route.getState())); 565 if (route.getSourceLocation() != null) { 566 sb.append(String.format(" sourceLocation=\"%s\"", route.getSourceLocation())); 567 } 568 569 // use substring as we only want the attributes 570 stat = route.dumpStatsAsXml(fullStats); 571 sb.append(" exchangesInflight=\"").append(route.getExchangesInflight()).append("\""); 572 sb.append(" ").append(stat, 7, stat.length() - 2).append(">\n"); 573 574 // add processor details if needed 575 if (includeProcessors) { 576 sb.append(" <processorStats>\n"); 577 for (ManagedProcessorMBean processor : processors) { 578 int line = processor.getSourceLineNumber() != null ? processor.getSourceLineNumber() : -1; 579 // the processor must belong to this route 580 if (route.getRouteId().equals(processor.getRouteId())) { 581 sb.append(" <processorStat") 582 .append(String.format(" id=\"%s\" index=\"%s\" state=\"%s\" sourceLineNumber=\"%s\"", 583 processor.getProcessorId(), processor.getIndex(), processor.getState(), line)); 584 // use substring as we only want the attributes 585 stat = processor.dumpStatsAsXml(fullStats); 586 sb.append(" exchangesInflight=\"").append(processor.getExchangesInflight()).append("\""); 587 sb.append(" ").append(stat, 7, stat.length()).append("\n"); 588 } 589 } 590 sb.append(" </processorStats>\n"); 591 } 592 sb.append(" </routeStat>\n"); 593 } 594 sb.append(" </routeStats>\n"); 595 } 596 597 sb.append("</camelContextStat>"); 598 return sb.toString(); 599 } 600 601 @Override 602 public String dumpStepStatsAsXml(boolean fullStats) throws Exception { 603 StringBuilder sb = new StringBuilder(); 604 sb.append("<camelContextStat").append(String.format(" id=\"%s\" state=\"%s\"", getCamelId(), getState())); 605 // use substring as we only want the attributes 606 String stat = dumpStatsAsXml(fullStats); 607 sb.append(" exchangesInflight=\"").append(getInflightExchanges()).append("\""); 608 sb.append(" ").append(stat, 7, stat.length() - 2).append(">\n"); 609 610 MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer(); 611 if (server != null) { 612 // gather all the routes for this CamelContext, which requires JMX 613 String prefix = getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() ? "*/" : ""; 614 ObjectName query = ObjectName 615 .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=routes,*"); 616 Set<ObjectName> routes = server.queryNames(query, null); 617 618 List<ManagedProcessorMBean> steps = new ArrayList<>(); 619 // gather all the steps for this CamelContext, which requires JMX 620 query = ObjectName 621 .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=steps,*"); 622 Set<ObjectName> names = server.queryNames(query, null); 623 for (ObjectName on : names) { 624 ManagedStepMBean step 625 = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedStepMBean.class); 626 steps.add(step); 627 } 628 steps.sort(new OrderProcessorMBeans()); 629 630 // loop the routes, and append the processor stats if needed 631 sb.append(" <routeStats>\n"); 632 for (ObjectName on : routes) { 633 ManagedRouteMBean route 634 = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedRouteMBean.class); 635 sb.append(" <routeStat") 636 .append(String.format(" id=\"%s\" state=\"%s\"", route.getRouteId(), route.getState())); 637 if (route.getSourceLocation() != null) { 638 sb.append(String.format(" sourceLocation=\"%s\"", route.getSourceLocation())); 639 } 640 641 // use substring as we only want the attributes 642 stat = route.dumpStatsAsXml(fullStats); 643 sb.append(" exchangesInflight=\"").append(route.getExchangesInflight()).append("\""); 644 sb.append(" ").append(stat, 7, stat.length() - 2).append(">\n"); 645 646 // add steps details if needed 647 sb.append(" <stepStats>\n"); 648 for (ManagedProcessorMBean step : steps) { 649 // the step must belong to this route 650 if (route.getRouteId().equals(step.getRouteId())) { 651 int line = step.getSourceLineNumber() != null ? step.getSourceLineNumber() : -1; 652 sb.append(" <stepStat") 653 .append(String.format(" id=\"%s\" index=\"%s\" state=\"%s\" sourceLineNumber=\"%s\"", 654 step.getProcessorId(), step.getIndex(), step.getState(), line)); 655 // use substring as we only want the attributes 656 stat = step.dumpStatsAsXml(fullStats); 657 sb.append(" exchangesInflight=\"").append(step.getExchangesInflight()).append("\""); 658 sb.append(" ").append(stat, 7, stat.length()).append("\n"); 659 } 660 sb.append(" </stepStats>\n"); 661 } 662 sb.append(" </stepStat>\n"); 663 } 664 sb.append(" </routeStats>\n"); 665 } 666 667 sb.append("</camelContextStat>"); 668 return sb.toString(); 669 } 670 671 @Override 672 public String dumpRoutesCoverageAsXml() throws Exception { 673 StringBuilder sb = new StringBuilder(); 674 sb.append("<camelContextRouteCoverage") 675 .append(String.format(" id=\"%s\" exchangesTotal=\"%s\" totalProcessingTime=\"%s\"", getCamelId(), 676 getExchangesTotal(), getTotalProcessingTime())) 677 .append(">\n"); 678 679 String xml = dumpRoutesAsXml(); 680 if (xml != null) { 681 // use the coverage xml parser to dump the routes and enrich with coverage stats 682 Document dom = RouteCoverageXmlParser.parseXml(context, new ByteArrayInputStream(xml.getBytes())); 683 // convert dom back to xml 684 String converted = context.getTypeConverter().convertTo(String.class, dom); 685 sb.append(converted); 686 } 687 688 sb.append("\n</camelContextRouteCoverage>"); 689 return sb.toString(); 690 } 691 692 @Override 693 @Deprecated 694 public String dumpRoutesSourceLocationsAsXml() throws Exception { 695 StringBuilder sb = new StringBuilder(); 696 sb.append("<routeLocations>"); 697 698 MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer(); 699 if (server != null) { 700 // gather all the routes for this CamelContext, which requires JMX 701 List<ManagedRouteMBean> routes = new ArrayList<>(); 702 String prefix = getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() ? "*/" : ""; 703 ObjectName query = ObjectName 704 .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=routes,*"); 705 Set<ObjectName> names = server.queryNames(query, null); 706 for (ObjectName on : names) { 707 ManagedRouteMBean route 708 = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedRouteMBean.class); 709 routes.add(route); 710 } 711 routes.sort(new RouteMBeans()); 712 713 List<ManagedProcessorMBean> processors = new ArrayList<>(); 714 // gather all the processors for this CamelContext, which requires JMX 715 query = ObjectName 716 .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=processors,*"); 717 names = server.queryNames(query, null); 718 for (ObjectName on : names) { 719 ManagedProcessorMBean processor 720 = context.getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedProcessorMBean.class); 721 processors.add(processor); 722 } 723 processors.sort(new OrderProcessorMBeans()); 724 725 // loop the routes, and append the node ids (via processor) 726 for (ManagedRouteMBean route : routes) { 727 // grab route consumer 728 RouteDefinition rd = context.adapt(ModelCamelContext.class).getRouteDefinition(route.getRouteId()); 729 if (rd != null) { 730 String id = rd.getRouteId(); 731 int line = rd.getInput().getLineNumber(); 732 String location 733 = rd.getInput().getLocation() != null ? rd.getInput().getLocation() : route.getSourceLocation(); 734 if (location == null) { 735 location = ""; 736 } 737 sb.append("\n <routeLocation") 738 .append(String.format( 739 " routeId=\"%s\" id=\"%s\" index=\"%s\" sourceLocation=\"%s\" sourceLineNumber=\"%s\"/>", 740 route.getRouteId(), id, 0, location, line)); 741 } 742 for (ManagedProcessorMBean processor : processors) { 743 // the step must belong to this route 744 if (route.getRouteId().equals(processor.getRouteId())) { 745 int line = processor.getSourceLineNumber() != null ? processor.getSourceLineNumber() : -1; 746 String location = processor.getSourceLocation(); 747 if (location == null) { 748 location = ""; 749 } 750 sb.append("\n <routeLocation") 751 .append(String.format( 752 " routeId=\"%s\" id=\"%s\" index=\"%s\" sourceLocation=\"%s\" sourceLineNumber=\"%s\"/>", 753 route.getRouteId(), processor.getProcessorId(), processor.getIndex(), location, line)); 754 } 755 } 756 } 757 } 758 sb.append("\n</routeLocations>"); 759 return sb.toString(); 760 } 761 762 @Override 763 public boolean createEndpoint(String uri) throws Exception { 764 if (context.hasEndpoint(uri) != null) { 765 // endpoint already exists 766 return false; 767 } 768 769 Endpoint endpoint = context.getEndpoint(uri); 770 if (endpoint != null) { 771 // ensure endpoint is registered, as the management strategy could have been configured to not always 772 // register new endpoints in JMX, so we need to check if its registered, and if not register it manually 773 ObjectName on 774 = context.getManagementStrategy().getManagementObjectNameStrategy().getObjectNameForEndpoint(endpoint); 775 if (on != null && !context.getManagementStrategy().getManagementAgent().isRegistered(on)) { 776 // register endpoint as mbean 777 Object me = context.getManagementStrategy().getManagementObjectStrategy().getManagedObjectForEndpoint(context, 778 endpoint); 779 context.getManagementStrategy().getManagementAgent().register(me, on); 780 } 781 return true; 782 } else { 783 return false; 784 } 785 } 786 787 @Override 788 public int removeEndpoints(String pattern) throws Exception { 789 // endpoints is always removed from JMX if removed from context 790 Collection<Endpoint> removed = context.removeEndpoints(pattern); 791 return removed.size(); 792 } 793 794 @Override 795 public void reset(boolean includeRoutes) throws Exception { 796 reset(); 797 load.reset(); 798 thp.reset(); 799 800 // and now reset all routes for this route 801 if (includeRoutes) { 802 MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer(); 803 if (server != null) { 804 String prefix = getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() ? "*/" : ""; 805 ObjectName query = ObjectName 806 .getInstance(jmxDomain + ":context=" + prefix + getContext().getManagementName() + ",type=routes,*"); 807 Set<ObjectName> names = server.queryNames(query, null); 808 for (ObjectName name : names) { 809 server.invoke(name, "reset", new Object[] { true }, new String[] { "boolean" }); 810 } 811 } 812 } 813 } 814 815 @Override 816 public Set<String> componentNames() throws Exception { 817 return context.getComponentNames(); 818 } 819 820 @Override 821 public Set<String> languageNames() throws Exception { 822 return context.getLanguageNames(); 823 } 824 825 @Override 826 public Set<String> dataFormatNames() throws Exception { 827 return context.getDataFormatNames(); 828 } 829 830 /** 831 * Used for sorting the processor mbeans accordingly to their index. 832 */ 833 private static final class OrderProcessorMBeans implements Comparator<ManagedProcessorMBean> { 834 835 @Override 836 public int compare(ManagedProcessorMBean o1, ManagedProcessorMBean o2) { 837 return o1.getIndex().compareTo(o2.getIndex()); 838 } 839 } 840 841 /** 842 * Used for sorting the routes mbeans accordingly to their ids. 843 */ 844 private static final class RouteMBeans implements Comparator<ManagedRouteMBean> { 845 846 @Override 847 public int compare(ManagedRouteMBean o1, ManagedRouteMBean o2) { 848 return o1.getRouteId().compareToIgnoreCase(o2.getRouteId()); 849 } 850 } 851 852}