Change DockerComposeProperties shut down default to stop

Closes gh-35239
pull/35333/head
Andy Wilkinson 2 years ago
parent 6a39b497ad
commit 4f9616c2f9

@ -33,35 +33,35 @@ import org.springframework.boot.logging.LogLevel;
public interface DockerCompose {
/**
* Timeout duration used to request a forced shutdown.
* Timeout duration used to request a forced stop.
*/
Duration FORCE_SHUTDOWN = Duration.ZERO;
Duration FORCE_STOP = Duration.ZERO;
/**
* Run {@code docker compose up} to startup services. Waits until all contains are
* started and healthy.
* Run {@code docker compose up} to create and start services. Waits until all
* contains are started and healthy.
* @param logLevel the log level used to report progress
*/
void up(LogLevel logLevel);
/**
* Run {@code docker compose down} to shut down any running services.
* @param timeout the amount of time to wait or {@link #FORCE_SHUTDOWN} to shut down
* without waiting.
* Run {@code docker compose down} to stop and remove any running services.
* @param timeout the amount of time to wait or {@link #FORCE_STOP} to stop without
* waiting.
*/
void down(Duration timeout);
/**
* Run {@code docker compose start} to startup services. Waits until all contains are
* Run {@code docker compose start} to start services. Waits until all containers are
* started and healthy.
* @param logLevel the log level used to report progress
*/
void start(LogLevel logLevel);
/**
* Run {@code docker compose stop} to shut down any running services.
* @param timeout the amount of time to wait or {@link #FORCE_SHUTDOWN} to shut down
* without waiting.
* Run {@code docker compose stop} to stop any running services.
* @param timeout the amount of time to wait or {@link #FORCE_STOP} to stop without
* waiting.
*/
void stop(Duration timeout);

@ -29,8 +29,8 @@ import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.docker.compose.core.DockerCompose;
import org.springframework.boot.docker.compose.core.DockerComposeFile;
import org.springframework.boot.docker.compose.core.RunningService;
import org.springframework.boot.docker.compose.lifecycle.DockerComposeProperties.Shutdown;
import org.springframework.boot.docker.compose.lifecycle.DockerComposeProperties.Startup;
import org.springframework.boot.docker.compose.lifecycle.DockerComposeProperties.Start;
import org.springframework.boot.docker.compose.lifecycle.DockerComposeProperties.Stop;
import org.springframework.boot.docker.compose.readiness.ServiceReadinessChecks;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
@ -89,30 +89,30 @@ class DockerComposeLifecycleManager {
: new ServiceReadinessChecks(this.classLoader, applicationContext.getEnvironment(), binder);
}
void startup() {
void start() {
if (!this.properties.isEnabled()) {
logger.trace("Docker compose support not enabled");
logger.trace("Docker Compose support not enabled");
return;
}
if (this.skipCheck.shouldSkip(this.classLoader, this.properties.getSkip())) {
logger.trace("Docker compose support skipped");
logger.trace("Docker Compose support skipped");
return;
}
DockerComposeFile composeFile = getComposeFile();
Set<String> activeProfiles = this.properties.getProfiles().getActive();
DockerCompose dockerCompose = getDockerCompose(composeFile, activeProfiles);
if (!dockerCompose.hasDefinedServices()) {
logger.warn(LogMessage.format("No services defined in docker compose file '%s' with active profiles %s",
logger.warn(LogMessage.format("No services defined in Docker Compose file '%s' with active profiles %s",
composeFile, activeProfiles));
return;
}
LifecycleManagement lifecycleManagement = this.properties.getLifecycleManagement();
Startup startup = this.properties.getStartup();
Shutdown shutdown = this.properties.getShutdown();
if (lifecycleManagement.shouldStartup() && !dockerCompose.hasRunningServices()) {
startup.getCommand().applyTo(dockerCompose, startup.getLogLevel());
if (lifecycleManagement.shouldShutdown()) {
this.shutdownHandlers.add(() -> shutdown.getCommand().applyTo(dockerCompose, shutdown.getTimeout()));
Start start = this.properties.getStart();
Stop stop = this.properties.getStop();
if (lifecycleManagement.shouldStart() && !dockerCompose.hasRunningServices()) {
start.getCommand().applyTo(dockerCompose, start.getLogLevel());
if (lifecycleManagement.shouldStop()) {
this.shutdownHandlers.add(() -> stop.getCommand().applyTo(dockerCompose, stop.getTimeout()));
}
}
List<RunningService> runningServices = new ArrayList<>(dockerCompose.getRunningServices());
@ -124,7 +124,7 @@ class DockerComposeLifecycleManager {
protected DockerComposeFile getComposeFile() {
DockerComposeFile composeFile = (this.properties.getFile() != null)
? DockerComposeFile.of(this.properties.getFile()) : DockerComposeFile.find(this.workingDirectory);
logger.info(LogMessage.format("Found docker compose file '%s'", composeFile));
logger.info(LogMessage.format("Found Docker Compose file '%s'", composeFile));
return composeFile;
}

@ -50,7 +50,7 @@ class DockerComposeListener implements ApplicationListener<ApplicationPreparedEv
Binder binder = Binder.get(applicationContext.getEnvironment());
DockerComposeProperties properties = DockerComposeProperties.get(binder);
Set<ApplicationListener<?>> eventListeners = event.getSpringApplication().getListeners();
createDockerComposeLifecycleManager(applicationContext, binder, properties, eventListeners).startup();
createDockerComposeLifecycleManager(applicationContext, binder, properties, eventListeners).start();
}
protected DockerComposeLifecycleManager createDockerComposeLifecycleManager(

@ -26,7 +26,7 @@ import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.logging.LogLevel;
/**
* Configuration properties for the 'docker compose'.
* Configuration properties for Docker Compose.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
@ -61,12 +61,12 @@ public class DockerComposeProperties {
/**
* Start configuration.
*/
private final Startup startup = new Startup();
private final Start start = new Start();
/**
* Stop configuration.
*/
private final Shutdown shutdown = new Shutdown();
private final Stop stop = new Stop();
/**
* Profiles configuration.
@ -107,12 +107,12 @@ public class DockerComposeProperties {
this.host = host;
}
public Startup getStartup() {
return this.startup;
public Start getStart() {
return this.start;
}
public Shutdown getShutdown() {
return this.shutdown;
public Stop getStop() {
return this.stop;
}
public Profiles getProfiles() {
@ -128,25 +128,25 @@ public class DockerComposeProperties {
}
/**
* Startup properties.
* Start properties.
*/
public static class Startup {
public static class Start {
/**
* Command used to start docker compose.
*/
private StartupCommand command = StartupCommand.UP;
private StartCommand command = StartCommand.UP;
/**
* Log level for output.
*/
private LogLevel logLevel = LogLevel.INFO;
public StartupCommand getCommand() {
public StartCommand getCommand() {
return this.command;
}
public void setCommand(StartupCommand command) {
public void setCommand(StartCommand command) {
this.command = command;
}
@ -161,25 +161,25 @@ public class DockerComposeProperties {
}
/**
* Shutdown properties.
* Stop properties.
*/
public static class Shutdown {
public static class Stop {
/**
* Command used to stop docker compose.
*/
private ShutdownCommand command = ShutdownCommand.DOWN;
private StopCommand command = StopCommand.STOP;
/**
* Timeout for stopping docker compose. Use '0' for forced stop.
* Timeout for stopping Docker Compose. Use '0' for forced stop.
*/
private Duration timeout = Duration.ofSeconds(10);
public ShutdownCommand getCommand() {
public StopCommand getCommand() {
return this.command;
}
public void setCommand(ShutdownCommand command) {
public void setCommand(StopCommand command) {
this.command = command;
}

@ -24,9 +24,9 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
/**
* {@link ApplicationEvent} published when docker compose {@link RunningService} instances
* are available. This event is published from the {@link ApplicationPreparedEvent} that
* performs the docker compose startup.
* {@link ApplicationEvent} published when Docker Compose {@link RunningService} instances
* are available. This event is published from the {@link ApplicationPreparedEvent}
* listener that starts Docker Compose.
*
* @author Moritz Halbritter
* @author Andy Wilkinson

@ -24,7 +24,7 @@ import org.springframework.boot.SpringApplicationAotProcessor;
import org.springframework.util.ClassUtils;
/**
* Checks if docker compose support should be skipped.
* Checks if Docker Compose support should be skipped.
*
* @author Phillip Webb
*/

@ -17,7 +17,7 @@
package org.springframework.boot.docker.compose.lifecycle;
/**
* Docker compose lifecycle management.
* Docker Compose lifecycle management.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
@ -27,43 +27,43 @@ package org.springframework.boot.docker.compose.lifecycle;
public enum LifecycleManagement {
/**
* Don't start or stop docker compose.
* Don't start or stop Docker Compose.
*/
NONE(false, false),
/**
* Only start docker compose if it's not running.
* Start Docker Compose if it's not running.
*/
START_ONLY(true, false),
/**
* Start and stop docker compose if it's not running.
* Start Docker Compose if it's not running and stop it when the JVM exits.
*/
START_AND_STOP(true, true);
private final boolean startup;
private final boolean start;
private final boolean shutdown;
private final boolean stop;
LifecycleManagement(boolean startup, boolean shutdown) {
this.startup = startup;
this.shutdown = shutdown;
LifecycleManagement(boolean start, boolean stop) {
this.start = start;
this.stop = stop;
}
/**
* Return whether docker compose should be started.
* @return whether docker compose should be started
* Return whether Docker Compose should be started.
* @return whether Docker Compose should be started
*/
boolean shouldStartup() {
return this.startup;
boolean shouldStart() {
return this.start;
}
/**
* Return whether docker compose should be stopped.
* @return whether docker compose should be stopped
* Return whether Docker Compose should be stopped.
* @return whether Docker Compose should be stopped
*/
boolean shouldShutdown() {
return this.shutdown;
boolean shouldStop() {
return this.stop;
}
}

@ -22,28 +22,28 @@ import org.springframework.boot.docker.compose.core.DockerCompose;
import org.springframework.boot.logging.LogLevel;
/**
* Command used to startup docker compose.
* Command used to start Docker Compose.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @since 3.1.0
*/
public enum StartupCommand {
public enum StartCommand {
/**
* Startup using {@code docker compose up}.
* Start using {@code docker compose up}.
*/
UP(DockerCompose::up),
/**
* Startup using {@code docker compose start}.
* Start using {@code docker compose start}.
*/
START(DockerCompose::start);
private final BiConsumer<DockerCompose, LogLevel> action;
StartupCommand(BiConsumer<DockerCompose, LogLevel> action) {
StartCommand(BiConsumer<DockerCompose, LogLevel> action) {
this.action = action;
}

@ -22,28 +22,28 @@ import java.util.function.BiConsumer;
import org.springframework.boot.docker.compose.core.DockerCompose;
/**
* Command used to shut down docker compose.
* Command used to stop Docker Compose.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @since 3.1.0
*/
public enum ShutdownCommand {
public enum StopCommand {
/**
* Shutdown using {@code docker compose down}.
* Stop using {@code docker compose down}.
*/
DOWN(DockerCompose::down),
/**
* Shutdown using {@code docker compose stop}.
* Stop using {@code docker compose stop}.
*/
STOP(DockerCompose::stop);
private final BiConsumer<DockerCompose, Duration> action;
ShutdownCommand(BiConsumer<DockerCompose, Duration> action) {
StopCommand(BiConsumer<DockerCompose, Duration> action) {
this.action = action;
}

@ -15,6 +15,6 @@
*/
/**
* Lifecycle management for docker compose with the context of a Spring application.
* Lifecycle management for Docker Compose with the context of a Spring application.
*/
package org.springframework.boot.docker.compose.lifecycle;

@ -103,32 +103,32 @@ class DockerComposeLifecycleManagerTests {
}
@Test
void startupWhenEnabledFalseDoesNotStart() {
void startWhenEnabledFalseDoesNotStart() {
this.properties.setEnabled(false);
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
setupRunningServices();
this.lifecycleManager.startup();
setUpRunningServices();
this.lifecycleManager.start();
assertThat(listener.getEvent()).isNull();
then(this.dockerCompose).should(never()).hasDefinedServices();
}
@Test
void startupWhenInTestDoesNotStart() {
void startWhenInTestDoesNotStart() {
given(this.skipCheck.shouldSkip(any(), any())).willReturn(true);
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
setupRunningServices();
this.lifecycleManager.startup();
setUpRunningServices();
this.lifecycleManager.start();
assertThat(listener.getEvent()).isNull();
then(this.dockerCompose).should(never()).hasDefinedServices();
}
@Test
void startupWhenHasNoDefinedServicesDoesNothing() {
void startWhenHasNoDefinedServicesDoesNothing() {
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
this.lifecycleManager.startup();
this.lifecycleManager.start();
assertThat(listener.getEvent()).isNull();
then(this.dockerCompose).should().hasDefinedServices();
then(this.dockerCompose).should(never()).up(any());
@ -138,27 +138,27 @@ class DockerComposeLifecycleManagerTests {
}
@Test
void startupWhenLifecycleStartAndStopAndHasNoRunningServicesDoesStartupAndShutdown() {
void startWhenLifecycleStartAndStopAndHasNoRunningServicesDoesUpAndStop() {
this.properties.setLifecycleManagement(LifecycleManagement.START_AND_STOP);
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
this.lifecycleManager.startup();
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should().up(any());
then(this.dockerCompose).should(never()).start(any());
then(this.dockerCompose).should().down(any());
then(this.dockerCompose).should(never()).stop(any());
then(this.dockerCompose).should().stop(any());
then(this.dockerCompose).should(never()).down(any());
}
@Test
void startupWhenLifecycleStartAndStopAndHasRunningServicesDoesNoStartupOrShutdown() {
void startWhenLifecycleStartAndStopAndHasRunningServicesDoesNothing() {
this.properties.setLifecycleManagement(LifecycleManagement.START_AND_STOP);
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
setupRunningServices();
this.lifecycleManager.startup();
setUpRunningServices();
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should(never()).up(any());
@ -168,12 +168,12 @@ class DockerComposeLifecycleManagerTests {
}
@Test
void startupWhenLifecycleNoneDoesNoStartupOrShutdown() {
void startWhenLifecycleNoneDoesNothing() {
this.properties.setLifecycleManagement(LifecycleManagement.NONE);
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
setupRunningServices();
this.lifecycleManager.startup();
setUpRunningServices();
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should(never()).up(any());
@ -183,12 +183,12 @@ class DockerComposeLifecycleManagerTests {
}
@Test
void startupWhenLifecycleStartOnlyDoesStartupAndNoShutdown() {
void startWhenLifecycleStartOnlyDoesOnlyStart() {
this.properties.setLifecycleManagement(LifecycleManagement.START_ONLY);
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
this.lifecycleManager.startup();
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should().up(any());
@ -199,97 +199,97 @@ class DockerComposeLifecycleManagerTests {
}
@Test
void startupWhenStartupCommandStartDoesStartupUsingStartAndShutdown() {
void startWhenStartCommandStartDoesStartAndStop() {
this.properties.setLifecycleManagement(LifecycleManagement.START_AND_STOP);
this.properties.getStartup().setCommand(StartupCommand.START);
this.properties.getStart().setCommand(StartCommand.START);
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
this.lifecycleManager.startup();
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should(never()).up(any());
then(this.dockerCompose).should().start(any());
then(this.dockerCompose).should().down(any());
then(this.dockerCompose).should(never()).stop(any());
then(this.dockerCompose).should().stop(any());
then(this.dockerCompose).should(never()).down(any());
}
@Test
void startupWhenShutdownCommandStopDoesStartupAndShutdownUsingStop() {
void startWhenStopCommandDownDoesStartAndDown() {
this.properties.setLifecycleManagement(LifecycleManagement.START_AND_STOP);
this.properties.getShutdown().setCommand(ShutdownCommand.STOP);
this.properties.getStop().setCommand(StopCommand.DOWN);
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
this.lifecycleManager.startup();
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should().up(any());
then(this.dockerCompose).should(never()).start(any());
then(this.dockerCompose).should(never()).down(any());
then(this.dockerCompose).should().stop(any());
then(this.dockerCompose).should(never()).stop(any());
then(this.dockerCompose).should().down(any());
}
@Test
void startupWhenHasShutdownTimeoutUsesDuration() {
void startWhenHasStopTimeoutUsesDuration() {
this.properties.setLifecycleManagement(LifecycleManagement.START_AND_STOP);
Duration timeout = Duration.ofDays(1);
this.properties.getShutdown().setTimeout(timeout);
this.properties.getStop().setTimeout(timeout);
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
this.lifecycleManager.startup();
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
then(this.dockerCompose).should().down(timeout);
then(this.dockerCompose).should().stop(timeout);
}
@Test
void startupWhenHasIgnoreLabelIgnoresService() {
void startWhenHasIgnoreLabelIgnoresService() {
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
setupRunningServices(Map.of("org.springframework.boot.ignore", "true"));
this.lifecycleManager.startup();
setUpRunningServices(Map.of("org.springframework.boot.ignore", "true"));
this.lifecycleManager.start();
this.shutdownHandlers.run();
assertThat(listener.getEvent()).isNotNull();
assertThat(listener.getEvent().getRunningServices()).isEmpty();
}
@Test
void startupWaitsUntilReady() {
void startWaitsUntilReady() {
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
setupRunningServices();
this.lifecycleManager.startup();
setUpRunningServices();
this.lifecycleManager.start();
this.shutdownHandlers.run();
then(this.serviceReadinessChecks).should().waitUntilReady(this.runningServices);
}
@Test
void startupGetsDockerComposeWithActiveProfiles() {
void startGetsDockerComposeWithActiveProfiles() {
this.properties.getProfiles().setActive(Set.of("my-profile"));
setupRunningServices();
this.lifecycleManager.startup();
setUpRunningServices();
this.lifecycleManager.start();
assertThat(this.activeProfiles).containsExactly("my-profile");
}
@Test
void startupPublishesEvent() {
void startPublishesEvent() {
EventCapturingListener listener = new EventCapturingListener();
this.eventListeners.add(listener);
setupRunningServices();
this.lifecycleManager.startup();
setUpRunningServices();
this.lifecycleManager.start();
DockerComposeServicesReadyEvent event = listener.getEvent();
assertThat(event).isNotNull();
assertThat(event.getSource()).isEqualTo(this.applicationContext);
assertThat(event.getRunningServices()).isEqualTo(this.runningServices);
}
private void setupRunningServices() {
setupRunningServices(Collections.emptyMap());
private void setUpRunningServices() {
setUpRunningServices(Collections.emptyMap());
}
private void setupRunningServices(Map<String, String> labels) {
private void setUpRunningServices(Map<String, String> labels) {
given(this.dockerCompose.hasDefinedServices()).willReturn(true);
given(this.dockerCompose.hasRunningServices()).willReturn(true);
RunningService runningService = mock(RunningService.class);

@ -53,7 +53,7 @@ class DockerComposeListenerTests {
ApplicationPreparedEvent event = new ApplicationPreparedEvent(application, new String[0], context);
listener.onApplicationEvent(event);
assertThat(listener.getManager()).isNotNull();
then(listener.getManager()).should().startup();
then(listener.getManager()).should().start();
}
static class TestDockerComposeListener extends DockerComposeListener {

@ -44,9 +44,9 @@ class DockerComposePropertiesTests {
assertThat(properties.getFile()).isNull();
assertThat(properties.getLifecycleManagement()).isEqualTo(LifecycleManagement.START_AND_STOP);
assertThat(properties.getHost()).isNull();
assertThat(properties.getStartup().getCommand()).isEqualTo(StartupCommand.UP);
assertThat(properties.getShutdown().getCommand()).isEqualTo(ShutdownCommand.DOWN);
assertThat(properties.getShutdown().getTimeout()).isEqualTo(Duration.ofSeconds(10));
assertThat(properties.getStart().getCommand()).isEqualTo(StartCommand.UP);
assertThat(properties.getStop().getCommand()).isEqualTo(StopCommand.STOP);
assertThat(properties.getStop().getTimeout()).isEqualTo(Duration.ofSeconds(10));
assertThat(properties.getProfiles().getActive()).isEmpty();
}
@ -56,18 +56,18 @@ class DockerComposePropertiesTests {
source.put("spring.docker.compose.file", "my-compose.yml");
source.put("spring.docker.compose.lifecycle-management", "start-only");
source.put("spring.docker.compose.host", "myhost");
source.put("spring.docker.compose.startup.command", "start");
source.put("spring.docker.compose.shutdown.command", "stop");
source.put("spring.docker.compose.shutdown.timeout", "5s");
source.put("spring.docker.compose.start.command", "start");
source.put("spring.docker.compose.stop.command", "down");
source.put("spring.docker.compose.stop.timeout", "5s");
source.put("spring.docker.compose.profiles.active", "myprofile");
Binder binder = new Binder(new MapConfigurationPropertySource(source));
DockerComposeProperties properties = DockerComposeProperties.get(binder);
assertThat(properties.getFile()).isEqualTo(new File("my-compose.yml"));
assertThat(properties.getLifecycleManagement()).isEqualTo(LifecycleManagement.START_ONLY);
assertThat(properties.getHost()).isEqualTo("myhost");
assertThat(properties.getStartup().getCommand()).isEqualTo(StartupCommand.START);
assertThat(properties.getShutdown().getCommand()).isEqualTo(ShutdownCommand.STOP);
assertThat(properties.getShutdown().getTimeout()).isEqualTo(Duration.ofSeconds(5));
assertThat(properties.getStart().getCommand()).isEqualTo(StartCommand.START);
assertThat(properties.getStop().getCommand()).isEqualTo(StopCommand.DOWN);
assertThat(properties.getStop().getTimeout()).isEqualTo(Duration.ofSeconds(5));
assertThat(properties.getProfiles().getActive()).containsExactly("myprofile");
}

@ -31,32 +31,32 @@ class LifecycleManagementTests {
@Test
void shouldStartupWhenNone() {
assertThat(LifecycleManagement.NONE.shouldStartup()).isFalse();
assertThat(LifecycleManagement.NONE.shouldStart()).isFalse();
}
@Test
void shouldShutdownWhenNone() {
assertThat(LifecycleManagement.NONE.shouldShutdown()).isFalse();
assertThat(LifecycleManagement.NONE.shouldStop()).isFalse();
}
@Test
void shouldStartupWhenStartOnly() {
assertThat(LifecycleManagement.START_ONLY.shouldStartup()).isTrue();
assertThat(LifecycleManagement.START_ONLY.shouldStart()).isTrue();
}
@Test
void shouldShutdownWhenStartOnly() {
assertThat(LifecycleManagement.START_ONLY.shouldShutdown()).isFalse();
assertThat(LifecycleManagement.START_ONLY.shouldStop()).isFalse();
}
@Test
void shouldStartupWhenStartAndStop() {
assertThat(LifecycleManagement.START_AND_STOP.shouldStartup()).isTrue();
assertThat(LifecycleManagement.START_AND_STOP.shouldStart()).isTrue();
}
@Test
void shouldShutdownWhenStartAndStop() {
assertThat(LifecycleManagement.START_AND_STOP.shouldShutdown()).isTrue();
assertThat(LifecycleManagement.START_AND_STOP.shouldStop()).isTrue();
}
}

@ -25,25 +25,25 @@ import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link StartupCommand}.
* Tests for {@link StartCommand}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class StartupCommandTests {
class StartCommandTests {
private DockerCompose dockerCompose = mock(DockerCompose.class);
@Test
void applyToWhenUp() {
StartupCommand.UP.applyTo(this.dockerCompose, LogLevel.INFO);
StartCommand.UP.applyTo(this.dockerCompose, LogLevel.INFO);
then(this.dockerCompose).should().up(LogLevel.INFO);
}
@Test
void applyToWhenStart() {
StartupCommand.START.applyTo(this.dockerCompose, LogLevel.INFO);
StartCommand.START.applyTo(this.dockerCompose, LogLevel.INFO);
then(this.dockerCompose).should().start(LogLevel.INFO);
}

@ -26,13 +26,13 @@ import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link ShutdownCommand}.
* Tests for {@link StopCommand}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class ShutdownCommandTests {
class StopCommandTests {
private DockerCompose dockerCompose = mock(DockerCompose.class);
@ -40,13 +40,13 @@ class ShutdownCommandTests {
@Test
void applyToWhenDown() {
ShutdownCommand.DOWN.applyTo(this.dockerCompose, this.duration);
StopCommand.DOWN.applyTo(this.dockerCompose, this.duration);
then(this.dockerCompose).should().down(this.duration);
}
@Test
void applyToWhenStart() {
ShutdownCommand.STOP.applyTo(this.dockerCompose, this.duration);
StopCommand.STOP.applyTo(this.dockerCompose, this.duration);
then(this.dockerCompose).should().stop(this.duration);
}

@ -43,7 +43,7 @@ public abstract class AbstractDockerComposeIntegrationTests {
private final Resource composeResource;
@AfterAll
static void shutdown() {
static void shutDown() {
SpringApplicationShutdownHandlers shutdownHandlers = SpringApplication.getShutdownHandlers();
((Runnable) shutdownHandlers).run();
}

@ -169,17 +169,17 @@ TIP: You can also provide your own `ServiceReadinessCheck` implementations and r
[[features.docker-compose.lifecycle]]
=== Controlling the Docker Compose Lifecycle
By default Spring Boot calls `docker compose up` when your application starts and `docker compose down` when it's shutdown.
By default Spring Boot calls `docker compose up` when your application starts and `docker compose stop` when it's shut down.
If you prefer to have different lifecycle management you can use the configprop:spring.docker.compose.lifecycle-management[] property.
The following values are supported:
* `none` - Do not start or stop Docker Compose
* `start-only` - Start Docker Compose on application startup and leave it running
* `start-and-stop` - Start Docker Compose on application startup and stop it on application shutdown
* `start-only` - Start Docker Compose when the application starts and leave it running
* `start-and-stop` - Start Docker Compose whe the application starts and stop it when the JVM exits
In addition you can use the configprop:spring.docker.compose.startup.command[] property to change if `docker up` or `docker start` is used.
The configprop:spring.docker.compose.shutdown.command[] allows you to configure if `docker down` or `docker stop` is used.
In addition you can use the configprop:spring.docker.compose.start.command[] property to change whether `docker compose up` or `docker compose start` is used.
The configprop:spring.docker.compose.stop.command[] allows you to configure if `docker compose down` or `docker compose stop` is used.
The following example shows how lifecycle management can be configured:
@ -189,10 +189,10 @@ The following example shows how lifecycle management can be configured:
docker:
compose:
lifecycle-management: start-and-stop
startup:
start:
command: start
shutdown:
command: stop
stop:
command: down
timeout: 1m
----

Loading…
Cancel
Save