001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.actuate.autoconfigure.health; 018 019import java.util.Map; 020 021import org.springframework.beans.factory.annotation.Autowired; 022import org.springframework.boot.actuate.health.CompositeHealthIndicator; 023import org.springframework.boot.actuate.health.DefaultHealthIndicatorRegistry; 024import org.springframework.boot.actuate.health.HealthAggregator; 025import org.springframework.boot.actuate.health.HealthIndicator; 026import org.springframework.boot.actuate.health.HealthIndicatorRegistry; 027import org.springframework.core.ResolvableType; 028 029/** 030 * Base class for configurations that can combine source beans using a 031 * {@link CompositeHealthIndicator}. 032 * 033 * @param <H> the health indicator type 034 * @param <S> the bean source type 035 * @author Stephane Nicoll 036 * @since 2.0.0 037 */ 038public abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndicator, S> { 039 040 @Autowired 041 private HealthAggregator healthAggregator; 042 043 protected HealthIndicator createHealthIndicator(Map<String, S> beans) { 044 if (beans.size() == 1) { 045 return createHealthIndicator(beans.values().iterator().next()); 046 } 047 HealthIndicatorRegistry registry = new DefaultHealthIndicatorRegistry(); 048 beans.forEach( 049 (name, source) -> registry.register(name, createHealthIndicator(source))); 050 return new CompositeHealthIndicator(this.healthAggregator, registry); 051 } 052 053 @SuppressWarnings("unchecked") 054 protected H createHealthIndicator(S source) { 055 Class<?>[] generics = ResolvableType 056 .forClass(CompositeHealthIndicatorConfiguration.class, getClass()) 057 .resolveGenerics(); 058 Class<H> indicatorClass = (Class<H>) generics[0]; 059 Class<S> sourceClass = (Class<S>) generics[1]; 060 try { 061 return indicatorClass.getConstructor(sourceClass).newInstance(source); 062 } 063 catch (Exception ex) { 064 throw new IllegalStateException("Unable to create indicator " + indicatorClass 065 + " for source " + sourceClass, ex); 066 } 067 } 068 069}