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.web.server; 018 019import java.util.Arrays; 020import java.util.Collections; 021import java.util.List; 022import java.util.Objects; 023import java.util.stream.Collectors; 024 025import org.springframework.beans.factory.BeanFactoryUtils; 026import org.springframework.beans.factory.ListableBeanFactory; 027import org.springframework.beans.factory.NoSuchBeanDefinitionException; 028import org.springframework.boot.autoconfigure.web.ServerProperties; 029import org.springframework.boot.util.LambdaSafe; 030import org.springframework.boot.web.server.ConfigurableWebServerFactory; 031import org.springframework.boot.web.server.ErrorPage; 032import org.springframework.boot.web.server.Ssl; 033import org.springframework.boot.web.server.WebServerFactory; 034import org.springframework.boot.web.server.WebServerFactoryCustomizer; 035import org.springframework.core.Ordered; 036 037/** 038 * {@link WebServerFactoryCustomizer} that customizes the {@link WebServerFactory} used to 039 * create the management context's web server. 040 * 041 * @param <T> the type of web server factory to customize 042 * @author Andy Wilkinson 043 * @since 2.0.0 044 */ 045public abstract class ManagementWebServerFactoryCustomizer<T extends ConfigurableWebServerFactory> 046 implements WebServerFactoryCustomizer<T>, Ordered { 047 048 private final ListableBeanFactory beanFactory; 049 050 private final Class<? extends WebServerFactoryCustomizer<?>>[] customizerClasses; 051 052 @SafeVarargs 053 protected ManagementWebServerFactoryCustomizer(ListableBeanFactory beanFactory, 054 Class<? extends WebServerFactoryCustomizer<?>>... customizerClasses) { 055 this.beanFactory = beanFactory; 056 this.customizerClasses = customizerClasses; 057 } 058 059 @Override 060 public int getOrder() { 061 return 0; 062 } 063 064 @Override 065 public final void customize(T factory) { 066 ManagementServerProperties managementServerProperties = BeanFactoryUtils 067 .beanOfTypeIncludingAncestors(this.beanFactory, 068 ManagementServerProperties.class); 069 // Customize as per the parent context first (so e.g. the access logs go to 070 // the same place) 071 customizeSameAsParentContext(factory); 072 // Then reset the error pages 073 factory.setErrorPages(Collections.emptySet()); 074 // and add the management-specific bits 075 ServerProperties serverProperties = BeanFactoryUtils 076 .beanOfTypeIncludingAncestors(this.beanFactory, ServerProperties.class); 077 customize(factory, managementServerProperties, serverProperties); 078 } 079 080 private void customizeSameAsParentContext(T factory) { 081 List<WebServerFactoryCustomizer<?>> customizers = Arrays 082 .stream(this.customizerClasses).map(this::getCustomizer) 083 .filter(Objects::nonNull).collect(Collectors.toList()); 084 invokeCustomizers(factory, customizers); 085 } 086 087 private WebServerFactoryCustomizer<?> getCustomizer( 088 Class<? extends WebServerFactoryCustomizer<?>> customizerClass) { 089 try { 090 return BeanFactoryUtils.beanOfTypeIncludingAncestors(this.beanFactory, 091 customizerClass); 092 } 093 catch (NoSuchBeanDefinitionException ex) { 094 return null; 095 } 096 } 097 098 @SuppressWarnings("unchecked") 099 private void invokeCustomizers(T factory, 100 List<WebServerFactoryCustomizer<?>> customizers) { 101 LambdaSafe.callbacks(WebServerFactoryCustomizer.class, customizers, factory) 102 .invoke((customizer) -> customizer.customize(factory)); 103 } 104 105 protected void customize(T factory, 106 ManagementServerProperties managementServerProperties, 107 ServerProperties serverProperties) { 108 factory.setPort(managementServerProperties.getPort()); 109 Ssl ssl = managementServerProperties.getSsl(); 110 if (ssl != null) { 111 factory.setSsl(ssl); 112 } 113 factory.setServerHeader(serverProperties.getServerHeader()); 114 factory.setAddress(managementServerProperties.getAddress()); 115 factory.addErrorPages(new ErrorPage(serverProperties.getError().getPath())); 116 } 117 118}