package io.arivera.oss.embedded.rabbitmq.helpers; import io.arivera.oss.embedded.rabbitmq.EmbeddedRabbitMqConfig; import io.arivera.oss.embedded.rabbitmq.bin.RabbitMqCommandException; import io.arivera.oss.embedded.rabbitmq.bin.RabbitMqCtl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.zeroturnaround.exec.ProcessResult; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * A helper class used to shut down a specific RabbitMQ Process and wait until it's the process is stopped. */ public class ShutdownHelper implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(ShutdownHelper.class); private final EmbeddedRabbitMqConfig config; private final Future<ProcessResult> rabbitMqProcess; private final long timeoutDuration; private final TimeUnit timeoutUnit; /** * Constructs a new instance that will be used to shut down the given RabbitMQ server process. */ public ShutdownHelper(EmbeddedRabbitMqConfig config, Future<ProcessResult> rabbitMqProcess) { this.config = config; this.rabbitMqProcess = rabbitMqProcess; this.timeoutDuration = config.getDefaultRabbitMqCtlTimeoutInMillis(); this.timeoutUnit = TimeUnit.MILLISECONDS; } @Override public void run() throws ShutDownException { submitShutdownRequest(); confirmShutdown(); } private void submitShutdownRequest() throws ShutDownException { Future<ProcessResult> resultFuture; try { resultFuture = new RabbitMqCtl(config).stop(); } catch (RabbitMqCommandException e) { throw new ShutDownException("Could not successfully execute command to stop RabbitMQ Server", e); } int exitValue; try { ProcessResult rabbitMqCtlProcessResult = resultFuture.get(timeoutDuration, timeoutUnit); exitValue = rabbitMqCtlProcessResult.getExitValue(); } catch (InterruptedException | ExecutionException | TimeoutException e) { throw new ShutDownException("Error while waiting " + timeoutDuration + " " + timeoutUnit + " for command " + "to shut down RabbitMQ Server to finish", e); } if (exitValue == 0) { LOGGER.debug("Successfully commanded RabbitMQ Server to stop."); } else { LOGGER.warn("Command to stop RabbitMQ Sever failed with exit value: " + exitValue); } } private void confirmShutdown() throws ShutDownException { int exitValue; try { ProcessResult rabbitMqProcessResult = rabbitMqProcess.get(timeoutDuration, TimeUnit.MILLISECONDS); exitValue = rabbitMqProcessResult.getExitValue(); } catch (InterruptedException | ExecutionException | TimeoutException e) { throw new ShutDownException("Error while waiting " + timeoutDuration + " " + timeoutUnit + "for " + "RabbitMQ Server to shut down", e); } if (exitValue == 0) { LOGGER.debug("RabbitMQ Server stopped successfully."); } else { LOGGER.warn("RabbitMQ Server stopped with exit value: " + exitValue); } } }