diff --git a/src/main/java/org/kiwiproject/dropwizard/lifecycle/KiwiDropwizardLifecycles.java b/src/main/java/org/kiwiproject/dropwizard/lifecycle/KiwiDropwizardLifecycles.java index 8516f7b1..3581474a 100644 --- a/src/main/java/org/kiwiproject/dropwizard/lifecycle/KiwiDropwizardLifecycles.java +++ b/src/main/java/org/kiwiproject/dropwizard/lifecycle/KiwiDropwizardLifecycles.java @@ -1,5 +1,6 @@ package org.kiwiproject.dropwizard.lifecycle; +import com.google.common.util.concurrent.Runnables; import io.dropwizard.lifecycle.Managed; import io.dropwizard.lifecycle.setup.LifecycleEnvironment; import lombok.experimental.UtilityClass; @@ -15,8 +16,8 @@ public class KiwiDropwizardLifecycles { * is {@code stopAction}, and attaches it to the given Dropwizard {@code lifecycle}. *

* Useful when you have some external object that has start and stop methods, but you don't want to clutter your - * code by creating an anonymous inner class just to specify the start and stop actions. For example if you have an - * ActiveMQ {@code PooledConnectionFactory} (which has {@code start} and {@code stop} methods) you can simply + * code by creating an anonymous inner class just to specify the start and stop actions. For example, if you have + * an ActiveMQ {@code PooledConnectionFactory} (which has {@code start} and {@code stop} methods) you can simply * call this method: *

* {@code KiwiDropwizardLifecycles.manage(lifecycle, () -> factory.start(), () -> factory.stop());} @@ -42,4 +43,48 @@ public void stop() { } }); } + + /** + * Creates a Dropwizard {@link Managed} whose start action is {@code startAction}, + * and attaches it to the given Dropwizard {@code lifecycle}. + *

+ * Useful when you have some external object that has a start method, but you don't want to clutter your + * code by creating an anonymous inner class just to specify the start action. For example, if you have + * a monitoring class that needs to start when the application starts, you can ensure that happens + * using code like: + *

+ * {@code KiwiDropwizardLifecycles.manage(lifecycle, () -> monitor.start());} + *

+ * To make the code cleaner, use method references: + *

+ * {@code KiwiDropwizardLifecycles.manage(lifecycle, monitor::start);} + * + * @param lifecycle the lifecycle to manage + * @param startAction the action to run when Dropwizard starts the application + */ + public static void manageOnlyStart(LifecycleEnvironment lifecycle, Runnable startAction) { + manage(lifecycle, startAction, Runnables.doNothing()); + } + + /** + * Creates a Dropwizard {@link Managed} whose stop action is {@code stopAction}, + * and attaches it to the given Dropwizard {@code lifecycle}. + *

+ * Useful when you have some external object that has a stop method, but you don't want to clutter your + * code by creating an anonymous inner class just to specify the stop action. For example, if you have + * an HTTP {@code Client} class that needs to stop when the application shuts down to ensure resources + * are properly closed, you can ensure that happens using code like: + *

+ * {@code KiwiDropwizardLifecycles.manage(lifecycle, () -> client.close());} + *

+ * To make the code cleaner, use method references: + *

+ * {@code KiwiDropwizardLifecycles.manage(lifecycle, client::close);} + * + * @param lifecycle the lifecycle to manage + * @param stopAction the action to run when Dropwizard stops the application + */ + public static void manageOnlyStop(LifecycleEnvironment lifecycle, Runnable stopAction) { + manage(lifecycle, Runnables.doNothing(), stopAction); + } } diff --git a/src/test/java/org/kiwiproject/dropwizard/lifecycle/KiwiDropwizardLifecyclesTest.java b/src/test/java/org/kiwiproject/dropwizard/lifecycle/KiwiDropwizardLifecyclesTest.java index c9ba539a..94c78d26 100644 --- a/src/test/java/org/kiwiproject/dropwizard/lifecycle/KiwiDropwizardLifecyclesTest.java +++ b/src/test/java/org/kiwiproject/dropwizard/lifecycle/KiwiDropwizardLifecyclesTest.java @@ -15,7 +15,7 @@ class KiwiDropwizardLifecyclesTest { @Test - void testManageStart() throws Exception { + void shouldManageStart() throws Exception { var lifecycle = new LifecycleEnvironment(new MetricRegistry()); var startCalled = new AtomicBoolean(); @@ -31,10 +31,11 @@ void testManageStart() throws Exception { managed.start(); assertThat(startCalled.get()).isTrue(); + assertThat(managed.isStarted()).isTrue(); } @Test - void testManageStop() throws Exception { + void shouldManageStop() throws Exception { var lifecycle = new LifecycleEnvironment(new MetricRegistry()); var stopCalled = new AtomicBoolean(); @@ -45,9 +46,56 @@ void testManageStop() throws Exception { var managedObjects = lifecycle.getManagedObjects(); assertThat(managedObjects).hasSize(1); + // Make sure it's started, so that AbstractLifeCycle#stop will stop it + var managed = first(managedObjects); + managed.start(); + assertThat(managed.isStarted()) + .describedAs("Precondition: Managed object must be started") + .isTrue(); + + managed.stop(); + assertThat(stopCalled.get()).isTrue(); + assertThat(managed.isStopped()).isTrue(); + } + + @Test + void shouldManageOnlyStart() throws Exception { + var lifecycle = new LifecycleEnvironment(new MetricRegistry()); + + var startCalled = new AtomicBoolean(); + Runnable startAction = () -> startCalled.set(true); + + KiwiDropwizardLifecycles.manageOnlyStart(lifecycle, startAction); + + var managedObjects = lifecycle.getManagedObjects(); + assertThat(managedObjects).hasSize(1); + var managed = first(managedObjects); + assertThat(managed.isStarted()).isFalse(); + managed.start(); + assertThat(startCalled.get()).isTrue(); assertThat(managed.isStarted()).isTrue(); + } + + @Test + void shouldManageOnlyStop() throws Exception { + var lifecycle = new LifecycleEnvironment(new MetricRegistry()); + + var stopCalled = new AtomicBoolean(); + Runnable stopAction = () -> stopCalled.set(true); + + KiwiDropwizardLifecycles.manageOnlyStop(lifecycle, stopAction); + + var managedObjects = lifecycle.getManagedObjects(); + assertThat(managedObjects).hasSize(1); + + // Make sure it's started, so that AbstractLifeCycle#stop will stop it + var managed = first(managedObjects); + managed.start(); + assertThat(managed.isStarted()) + .describedAs("Precondition: Managed object must be started") + .isTrue(); managed.stop(); assertThat(stopCalled.get()).isTrue();