JAVA-11420: Dissolve spring-boot-1 and spring-boot-2 inside (#12122)
spring-boot-modules
This commit is contained in:
@@ -7,3 +7,4 @@ This module contains articles about Spring 4
|
||||
- [Configuring a Hikari Connection Pool with Spring Boot](https://www.baeldung.com/spring-boot-hikari)
|
||||
- [Spring JSON-P with Jackson](https://www.baeldung.com/spring-jackson-jsonp)
|
||||
- [What’s New in Spring 4.3?](https://www.baeldung.com/whats-new-in-spring-4-3)
|
||||
- [Spring Boot Actuator](https://www.baeldung.com/spring-boot-actuators)
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.actuator;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class CustomEndpoint implements Endpoint<List<String>> {
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "customEndpoint";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSensitive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> invoke() {
|
||||
// Custom logic to build the output
|
||||
List<String> messages = new ArrayList<>();
|
||||
messages.add("This is message 1");
|
||||
messages.add("This is message 2");
|
||||
return messages;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.actuator;
|
||||
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("myHealthCheck")
|
||||
public class HealthCheck implements HealthIndicator {
|
||||
|
||||
@Override
|
||||
public Health health() {
|
||||
int errorCode = check(); // perform some specific health check
|
||||
if (errorCode != 0) {
|
||||
return Health.down().withDetail("Error Code", errorCode).build();
|
||||
}
|
||||
return Health.up().build();
|
||||
}
|
||||
|
||||
public int check() {
|
||||
// Our logic to check health
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.baeldung.actuator;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.CounterService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Service
|
||||
public class LoginServiceImpl {
|
||||
|
||||
private final CounterService counterService;
|
||||
|
||||
public LoginServiceImpl(CounterService counterService) {
|
||||
this.counterService = counterService;
|
||||
}
|
||||
|
||||
public boolean login(String userName, char[] password) {
|
||||
boolean success;
|
||||
if (userName.equals("admin") && Arrays.equals("secret".toCharArray(), password)) {
|
||||
counterService.increment("counter.login.success");
|
||||
success = true;
|
||||
} else {
|
||||
counterService.increment("counter.login.failure");
|
||||
success = false;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
}
|
||||
13
spring-4/src/main/java/com/baeldung/actuator/SpringBoot.java
Normal file
13
spring-4/src/main/java/com/baeldung/actuator/SpringBoot.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.actuator;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringBoot {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBoot.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,3 +3,24 @@ feature.new.foo=Y
|
||||
last.active.after=2018-03-14T00:00:00Z
|
||||
first.active.after=2999-03-15T00:00:00Z
|
||||
logging.level.org.flips=info
|
||||
|
||||
#actuator properties
|
||||
### server port
|
||||
server.port=8080
|
||||
#port used to expose actuator
|
||||
management.port=8081
|
||||
#CIDR allowed to hit actuator
|
||||
management.address=127.0.0.1
|
||||
# Actuator Configuration
|
||||
# customize /beans endpoint
|
||||
endpoints.beans.id=springbeans
|
||||
endpoints.beans.sensitive=false
|
||||
endpoints.beans.enabled=true
|
||||
# for the Spring Boot version 1.5.0 and above, we have to disable security to expose the health endpoint fully for unauthorized access.
|
||||
# see: https://docs.spring.io/spring-boot/docs/1.5.x/reference/html/production-ready-monitoring.html
|
||||
management.security.enabled=false
|
||||
endpoints.health.sensitive=false
|
||||
# customize /info endpoint
|
||||
info.app.name=Spring Sample Application
|
||||
info.app.description=This is my first spring boot application
|
||||
info.app.version=1.0.0
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.baeldung.actuator;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.LocalManagementPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.hasItems;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = "management.port=0")
|
||||
public class CustomEndpointIntegrationTest {
|
||||
|
||||
@LocalManagementPort
|
||||
private int port;
|
||||
|
||||
private RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenActuatorCustomEndpointWorks() throws IOException {
|
||||
ResponseEntity<String> entity = restTemplate.getForEntity("http://localhost:" + port + "/customEndpoint", String.class);
|
||||
|
||||
assertThat(entity.getStatusCode(), is(HttpStatus.OK));
|
||||
|
||||
List<String> response = objectMapper.readValue(entity.getBody(), new TypeReference<ArrayList<String>>() {
|
||||
});
|
||||
|
||||
assertThat(response, hasItems("This is message 1", "This is message 2"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.baeldung.actuator;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.LocalManagementPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.collection.IsMapContaining.hasEntry;
|
||||
import static org.hamcrest.collection.IsMapContaining.hasKey;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = "management.port=0")
|
||||
public class HealthCheckIntegrationTest {
|
||||
|
||||
@LocalManagementPort
|
||||
private int port;
|
||||
|
||||
private RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenActuatorHealthEndpointWorks() throws IOException {
|
||||
ResponseEntity<String> entity = restTemplate.getForEntity("http://localhost:" + port + "/health", String.class);
|
||||
|
||||
assertThat(entity.getStatusCode(), is(HttpStatus.OK));
|
||||
|
||||
Map<String, Object> response = objectMapper.readValue(entity.getBody(), new TypeReference<LinkedHashMap<String, Object>>() {
|
||||
});
|
||||
|
||||
assertThat(response, hasEntry("status", "UP"));
|
||||
assertThat(response, hasKey("myHealthCheck"));
|
||||
assertThat(response, hasKey("diskSpace"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.actuator;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class HealthCheckUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenCheckMethodReturnsZero_thenHealthMethodReturnsStatusUP() {
|
||||
HealthCheck healthCheck = Mockito.spy(new HealthCheck());
|
||||
when(healthCheck.check()).thenReturn(0);
|
||||
Health health = healthCheck.health();
|
||||
|
||||
assertThat(health.getStatus(), is(Status.UP));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCheckMethodReturnsOtherThanZero_thenHealthMethodReturnsStatusDOWN() {
|
||||
HealthCheck healthCheck = Mockito.spy(new HealthCheck());
|
||||
when(healthCheck.check()).thenReturn(-1);
|
||||
Health health = healthCheck.health();
|
||||
|
||||
assertThat(health.getStatus(), is(Status.DOWN));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.baeldung.actuator;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.LocalManagementPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasEntry;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = "management.port=0")
|
||||
public class LoginServiceIntegrationTest {
|
||||
|
||||
@LocalManagementPort
|
||||
private int port;
|
||||
|
||||
@Autowired
|
||||
private LoginServiceImpl loginService;
|
||||
|
||||
private RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Test
|
||||
public void whenLoginIsAdmin_thenSuccessCounterIsIncremented() throws IOException {
|
||||
boolean success = loginService.login("admin", "secret".toCharArray());
|
||||
ResponseEntity<String> entity = restTemplate.getForEntity("http://localhost:" + port + "/metrics", String.class);
|
||||
Map<String, Object> response = objectMapper.readValue(entity.getBody(), new TypeReference<HashMap<String, Object>>() {
|
||||
});
|
||||
|
||||
assertThat(success, is(true));
|
||||
assertThat(entity.getStatusCode(), is(HttpStatus.OK));
|
||||
assertThat(response, hasEntry("counter.login.success", 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenLoginIsNotAdmin_thenFailureCounterIsIncremented() throws IOException {
|
||||
boolean success = loginService.login("user", "notsecret".toCharArray());
|
||||
ResponseEntity<String> entity = restTemplate.getForEntity("http://localhost:" + port + "/metrics", String.class);
|
||||
Map<String, Object> response = objectMapper.readValue(entity.getBody(), new TypeReference<HashMap<String, Object>>() {
|
||||
});
|
||||
|
||||
assertThat(success, is(false));
|
||||
assertThat(entity.getStatusCode(), is(HttpStatus.OK));
|
||||
assertThat(response, hasEntry("counter.login.failure", 1));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.baeldung.actuator;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.metrics.CounterService;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = LoginServiceImpl.class)
|
||||
public class LoginServiceUnitTest {
|
||||
|
||||
@MockBean
|
||||
CounterService counterService;
|
||||
|
||||
@Autowired
|
||||
LoginServiceImpl loginService;
|
||||
|
||||
@Test
|
||||
public void whenLoginUserIsAdmin_thenSuccessCounterIsIncremented() {
|
||||
boolean loginResult = loginService.login("admin", "secret".toCharArray());
|
||||
assertThat(loginResult, is(true));
|
||||
verify(counterService, times(1)).increment("counter.login.success");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenLoginUserIsNotAdmin_thenFailureCounterIsIncremented() {
|
||||
boolean loginResult = loginService.login("user", "notsecret".toCharArray());
|
||||
assertThat(loginResult, is(false));
|
||||
verify(counterService, times(1)).increment("counter.login.failure");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user