diff --git a/spring-boot/src/main/java/com/baeldung/shutdown/Application.java b/spring-boot/src/main/java/com/baeldung/shutdown/Application.java new file mode 100644 index 000000000000..964e092c10d1 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/shutdown/Application.java @@ -0,0 +1,55 @@ +package com.baeldung.shutdown; + +import com.baeldung.autoconfiguration.MySQLAutoconfiguration; +import org.springframework.boot.ExitCodeGenerator; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.system.ApplicationPidFileWriter; +import org.springframework.context.ConfigurableApplicationContext; + +import javax.annotation.security.RolesAllowed; + +@SpringBootApplication(exclude = MySQLAutoconfiguration.class) +public class Application { + + public static void main(String[] args) { + + SpringApplication.run(Application.class, args); +// closeApplication(); +// exitApplication(); +// writePID(); + + } + + private static void closeApplication() { + + ConfigurableApplicationContext ctx = new SpringApplicationBuilder(Application.class).web(false).run(); + System.out.println("Spring Boot application started"); + ctx.getBean(TerminateBean.class); + ctx.close(); + } + + private static void exitApplication() { + + ConfigurableApplicationContext ctx = new SpringApplicationBuilder(Application.class).web(false).run(); + + int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() { + @Override + public int getExitCode() { + // return the error code + return 0; + } + }); + + System.out.println("Exit Spring Boot"); + + System.exit(exitCode); + } + + private static void writePID() { + SpringApplicationBuilder app = new SpringApplicationBuilder(Application.class).web(false); + app.build().addListeners(new ApplicationPidFileWriter("./bin/shutdown.pid")); + app.run(); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/shutdown/ShutdownConfig.java b/spring-boot/src/main/java/com/baeldung/shutdown/ShutdownConfig.java new file mode 100644 index 000000000000..2068f45b7dd3 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/shutdown/ShutdownConfig.java @@ -0,0 +1,15 @@ +package com.baeldung.shutdown; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackages = "com.baeldung.shutdown") +public class ShutdownConfig { + + @Bean + public TerminateBean getTerminateBean() { + return new TerminateBean(); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/shutdown/TerminateBean.java b/spring-boot/src/main/java/com/baeldung/shutdown/TerminateBean.java new file mode 100644 index 000000000000..4f3b81b9207f --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/shutdown/TerminateBean.java @@ -0,0 +1,11 @@ +package com.baeldung.shutdown; + +import javax.annotation.PreDestroy; + +public class TerminateBean { + + @PreDestroy + public void onDestroy() throws Exception { + System.out.println("Spring Container is destroyed!"); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/shutdown/shutdown/ShutdownController.java b/spring-boot/src/main/java/com/baeldung/shutdown/shutdown/ShutdownController.java new file mode 100644 index 000000000000..b0acc1f422ea --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/shutdown/shutdown/ShutdownController.java @@ -0,0 +1,7 @@ +package com.baeldung.shutdown.shutdown; + +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ShutdownController { +} diff --git a/spring-boot/src/main/resources/application.properties b/spring-boot/src/main/resources/application.properties index 059a6c96bec6..203f0ee3c530 100644 --- a/spring-boot/src/main/resources/application.properties +++ b/spring-boot/src/main/resources/application.properties @@ -30,6 +30,7 @@ info.java-vendor = ${java.specification.vendor} security.user.name=admin1 security.user.password=secret1 management.security.role=SUPERUSER +management.endpoint.shutdown.enabled=true logging.level.org.springframework=INFO diff --git a/spring-boot/src/main/resources/shutdown/shutdown.bat b/spring-boot/src/main/resources/shutdown/shutdown.bat new file mode 100644 index 000000000000..2e3bbb50f1d5 --- /dev/null +++ b/spring-boot/src/main/resources/shutdown/shutdown.bat @@ -0,0 +1 @@ +kill $(cat ./bin/shutdown.pid) \ No newline at end of file diff --git a/spring-boot/src/test/java/com/baeldung/shutdown/ShutdownApplicationTest.java b/spring-boot/src/test/java/com/baeldung/shutdown/ShutdownApplicationTest.java new file mode 100644 index 000000000000..7896b9dc096e --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/shutdown/ShutdownApplicationTest.java @@ -0,0 +1,43 @@ +package com.baeldung.shutdown; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +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.junit4.SpringJUnit4ClassRunner; +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.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class) +@AutoConfigureMockMvc +public class ShutdownApplicationTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext wac; + + @Before + public void setup() { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + } + + @Test + @Ignore + public void givenBootApp_whenShutdownEndpoint_thenExit() throws Exception { + + mockMvc.perform( + post("/shutdown")) + .andExpect(status().isOk()); + } +}