JAVA-11420: Dissolve spring-boot-1 and spring-boot-2 inside (#12122)

spring-boot-modules
This commit is contained in:
freelansam
2022-04-28 22:45:45 +05:30
committed by GitHub
parent 2d9fea5406
commit 09095ca210
56 changed files with 85 additions and 1203 deletions

View File

@@ -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)
- [Whats 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)

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View 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);
}
}

View File

@@ -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

View File

@@ -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"));
}
}

View File

@@ -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"));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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");
}
}