Merge branch 'master' of https://github.com/Maiklins/tutorials into BAEL-20873-move-spring-boot-kotlin

 Conflicts:
	spring-boot-modules/pom.xml
This commit is contained in:
mikr
2020-02-01 16:42:36 +01:00
228 changed files with 846 additions and 880 deletions
+8
View File
@@ -14,11 +14,19 @@
</parent>
<modules>
<module>spring-boot-admin</module>
<module>spring-boot-artifacts</module>
<module>spring-boot-autoconfiguration</module>
<module>spring-boot-camel</module>
<module>spring-boot-custom-starter</module>
<module>spring-boot-crud</module>
<module>spring-boot-data</module>
<!-- <module>spring-boot-gradle</module> --> <!-- Not a maven project -->
<module>spring-boot-keycloak</module>
<module>spring-boot-logging-log4j2</module>
<module>spring-boot-kotlin</module>
<module>spring-boot-mvc-birt</module>
<module>spring-boot-nashorn</module>
<module>spring-boot-properties</module>
<module>spring-boot-springdoc</module>
<module>spring-boot-testing</module>
@@ -0,0 +1,27 @@
## Spring Boot Admin
This module contains articles about Spring Boot Admin
## 1. Spring Boot Admin Server
* mvn clean install
* mvn spring-boot:run
* starts on port 8080
* login with admin/admin
* to activate mail notifications uncomment the starter mail dependency
and the mail configuration from application.properties
* add some real credentials if you want the app to send emails
* to activate Hipchat notifications proceed same as for email
## 2. Spring Boot App Client
* mvn clean install
* mvn spring-boot:run
* starts on port 8081
* basic auth client/client
### Relevant Articles:
- [A Guide to Spring Boot Admin](https://www.baeldung.com/spring-boot-admin)
- [Changing the Logging Level at the Runtime for a Spring Boot Application](https://www.baeldung.com/spring-boot-changing-log-level-at-runtime)
@@ -0,0 +1,26 @@
<?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</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-admin</name>
<packaging>pom</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
</parent>
<modules>
<module>spring-boot-admin-server</module>
<module>spring-boot-admin-client</module>
</modules>
<properties>
<spring-boot.version>2.1.9.RELEASE</spring-boot.version>
</properties>
</project>
@@ -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,65 @@
<?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-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-admin-client</name>
<packaging>jar</packaging>
<description>Spring Boot Admin Client</description>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${spring-boot-admin-starter-client.version}</version>
</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>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<spring-boot-admin-starter-client.version>2.1.6</spring-boot-admin-starter-client.version>
<spring-boot-maven-plugin.version>2.0.4.RELEASE</spring-boot-maven-plugin.version>
</properties>
</project>
@@ -0,0 +1,12 @@
package com.baeldung.springbootadminclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootAdminClientApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAdminClientApplication.class, args);
}
}
@@ -0,0 +1,20 @@
#basic auth creddentials
spring.security.user.name=client
spring.security.user.password=client
#configs to connect to a secured server
spring.boot.admin.client.url=http://localhost:8080
#spring.boot.admin.client.instance.service-base-url=http://localhost:8081
spring.boot.admin.client.username=admin
spring.boot.admin.client.password=admin
#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}
#app config
spring.application.name=spring-boot-admin-client
server.port=8081
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
@@ -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,55 @@
package com.baeldung.springbootadminclient;
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.core.env.Environment;
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.junit.Assert.assertEquals;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
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.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
public class SpringBootAdminClientApplicationIntegrationTest {
@Autowired Environment environment;
@Autowired WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
mockMvc = MockMvcBuilders
.webAppContextSetup(wac)
.build();
}
@Test
public void whenEnvironmentAvailable_ThenAdminServerPropertiesExist() {
assertEquals(environment.getProperty("spring.boot.admin.client.url"), "http://localhost:8080");
assertEquals(environment.getProperty("spring.boot.admin.client.username"), "admin");
assertEquals(environment.getProperty("spring.boot.admin.client.password"), "admin");
}
@Test
public void whenHttpBasicAttempted_ThenSuccess() throws Exception {
mockMvc.perform(get("/actuator/env").with(httpBasic("client", "client")));
}
@Test
public void whenInvalidHttpBasicAttempted_ThenUnauthorized() throws Exception {
mockMvc
.perform(get("/actuator/env").with(httpBasic("client", "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.springbootadminclient.SpringBootAdminClientApplication;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootAdminClientApplication.class)
public class SpringContextTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
}
@@ -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() {
}
}
@@ -0,0 +1,5 @@
/target/
.settings/
.classpath
.project
@@ -0,0 +1,12 @@
## Spring Boot Auto Configuration
This module contains articles about Spring Boot Auto Configuration
### The Course
The "REST With Spring" Classes: http://bit.ly/restwithspring
### Relevant Articles:
- [Create a Custom Auto-Configuration with Spring Boot](https://www.baeldung.com/spring-boot-custom-auto-configuration)
- [Guide to ApplicationContextRunner in Spring Boot](https://www.baeldung.com/spring-boot-context-runner)
- [A Guide to Spring Boot Configuration Metadata](https://www.baeldung.com/spring-boot-configuration-metadata)
@@ -0,0 +1,118 @@
<?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-autoconfiguration</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-autoconfiguration</name>
<packaging>war</packaging>
<description>This is simple boot application demonstrating a custom auto-configuration</description>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.1.6.RELEASE</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>spring-boot</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>autoconfiguration</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludes>
<exclude>**/*LiveTest.java</exclude>
<exclude>**/*IntegrationTest.java</exclude>
<exclude>**/*IntTest.java</exclude>
</excludes>
<includes>
<include>**/AutoconfigurationTest.java</include>
</includes>
</configuration>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<test.mime>json</test.mime>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<properties>
<jquery.version>3.1.1</jquery.version>
<bootstrap.version>3.3.7-1</bootstrap.version>
<subethasmtp.version>3.1.7</subethasmtp.version>
<tomee-servlet-api.version>8.5.11</tomee-servlet-api.version>
</properties>
</project>
@@ -0,0 +1,118 @@
package com.baeldung.autoconfiguration;
import java.util.Arrays;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionMessage.Style;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnResource;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.util.ClassUtils;
@Configuration
@ConditionalOnClass(DataSource.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@PropertySource("classpath:mysql.properties")
public class MySQLAutoconfiguration {
@Autowired
private Environment env;
@Bean
@ConditionalOnProperty(name = "usemysql", havingValue = "local")
@ConditionalOnMissingBean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/myDb?createDatabaseIfNotExist=true&&serverTimezone=UTC");
dataSource.setUsername("mysqluser");
dataSource.setPassword("mysqlpass");
return dataSource;
}
@Bean(name = "dataSource")
@ConditionalOnProperty(name = "usemysql", havingValue = "custom")
@ConditionalOnMissingBean
public DataSource dataSource2() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl(env.getProperty("mysql.url"));
dataSource.setUsername(env.getProperty("mysql.user") != null ? env.getProperty("mysql.user") : "");
dataSource.setPassword(env.getProperty("mysql.pass") != null ? env.getProperty("mysql.pass") : "");
return dataSource;
}
@Bean
@ConditionalOnBean(name = "dataSource")
@ConditionalOnMissingBean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("com.baeldung.autoconfiguration.example");
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
if (additionalProperties() != null) {
em.setJpaProperties(additionalProperties());
}
return em;
}
@Bean
@ConditionalOnMissingBean(type = "JpaTransactionManager")
JpaTransactionManager transactionManager(final EntityManagerFactory entityManagerFactory) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
@ConditionalOnResource(resources = "classpath:mysql.properties")
@Conditional(HibernateCondition.class)
final Properties additionalProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("mysql-hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("mysql-hibernate.dialect"));
hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("mysql-hibernate.show_sql") != null ? env.getProperty("mysql-hibernate.show_sql") : "false");
return hibernateProperties;
}
static class HibernateCondition extends SpringBootCondition {
private static final String[] CLASS_NAMES = { "org.hibernate.ejb.HibernateEntityManager", "org.hibernate.jpa.HibernateEntityManager" };
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
ConditionMessage.Builder message = ConditionMessage.forCondition("Hibernate");
return Arrays.stream(CLASS_NAMES).filter(className -> ClassUtils.isPresent(className, context.getClassLoader())).map(className -> ConditionOutcome.match(message.found("class").items(Style.NORMAL, className))).findAny()
.orElseGet(() -> ConditionOutcome.noMatch(message.didNotFind("class", "classes").items(Style.NORMAL, Arrays.asList(CLASS_NAMES))));
}
}
}
@@ -0,0 +1,15 @@
package com.baeldung.autoconfiguration.annotationprocessor;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
import com.baeldung.autoconfiguration.MySQLAutoconfiguration;
@EnableAutoConfiguration(exclude = { MySQLAutoconfiguration.class})
@ComponentScan(basePackageClasses = {DatabaseProperties.class})
public class AnnotationProcessorApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(AnnotationProcessorApplication.class).run();
}
}
@@ -0,0 +1,73 @@
package com.baeldung.autoconfiguration.annotationprocessor;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "database")
public class DatabaseProperties {
public static class Server {
/**
* The IP of the database server
*/
private String ip;
/**
* The Port of the database server.
* The Default value is 443.
* The allowed values are in the range 400-4000.
*/
@Min(400)
@Max(800)
private int port = 443;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
private String username;
private String password;
private Server server;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Server getServer() {
return server;
}
public void setServer(Server server) {
this.server = server;
}
}
@@ -0,0 +1,12 @@
package com.baeldung.autoconfiguration.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AutoconfigurationApplication {
public static void main(String[] args) {
SpringApplication.run(AutoconfigurationApplication.class, args);
}
}
@@ -0,0 +1,27 @@
package com.baeldung.autoconfiguration.example;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class MyUser {
@Id
private String email;
public MyUser() {
}
public MyUser(String email) {
super();
this.email = email;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

Some files were not shown because too many files have changed in this diff Show More