Controlling the application life cycle

Controlling the application life cycle is a common requirement for your services to be able to bootstrap some external resources or verify the status of your components. One simple strategy, borrowed from the Java Enterprise API, is to include the Undertow extension (or any upper layer, such as rest services) so that you can leverage ServletContextListener, which is notified when a web application is created or destroyed. Here is a minimal implementation of it:

public final class ContextListener implements ServletContextListener {

private ServletContext context = null;

public void contextInitialized(ServletContextEvent event) {
context = event.getServletContext();
System.out.println("Web application started!");

}
public void contextDestroyed(ServletContextEvent event) {
context = event.getServletContext();
System.out.println("Web application stopped!");

}
}

Although it is perfectly fine to reuse this strategy in a Quarkus web application, it is recommended to use this approach for any kind of Quarkus service. This can be done by observing the io.quarkus.runtime.StartupEvent and io.quarkus.runtime.ShutdownEvent events. Additionally, in CDI applications, you can observe an event with the @Initialized(ApplicationScoped.class) qualifier, which is fired when the application context is initialized. This can be particularly useful for bootstrapping resources such as databases, which are required before the configuration is read by Quarkus.

To see a practical example of this, check the source code that's available in the Chapter08/lifecycle folder of this book's GitHub repository. As usual, it's advised to import the project into your IDE before you move on. The purpose of this example is to show you how to replace the PostgreSQL database, in our customer service, with the H2 database (https://www.h2database.com/).

Starting with the configuration, the life cycle project doesn't contain the PostgreSQL JDBC dependency anymore. To replace this, the following one has been included:

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
</dependency>

To test our customer service, we have included two H2 database configuration profiles: one that's bound to the dev profile and one that's bound to the test profile:

%dev.quarkus.datasource.url=jdbc:h2:tcp://localhost:19092/mem:test
%test.quarkus.datasource.url=jdbc:h2:tcp://localhost/mem:test
quarkus.datasource.driver=org.h2.Driver

To bind the H2 database before the application context is started, we can use the following DBLifeCycleBean class:

@ApplicationScoped
public class DBLifeCycleBean {

protected final Logger log =
LoggerFactory.getLogger(this.getClass());

// H2 Database
private Server tcpServer;

public void observeContextInit(@Observes
@Initialized(ApplicationScoped.class) Object event) {
try {
tcpServer = Server.createTcpServer("-tcpPort",
"19092", "-tcpAllowOthers").start();
log.info("H2 database started in TCP server
mode on Port 19092"
);
} catch (SQLException e) {

throw new RuntimeException(e);

}
}
void onStart(@Observes StartupEvent ev) {
log.info("Application is starting");
}

void onStop(@Observes ShutdownEvent ev) {
if (tcpServer != null) {
tcpServer.stop();
log.info("H2 database was shut down");
tcpServer = null;
}
}
}

This class is able to intercept the following events:

  • Context startup: This is captured through the observeContextInit method. The database is bootstrapped in this method.
  • Application startup: This is captured through the onStart method. We are simply performing some logs when this event is fired.
  • Application shutdown: This is captured through the onStop method. We are shutting down the database in this method.

Now, you can start Quarkus in the dev profile as usual with the following command:

mvn quarkus:dev

When the application is started, we will be notified that the H2 database has been started:

INFO  [com.pac.qua.cha.DBLifeCycleBean] (main) H2 database started in TCP server mode on Port 19092

Then, we will receive one more notification on application startup, where we can include some extra tasks to be completed:

[com.pac.qua.cha.DBLifeCycleBean] (main) Application is starting

Finally, when we stop the application, the resource will be dismissed, as shown in the following console logs:

[com.pac.qua.cha.DBLifeCycleBean] (main) H2 database was shut down

Before shutting down the database, you can enjoy running your customer service example with a tiny in-memory database layer.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.152.157