AdminServerWebConfiguration.java 6.21 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 19

import java.util.List;

20
import org.springframework.beans.factory.annotation.Autowired;
21
import org.springframework.beans.factory.annotation.Value;
22
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
23
import org.springframework.boot.context.properties.ConfigurationProperties;
24
import org.springframework.context.ApplicationContext;
25
import org.springframework.context.ApplicationContextAware;
26
import org.springframework.context.ApplicationEventPublisher;
Thomas Bosch committed
27
import org.springframework.context.annotation.Bean;
Thomas Bosch committed
28
import org.springframework.context.annotation.Configuration;
29
import org.springframework.context.event.EventListener;
30
import org.springframework.http.HttpStatus;
Thomas Bosch committed
31
import org.springframework.http.converter.HttpMessageConverter;
32
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
Thomas Bosch committed
33
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
34
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
35
import org.springframework.web.client.DefaultResponseErrorHandler;
36
import org.springframework.web.client.RestTemplate;
Thomas Bosch committed
37 38
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

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

41
import de.codecentric.boot.admin.controller.JournalController;
Thomas Bosch committed
42
import de.codecentric.boot.admin.controller.RegistryController;
43
import de.codecentric.boot.admin.event.ClientApplicationDeregisteredEvent;
44
import de.codecentric.boot.admin.event.ClientApplicationRegisteredEvent;
45
import de.codecentric.boot.admin.event.RoutesOutdatedEvent;
46 47 48
import de.codecentric.boot.admin.journal.ApplicationEventJournal;
import de.codecentric.boot.admin.journal.store.JournaledEventStore;
import de.codecentric.boot.admin.journal.store.SimpleJournaledEventStore;
Johannes Stelzer committed
49 50 51
import de.codecentric.boot.admin.registry.ApplicationIdGenerator;
import de.codecentric.boot.admin.registry.ApplicationRegistry;
import de.codecentric.boot.admin.registry.HashingApplicationUrlIdGenerator;
52
import de.codecentric.boot.admin.registry.StatusUpdater;
Johannes Stelzer committed
53
import de.codecentric.boot.admin.registry.store.ApplicationStore;
54
import de.codecentric.boot.admin.registry.store.SimpleApplicationStore;
Thomas Bosch committed
55

Thomas Bosch committed
56
@Configuration
57 58
public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter
		implements ApplicationContextAware {
59

60 61
	private ApplicationContext applicationContext;

62 63 64 65 66 67 68 69 70
	@Autowired
	private ApplicationEventPublisher publisher;

	@Autowired
	private ApplicationStore applicationStore;

	@Value("${spring.boot.admin.monitor.period:10000}")
	private long monitorPeriod;

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
	}

Thomas Bosch committed
95
	/**
96
	 * @return Controller with REST-API for spring-boot applications to register itself.
Thomas Bosch committed
97
	 */
Thomas Bosch committed
98
	@Bean
99 100
	public RegistryController registryController() {
		return new RegistryController(applicationRegistry());
Thomas Bosch committed
101 102
	}

Thomas Bosch committed
103
	/**
104
	 * @return Default registry for all registered application.
Thomas Bosch committed
105
	 */
Thomas Bosch committed
106
	@Bean
107 108
	public ApplicationRegistry applicationRegistry() {
		return new ApplicationRegistry(applicationStore, applicationIdGenerator());
Johannes Stelzer committed
109 110 111
	}

	/**
112
	 * @return Default applicationId Generator
Johannes Stelzer committed
113 114 115
	 */
	@Bean
	@ConditionalOnMissingBean
116
	public ApplicationIdGenerator applicationIdGenerator() {
Johannes Stelzer committed
117 118 119
		return new HashingApplicationUrlIdGenerator();
	}

120 121 122
	@Bean
	@ConditionalOnMissingBean
	@ConfigurationProperties("spring.boot.admin.monitor")
123
	public StatusUpdater statusUpdater() {
124
		RestTemplate template = new RestTemplate();
125 126 127 128 129 130 131
		template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
		template.setErrorHandler(new DefaultResponseErrorHandler() {
			@Override
			protected boolean hasError(HttpStatus statusCode) {
				return false;
			}
		});
132
		return new StatusUpdater(template, applicationStore);
133 134
	}

135 136 137
	@EventListener
	public void onClientApplicationRegistered(ClientApplicationRegisteredEvent event) {
		statusUpdater().updateStatus(event.getApplication());
138 139 140 141 142 143
		publisher.publishEvent(new RoutesOutdatedEvent());
	}

	@EventListener
	public void onClientApplicationDeregistered(ClientApplicationDeregisteredEvent event) {
		publisher.publishEvent(new RoutesOutdatedEvent());
144 145 146
	}

	@Bean
147
	public ScheduledTaskRegistrar updateTaskRegistrar() {
148
		ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar();
149 150

		registrar.addFixedRateTask(new Runnable() {
151 152
			@Override
			public void run() {
153
				statusUpdater().updateStatusForAllApplications();
154
			}
155
		}, monitorPeriod);
156 157 158 159

		return registrar;
	}

160 161
	@Bean
	@ConditionalOnMissingBean
162 163
	public ApplicationEventJournal applicationEventJournal() {
		return new ApplicationEventJournal(journaledEventStore());
164 165 166 167 168 169 170 171 172 173
	}

	@Bean
	@ConditionalOnMissingBean
	public JournaledEventStore journaledEventStore() {
		return new SimpleJournaledEventStore();
	}

	@Bean
	@ConditionalOnMissingBean
174 175
	public JournalController journalController() {
		return new JournalController(applicationEventJournal());
176 177
	}

178 179 180 181 182
	@Bean
	@ConditionalOnMissingBean
	public ApplicationStore applicationStore() {
		return new SimpleApplicationStore();
	}
183

Thomas Bosch committed
184
}