AdminServerWebConfiguration.java 6.63 KB
Newer Older
Thomas Bosch committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright 2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Thomas Bosch committed
16
package de.codecentric.boot.admin.config;
Thomas Bosch committed
17 18

import java.util.List;
19
import java.util.Map;
Thomas Bosch committed
20

21
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
22
import org.springframework.boot.autoconfigure.web.ServerProperties;
23
import org.springframework.context.ApplicationContext;
24
import org.springframework.context.ApplicationContextAware;
25
import org.springframework.context.ApplicationEventPublisher;
Thomas Bosch committed
26
import org.springframework.context.annotation.Bean;
Thomas Bosch committed
27
import org.springframework.context.annotation.Configuration;
28
import org.springframework.context.event.EventListener;
29
import org.springframework.core.io.support.ResourcePatternResolver;
Thomas Bosch committed
30
import org.springframework.http.converter.HttpMessageConverter;
31
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
Thomas Bosch committed
32
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
33 34 35
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
Thomas Bosch committed
36 37
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

38
import com.fasterxml.jackson.databind.ObjectMapper;
39

40
import de.codecentric.boot.admin.event.ClientApplicationDeregisteredEvent;
41
import de.codecentric.boot.admin.event.ClientApplicationRegisteredEvent;
42
import de.codecentric.boot.admin.event.RoutesOutdatedEvent;
43
import de.codecentric.boot.admin.journal.ApplicationEventJournal;
44
import de.codecentric.boot.admin.journal.web.JournalController;
Johannes Stelzer committed
45
import de.codecentric.boot.admin.registry.ApplicationRegistry;
46
import de.codecentric.boot.admin.registry.web.RegistryController;
47
import de.codecentric.boot.admin.web.AdminController;
48
import de.codecentric.boot.admin.web.PrefixHandlerMapping;
49 50 51
import de.codecentric.boot.admin.web.servlet.resource.ConcatenatingResourceResolver;
import de.codecentric.boot.admin.web.servlet.resource.PreferMinifiedFilteringResourceResolver;
import de.codecentric.boot.admin.web.servlet.resource.ResourcePatternResolvingResourceResolver;
Thomas Bosch committed
52

Thomas Bosch committed
53
@Configuration
54 55
public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter
		implements ApplicationContextAware {
56 57 58 59
	private final ApplicationEventPublisher publisher;
	private final ServerProperties server;
	private final ResourcePatternResolver resourcePatternResolver;
	private final AdminServerProperties adminServerProperties;
60 61
	private ApplicationContext applicationContext;

62 63 64 65 66 67 68
	public AdminServerWebConfiguration(ApplicationEventPublisher publisher, ServerProperties server,
			ResourcePatternResolver resourcePatternResolver,
			AdminServerProperties adminServerProperties) {
		this.publisher = publisher;
		this.server = server;
		this.resourcePatternResolver = resourcePatternResolver;
		this.adminServerProperties = adminServerProperties;
69
	}
70

71 72 73 74
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}
Thomas Bosch committed
75 76

	@Override
77 78
	public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
		if (!hasConverter(converters, MappingJackson2HttpMessageConverter.class)) {
79 80
			ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json()
					.applicationContext(this.applicationContext).build();
81 82 83 84 85 86 87 88 89 90 91 92
			converters.add(new MappingJackson2HttpMessageConverter(objectMapper));
		}
	}

	private boolean hasConverter(List<HttpMessageConverter<?>> converters,
			Class<? extends HttpMessageConverter<?>> clazz) {
		for (HttpMessageConverter<?> converter : converters) {
			if (clazz.isInstance(converter)) {
				return true;
			}
		}
		return false;
Thomas Bosch committed
93 94
	}

95 96
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
97
		registry.addResourceHandler(adminServerProperties.getContextPath() + "/**")
98 99 100 101
				.addResourceLocations("classpath:/META-INF/spring-boot-admin-server-ui/")
				.resourceChain(true)
				.addResolver(new PreferMinifiedFilteringResourceResolver(".min"));

102
		registry.addResourceHandler(adminServerProperties.getContextPath() + "/all-modules.css")
103 104
				.resourceChain(true)
				.addResolver(new ResourcePatternResolvingResourceResolver(resourcePatternResolver,
105
						"classpath*:/META-INF/spring-boot-admin-server-ui/*/module.css"))
106 107
				.addResolver(new ConcatenatingResourceResolver("\n".getBytes()));

108
		registry.addResourceHandler(adminServerProperties.getContextPath() + "/all-modules.js")
109 110 111 112 113
				.resourceChain(true)
				.addResolver(new ResourcePatternResolvingResourceResolver(resourcePatternResolver,
						"classpath*:/META-INF/spring-boot-admin-server-ui/*/module.js"))
				.addResolver(new PreferMinifiedFilteringResourceResolver(".min"))
				.addResolver(new ConcatenatingResourceResolver(";\n".getBytes()));
114 115 116 117
	}

	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
118 119 120
		String contextPath = adminServerProperties.getContextPath();
		if (StringUtils.hasText(contextPath)) {
			registry.addRedirectViewController(contextPath, server.getPath(contextPath) + "/");
121
		}
122
		registry.addViewController(contextPath + "/").setViewName("forward:index.html");
123 124 125 126
	}

	@Bean
	public PrefixHandlerMapping prefixHandlerMapping() {
127 128 129 130
		Map<String, Object> beans = applicationContext
				.getBeansWithAnnotation(AdminController.class);
		PrefixHandlerMapping prefixHandlerMapping = new PrefixHandlerMapping(
				beans.values().toArray(new Object[beans.size()]));
131
		prefixHandlerMapping.setPrefix(adminServerProperties.getContextPath());
132 133 134
		return prefixHandlerMapping;
	}

135 136
	@Bean
	@ConditionalOnMissingBean
137 138
	public RegistryController registryController(ApplicationRegistry applicationRegistry) {
		return new RegistryController(applicationRegistry);
139 140
	}

141 142
	@Bean
	@ConditionalOnMissingBean
143 144
	public JournalController journalController(ApplicationEventJournal applicationEventJournal) {
		return new JournalController(applicationEventJournal);
145 146
	}

147 148
	@EventListener
	public void onClientApplicationRegistered(ClientApplicationRegisteredEvent event) {
149 150 151 152 153 154
		publisher.publishEvent(new RoutesOutdatedEvent());
	}

	@EventListener
	public void onClientApplicationDeregistered(ClientApplicationDeregisteredEvent event) {
		publisher.publishEvent(new RoutesOutdatedEvent());
155 156
	}

Thomas Bosch committed
157
}