Skip to content

Commit 487d465

Browse files
authored
Merge pull request #206 from zonkyio/shutdown-hook
#201 Improve shutdown hook of zonky provider to support destroy methods
2 parents 49be30c + 443e8be commit 487d465

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

embedded-database-spring-test/src/main/java/io/zonky/test/db/provider/postgres/ZonkyPostgresDatabaseProvider.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@
3434
import io.zonky.test.db.provider.support.SimpleDatabaseTemplate;
3535
import io.zonky.test.db.util.PropertyUtils;
3636
import io.zonky.test.db.util.RandomStringUtils;
37+
import io.zonky.test.db.util.ReflectionUtils;
3738
import org.postgresql.ds.PGSimpleDataSource;
3839
import org.postgresql.ds.common.BaseDataSource;
3940
import org.slf4j.Logger;
4041
import org.slf4j.LoggerFactory;
4142
import org.springframework.beans.factory.ObjectProvider;
4243
import org.springframework.core.env.Environment;
4344
import org.springframework.jdbc.core.JdbcTemplate;
45+
import org.springframework.util.ClassUtils;
4446

4547
import javax.sql.DataSource;
4648
import java.io.IOException;
@@ -56,8 +58,10 @@
5658
import java.util.concurrent.CompletableFuture;
5759
import java.util.concurrent.ExecutionException;
5860
import java.util.concurrent.Semaphore;
61+
import java.util.concurrent.atomic.AtomicBoolean;
5962
import java.util.function.Consumer;
6063

64+
import static io.zonky.test.db.util.ReflectionUtils.getField;
6165
import static java.util.Collections.emptyList;
6266

6367
public class ZonkyPostgresDatabaseProvider implements TemplatableDatabaseProvider {
@@ -133,6 +137,7 @@ private DatabaseInstance(DatabaseConfig config) throws IOException {
133137
config.applyTo(builder);
134138

135139
postgres = builder.start();
140+
registerShutdownHook(postgres);
136141

137142
DataSource dataSource = postgres.getDatabase("postgres", "postgres");
138143
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
@@ -190,6 +195,29 @@ private EmbeddedDatabase getDatabase(ClientConfig config, String dbName) {
190195
PGSimpleDataSource dataSource = (PGSimpleDataSource) postgres.getDatabase("postgres", dbName, config.connectProperties);
191196
return new BlockingDatabaseWrapper(new PostgresEmbeddedDatabase(dataSource, () -> dropDatabase(config, dbName)), semaphore);
192197
}
198+
199+
protected void registerShutdownHook(EmbeddedPostgres postgres) {
200+
try {
201+
AtomicBoolean closed = getField(postgres, "closed");
202+
203+
Runnable shutdownHandler = () -> {
204+
try {
205+
closed.set(false);
206+
postgres.close();
207+
} catch (IOException e) {
208+
logger.error("Unexpected IOException when closing PostgreSQL server", e);
209+
}
210+
};
211+
212+
Class<?> applicationType = ClassUtils.forName("org.springframework.boot.SpringApplication", null);
213+
Object shutdownHandlers = ReflectionUtils.invokeStaticMethod(applicationType, "getShutdownHandlers");
214+
ReflectionUtils.invokeMethod(shutdownHandlers, "add", shutdownHandler);
215+
216+
closed.set(true);
217+
} catch (Throwable ex) {
218+
// ClassNotFoundException or NoClassDefFoundError...
219+
}
220+
}
193221
}
194222

195223
private static class DatabaseConfig {

0 commit comments

Comments
 (0)