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.impl.health; 018 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.Collections; 022import java.util.HashMap; 023import java.util.List; 024import java.util.Map; 025 026import org.apache.camel.CamelContext; 027import org.apache.camel.Route; 028import org.apache.camel.ServiceStatus; 029import org.apache.camel.api.management.mbean.ManagedRouteMBean; 030import org.apache.camel.health.HealthCheckResultBuilder; 031import org.apache.camel.util.ObjectHelper; 032import org.slf4j.Logger; 033import org.slf4j.LoggerFactory; 034 035public class RouteHealthCheck extends AbstractHealthCheck { 036 private static final Logger LOGGER = LoggerFactory.getLogger(RouteHealthCheck.class); 037 038 private final Route route; 039 private final List<PerformanceCounterEvaluator<ManagedRouteMBean>> evaluators; 040 041 public RouteHealthCheck(Route route) { 042 this(route, null); 043 } 044 045 public RouteHealthCheck(Route route, Collection<PerformanceCounterEvaluator<ManagedRouteMBean>> evaluators) { 046 super("camel", "route:" + route.getId()); 047 048 this.route = route; 049 050 if (ObjectHelper.isNotEmpty(evaluators)) { 051 this.evaluators = new ArrayList<>(evaluators); 052 } else { 053 this.evaluators = Collections.emptyList(); 054 } 055 } 056 057 @Override 058 protected void doCall(HealthCheckResultBuilder builder, Map<String, Object> options) { 059 if (route.getId() != null) { 060 final CamelContext context = route.getRouteContext().getCamelContext(); 061 final ServiceStatus status = context.getRouteStatus(route.getId()); 062 063 builder.detail("route.id", route.getId()); 064 builder.detail("route.status", status.name()); 065 builder.detail("route.context.name", context.getName()); 066 067 if (route.getRouteContext().getRouteController() != null || route.getRouteContext().isAutoStartup()) { 068 if (status.isStarted()) { 069 builder.up(); 070 } else if (status.isStopped()) { 071 builder.down(); 072 builder.message(String.format("Route %s has status %s", route.getId(), status.name())); 073 } 074 } else { 075 LOGGER.debug("Route {} marked as UP (controlled={}, auto-startup={})", 076 route.getId(), 077 route.getRouteContext().getRouteController() != null, 078 route.getRouteContext().isAutoStartup() 079 ); 080 081 // Assuming that if no route controller is configured or if a 082 // route is configured to not to automatically start, then the 083 // route is always up as it is externally managed. 084 builder.up(); 085 } 086 087 if (builder.state() != State.DOWN) { 088 // If JMX is enabled, use the Managed MBeans to determine route 089 // health based on performance counters. 090 ManagedRouteMBean managedRoute = context.getManagedRoute(route.getId(), ManagedRouteMBean.class); 091 092 if (managedRoute != null && !evaluators.isEmpty()) { 093 Map<String, Object> details = new HashMap<>(); 094 095 for (PerformanceCounterEvaluator evaluator : evaluators) { 096 details.clear(); 097 098 evaluator.test(managedRoute, builder, options); 099 100 if (builder.state() == State.DOWN) { 101 break; 102 } 103 } 104 } 105 } 106 } 107 } 108}