Merge pull request #9868 from mona-mohamadinia/BAEL-4528

BAEL-4528: Custom Health Indicators in Spring Boot
This commit is contained in:
Jonathan Cook 2020-08-21 16:40:55 +02:00 committed by GitHub
commit 0c657fdd79
9 changed files with 172 additions and 1 deletions

View File

@ -43,6 +43,9 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.baeldung.probes.ProbesApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>

View File

@ -0,0 +1,30 @@
package com.baeldung.health;
import org.springframework.boot.actuate.health.HttpCodeStatusMapper;
import org.springframework.boot.actuate.health.Status;
import org.springframework.stereotype.Component;
@Component
public class CustomStatusCodeMapper implements HttpCodeStatusMapper {
@Override
public int getStatusCode(Status status) {
if (status == Status.DOWN) {
return 500;
}
if (status == Status.OUT_OF_SERVICE) {
return 503;
}
if (status == Status.UNKNOWN) {
return 500;
}
if (status.getCode().equals("WARNING")) {
return 500;
}
return 200;
}
}

View File

@ -0,0 +1,12 @@
package com.baeldung.health;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HealthApplication {
public static void main(String[] args) {
SpringApplication.run(HealthApplication.class, args);
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.health;
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
@Component
@ConditionalOnEnabledHealthIndicator("random")
public class RandomHealthIndicator implements HealthIndicator {
@Override
public Health health() {
double chance = ThreadLocalRandom.current().nextDouble();
Health.Builder status = Health.up();
if (chance > 0.9) {
status = Health.down(new RuntimeException("Bad Luck"));
}
Map<String, Object> details = new HashMap<>();
details.put("chance", chance);
details.put("strategy", "thread-local");
return status.withDetails(details).build();
}
}

View File

@ -0,0 +1,14 @@
package com.baeldung.health;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
@Component
public class WarningHealthIndicator implements HealthIndicator {
@Override
public Health health() {
return Health.status("WARNING").build();
}
}

View File

@ -1 +1,5 @@
management.health.probes.enabled=true
management.health.probes.enabled=true
management.endpoint.health.show-details=always
management.endpoint.health.status.http-mapping.down=500
management.endpoint.health.status.http-mapping.out_of_service=503
management.endpoint.health.status.http-mapping.warning=500

View File

@ -0,0 +1,26 @@
package com.baeldung.health;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
@TestPropertySource(properties = "management.health.random.enabled=false")
class DisabledRandomHealthIndicatorIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Test
void givenADisabledIndicator_whenSendingRequest_thenReturns404() throws Exception {
mockMvc.perform(get("/actuator/health/random"))
.andExpect(status().isNotFound());
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.health;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
@SpringBootTest
@AutoConfigureMockMvc
class RandomHealthIndicatorIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Test
void givenRandomIndicator_whenCallingTheAPI_thenReturnsExpectedDetails() throws Exception {
mockMvc.perform(get("/actuator/health/random"))
.andExpect(jsonPath("$.status").exists())
.andExpect(jsonPath("$.details.strategy").value("thread-local"))
.andExpect(jsonPath("$.details.chance").exists());
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.health;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
class WarningHealthIndicatorIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Test
void givenCustomMapping_whenCallingTheAPI_thenTheStatusCodeIsAsExpected() throws Exception {
mockMvc.perform(get("/actuator/health/warning"))
.andExpect(jsonPath("$.status").value("WARNING"))
.andExpect(status().isInternalServerError());
}
}