Skip to content

Commit

Permalink
Add new lifecycle management methods in KiwiDropwizardLifecycles (#1175)
Browse files Browse the repository at this point in the history
Add methods in KiwiDropwizardLifecycles to manage and only provide a
start or a stop action

Closes  #1163
  • Loading branch information
sleberknight authored Jul 30, 2024
1 parent e517edc commit ff30117
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -15,8 +16,8 @@ public class KiwiDropwizardLifecycles {
* is {@code stopAction}, and attaches it to the given Dropwizard {@code lifecycle}.
* <p>
* 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:
* <p>
* {@code KiwiDropwizardLifecycles.manage(lifecycle, () -> factory.start(), () -> factory.stop());}
Expand All @@ -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}.
* <p>
* 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:
* <p>
* {@code KiwiDropwizardLifecycles.manage(lifecycle, () -> monitor.start());}
* <p>
* To make the code cleaner, use method references:
* <p>
* {@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}.
* <p>
* 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:
* <p>
* {@code KiwiDropwizardLifecycles.manage(lifecycle, () -> client.close());}
* <p>
* To make the code cleaner, use method references:
* <p>
* {@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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand All @@ -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();
Expand Down

0 comments on commit ff30117

Please sign in to comment.