BAEL-19751: Move spring-boot-admin into spring-boot-modules
This commit is contained in:
24
spring-boot-modules/spring-boot-admin/spring-boot-admin-server/.gitignore
vendored
Normal file
24
spring-boot-modules/spring-boot-admin/spring-boot-admin-server/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
.nb-gradle/
|
||||
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-boot-admin-server</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>spring-boot-admin-server</name>
|
||||
<description>Spring Boot Admin Server</description>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-boot-admin</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- dependencies used to enable admin server and UI -->
|
||||
<!-- https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-starter-server -->
|
||||
<dependency>
|
||||
<groupId>de.codecentric</groupId>
|
||||
<artifactId>spring-boot-admin-starter-server</artifactId>
|
||||
<version>${spring-boot-admin-server.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--Add login page and logout feature -->
|
||||
<dependency>
|
||||
<groupId>de.codecentric</groupId>
|
||||
<artifactId>spring-boot-admin-server-ui-login</artifactId>
|
||||
<version>${spring-boot-admin-server-ui-login.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.hazelcast</groupId>
|
||||
<artifactId>hazelcast</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--declare the admin server as a client, for self monitoring -->
|
||||
<dependency>
|
||||
<groupId>de.codecentric</groupId>
|
||||
<artifactId>spring-boot-admin-starter-client</artifactId>
|
||||
<version>${spring-boot-admin-starter-client.version}</version>
|
||||
</dependency>
|
||||
<!--mail notifications -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<spring-boot-admin-server.version>2.1.6</spring-boot-admin-server.version>
|
||||
<spring-boot-admin-starter-client.version>2.1.6</spring-boot-admin-starter-client.version>
|
||||
<spring-boot-admin-server-ui-login.version>1.5.7</spring-boot-admin-server-ui-login.version>
|
||||
<spring-boot-maven-plugin.version>2.0.4.RELEASE</spring-boot-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.springbootadminserver;
|
||||
|
||||
import de.codecentric.boot.admin.server.config.EnableAdminServer;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@EnableAdminServer
|
||||
@SpringBootApplication
|
||||
public class SpringBootAdminServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBootAdminServerApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.baeldung.springbootadminserver.configs;
|
||||
|
||||
import com.hazelcast.config.Config;
|
||||
import com.hazelcast.config.EvictionPolicy;
|
||||
import com.hazelcast.config.InMemoryFormat;
|
||||
import com.hazelcast.config.MapConfig;
|
||||
import com.hazelcast.config.MergePolicyConfig;
|
||||
import com.hazelcast.config.TcpIpConfig;
|
||||
import com.hazelcast.map.merge.PutIfAbsentMapMergePolicy;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class HazelcastConfig {
|
||||
|
||||
@Bean
|
||||
public Config hazelcast() {
|
||||
MapConfig eventStoreMap = new MapConfig("spring-boot-admin-event-store").setInMemoryFormat(InMemoryFormat.OBJECT)
|
||||
.setBackupCount(1)
|
||||
.setEvictionPolicy(EvictionPolicy.NONE)
|
||||
.setMergePolicyConfig(new MergePolicyConfig(PutIfAbsentMapMergePolicy.class.getName(), 100));
|
||||
|
||||
MapConfig sentNotificationsMap = new MapConfig("spring-boot-admin-application-store").setInMemoryFormat(InMemoryFormat.OBJECT)
|
||||
.setBackupCount(1)
|
||||
.setEvictionPolicy(EvictionPolicy.LRU)
|
||||
.setMergePolicyConfig(new MergePolicyConfig(PutIfAbsentMapMergePolicy.class.getName(), 100));
|
||||
|
||||
Config config = new Config();
|
||||
config.addMapConfig(eventStoreMap);
|
||||
config.addMapConfig(sentNotificationsMap);
|
||||
config.setProperty("hazelcast.jmx", "true");
|
||||
|
||||
config.getNetworkConfig()
|
||||
.getJoin()
|
||||
.getMulticastConfig()
|
||||
.setEnabled(false);
|
||||
TcpIpConfig tcpIpConfig = config.getNetworkConfig()
|
||||
.getJoin()
|
||||
.getTcpIpConfig();
|
||||
tcpIpConfig.setEnabled(true);
|
||||
tcpIpConfig.setMembers(Collections.singletonList("127.0.0.1"));
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.baeldung.springbootadminserver.configs;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
|
||||
import de.codecentric.boot.admin.server.notify.CompositeNotifier;
|
||||
import de.codecentric.boot.admin.server.notify.LoggingNotifier;
|
||||
import de.codecentric.boot.admin.server.notify.Notifier;
|
||||
import de.codecentric.boot.admin.server.notify.RemindingNotifier;
|
||||
import de.codecentric.boot.admin.server.notify.filter.FilteringNotifier;
|
||||
|
||||
@Configuration
|
||||
public class NotifierConfiguration {
|
||||
private final InstanceRepository repository;
|
||||
private final ObjectProvider<List<Notifier>> otherNotifiers;
|
||||
|
||||
public NotifierConfiguration(InstanceRepository repository, ObjectProvider<List<Notifier>> otherNotifiers) {
|
||||
this.repository = repository;
|
||||
this.otherNotifiers = otherNotifiers;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilteringNotifier filteringNotifier() {
|
||||
CompositeNotifier delegate = new CompositeNotifier(this.otherNotifiers.getIfAvailable(Collections::emptyList));
|
||||
return new FilteringNotifier(delegate, this.repository);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LoggingNotifier notifier() {
|
||||
return new LoggingNotifier(repository);
|
||||
}
|
||||
|
||||
@Primary
|
||||
@Bean(initMethod = "start", destroyMethod = "stop")
|
||||
public RemindingNotifier remindingNotifier() {
|
||||
RemindingNotifier remindingNotifier = new RemindingNotifier(filteringNotifier(), repository);
|
||||
remindingNotifier.setReminderPeriod(Duration.ofMinutes(5));
|
||||
remindingNotifier.setCheckReminderInverval(Duration.ofSeconds(60));
|
||||
return remindingNotifier;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.baeldung.springbootadminserver.configs;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
||||
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
|
||||
import de.codecentric.boot.admin.server.config.AdminServerProperties;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
private final AdminServerProperties adminServer;
|
||||
|
||||
public WebSecurityConfig(AdminServerProperties adminServer) {
|
||||
this.adminServer = adminServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
|
||||
successHandler.setTargetUrlParameter("redirectTo");
|
||||
successHandler.setDefaultTargetUrl(this.adminServer.getContextPath() + "/");
|
||||
|
||||
http.authorizeRequests()
|
||||
.antMatchers(this.adminServer.getContextPath() + "/assets/**")
|
||||
.permitAll()
|
||||
.antMatchers(this.adminServer.getContextPath() + "/login")
|
||||
.permitAll()
|
||||
.anyRequest()
|
||||
.authenticated()
|
||||
.and()
|
||||
.formLogin()
|
||||
.loginPage(this.adminServer.getContextPath() + "/login")
|
||||
.successHandler(successHandler)
|
||||
.and()
|
||||
.logout()
|
||||
.logoutUrl(this.adminServer.getContextPath() + "/logout")
|
||||
.and()
|
||||
.httpBasic()
|
||||
.and()
|
||||
.csrf()
|
||||
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
|
||||
.ignoringRequestMatchers(new AntPathRequestMatcher(this.adminServer.getContextPath() + "/instances", HttpMethod.POST.toString()), new AntPathRequestMatcher(this.adminServer.getContextPath() + "/instances/*", HttpMethod.DELETE.toString()),
|
||||
new AntPathRequestMatcher(this.adminServer.getContextPath() + "/actuator/**"))
|
||||
.and()
|
||||
.rememberMe()
|
||||
.key(UUID.randomUUID()
|
||||
.toString())
|
||||
.tokenValiditySeconds(1209600);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
spring.application.name=spring-boot-admin-server
|
||||
|
||||
spring.security.user.name=admin
|
||||
spring.security.user.password=admin
|
||||
|
||||
#configs to connect to self register the admin server as a client
|
||||
spring.boot.admin.client.url=http://localhost:8080
|
||||
spring.boot.admin.client.username=${spring.security.user.name}
|
||||
spring.boot.admin.client.password=${spring.security.user.password}
|
||||
|
||||
#configs to give secured server info
|
||||
spring.boot.admin.client.instance.metadata.user.name=${spring.security.user.name}
|
||||
spring.boot.admin.client.instance.metadata.user.password=${spring.security.user.password}
|
||||
|
||||
management.endpoints.web.exposure.include=*
|
||||
management.endpoint.health.show-details=always
|
||||
|
||||
#mail notifications
|
||||
spring.mail.host=
|
||||
spring.mail.username=
|
||||
spring.mail.password=
|
||||
spring.mail.port=
|
||||
spring.mail.properties.mail.smtp.auth=
|
||||
spring.mail.properties.mail.smtp.starttls.enable=
|
||||
|
||||
spring.boot.admin.notify.mail.to=
|
||||
|
||||
#hipchat notifications
|
||||
#spring.boot.admin.notify.hipchat.auth-token=<generated_token>
|
||||
#spring.boot.admin.notify.hipchat.room-id=<room-id>
|
||||
#spring.boot.admin.notify.hipchat.url=https://youcompany.hipchat.com/v2/
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<jmxConfigurator />
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%date [%thread] %-5level %logger{25} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.springbootadminserver;
|
||||
|
||||
import com.baeldung.springbootadminserver.configs.HazelcastConfig;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = { HazelcastConfig.class }, webEnvironment = NONE)
|
||||
public class HazelcastConfigIntegrationTest {
|
||||
|
||||
@Autowired private ApplicationContext applicationContext;
|
||||
|
||||
@Test
|
||||
public void whenApplicationContextStarts_HazelcastConfigBeanExists() {
|
||||
assertNotEquals(applicationContext.getBean("hazelcast"), null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.baeldung.springbootadminserver;
|
||||
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.springbootadminserver.configs.NotifierConfiguration;
|
||||
|
||||
import de.codecentric.boot.admin.server.notify.Notifier;
|
||||
import de.codecentric.boot.admin.server.notify.RemindingNotifier;
|
||||
import de.codecentric.boot.admin.server.notify.filter.FilteringNotifier;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = { NotifierConfiguration.class, SpringBootAdminServerApplication.class }, webEnvironment = NONE)
|
||||
public class NotifierConfigurationIntegrationTest {
|
||||
|
||||
@Autowired private ApplicationContext applicationContext;
|
||||
|
||||
@Test
|
||||
public void whenApplicationContextStart_ThenNotifierBeanExists() {
|
||||
Notifier notifier = (Notifier) applicationContext.getBean("notifier");
|
||||
assertNotEquals(notifier, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenApplicationContextStart_ThenFilteringNotifierBeanExists() {
|
||||
FilteringNotifier filteringNotifier = (FilteringNotifier) applicationContext.getBean("filteringNotifier");
|
||||
assertNotEquals(filteringNotifier, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenApplicationContextStart_ThenRemindingNotifierBeanExists() {
|
||||
RemindingNotifier remindingNotifier = (RemindingNotifier) applicationContext.getBean("remindingNotifier");
|
||||
assertNotEquals(remindingNotifier, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.baeldung.springbootadminserver;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class WebSecurityConfigIntegrationTest {
|
||||
|
||||
@Autowired WebApplicationContext wac;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mockMvc = MockMvcBuilders
|
||||
.webAppContextSetup(wac)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenApplicationStarts_ThenGetLoginPageWithSuccess() throws Exception {
|
||||
mockMvc
|
||||
.perform(get("/login.html"))
|
||||
.andExpect(status().is2xxSuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFormLoginAttempted_ThenSuccess() throws Exception {
|
||||
mockMvc.perform(formLogin("/login")
|
||||
.user("admin")
|
||||
.password("admin"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFormLoginWithSuccess_ThenApiEndpointsAreAccessible() throws Exception {
|
||||
mockMvc.perform(formLogin("/login")
|
||||
.user("admin")
|
||||
.password("admin"));
|
||||
|
||||
mockMvc
|
||||
.perform(get("/applications/"))
|
||||
.andExpect(status().is2xxSuccessful());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenHttpBasicAttempted_ThenSuccess() throws Exception {
|
||||
mockMvc.perform(get("/actuator/env").with(httpBasic("admin", "admin")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInvalidHttpBasicAttempted_ThenUnauthorized() throws Exception {
|
||||
mockMvc
|
||||
.perform(get("/actuator/env").with(httpBasic("admin", "invalid")))
|
||||
.andExpect(unauthenticated());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.baeldung;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.springbootadminserver.SpringBootAdminServerApplication;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = SpringBootAdminServerApplication.class)
|
||||
public class SpringContextTest {
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user