diff --git a/scm-webapp/src/main/java/sonia/scm/lifecycle/BootstrapContextFilter.java b/scm-webapp/src/main/java/sonia/scm/lifecycle/BootstrapContextFilter.java index 5c81089616..b5094e2aba 100644 --- a/scm-webapp/src/main/java/sonia/scm/lifecycle/BootstrapContextFilter.java +++ b/scm-webapp/src/main/java/sonia/scm/lifecycle/BootstrapContextFilter.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm.lifecycle; //~--- non-JDK imports -------------------------------------------------------- @@ -103,7 +103,7 @@ public class BootstrapContextFilter extends GuiceFilter { } } - private class GuiceInjectionContext implements RestartStrategy.InjectionContext { + private class GuiceInjectionContext implements RestartStrategy.InternalInjectionContext { @Override public void initialize() { diff --git a/scm-webapp/src/main/java/sonia/scm/lifecycle/ExitRestartStrategy.java b/scm-webapp/src/main/java/sonia/scm/lifecycle/ExitRestartStrategy.java index d8eb2fd22a..04d58df731 100644 --- a/scm-webapp/src/main/java/sonia/scm/lifecycle/ExitRestartStrategy.java +++ b/scm-webapp/src/main/java/sonia/scm/lifecycle/ExitRestartStrategy.java @@ -35,7 +35,7 @@ import java.util.function.IntConsumer; *
* This is useful if an external mechanism is able to restart the process after it has exited. */ -class ExitRestartStrategy implements RestartStrategy { +class ExitRestartStrategy extends RestartStrategy { private static final Logger LOG = LoggerFactory.getLogger(ExitRestartStrategy.class); @@ -45,6 +45,8 @@ class ExitRestartStrategy implements RestartStrategy { private IntConsumer exiter = System::exit; + private int exitCode; + ExitRestartStrategy() { } @@ -54,12 +56,12 @@ class ExitRestartStrategy implements RestartStrategy { } @Override - public void restart(InjectionContext context) { - int exitCode = determineExitCode(); - - LOG.warn("destroy injection context"); - context.destroy(); + public void prepareRestart(InjectionContext context) { + exitCode = determineExitCode(); + } + @Override + protected void executeRestart(InjectionContext context) { LOG.warn("exit scm-manager with exit code {}", exitCode); exiter.accept(exitCode); } diff --git a/scm-webapp/src/main/java/sonia/scm/lifecycle/PosixRestartStrategy.java b/scm-webapp/src/main/java/sonia/scm/lifecycle/PosixRestartStrategy.java index 6d5477dd78..852d4b5f60 100644 --- a/scm-webapp/src/main/java/sonia/scm/lifecycle/PosixRestartStrategy.java +++ b/scm-webapp/src/main/java/sonia/scm/lifecycle/PosixRestartStrategy.java @@ -33,7 +33,7 @@ import static sonia.scm.lifecycle.CLibrary.*; /** * Restart strategy which uses execvp from libc. This strategy is only supported on posix base operating systems. */ -class PosixRestartStrategy implements RestartStrategy { +class PosixRestartStrategy extends RestartStrategy { private static final Logger LOG = LoggerFactory.getLogger(PosixRestartStrategy.class); @@ -41,10 +41,7 @@ class PosixRestartStrategy implements RestartStrategy { } @Override - public void restart(InjectionContext context) { - LOG.warn("destroy injection context"); - context.destroy(); - + protected void executeRestart(InjectionContext context) { LOG.warn("restart scm-manager jvm process"); try { restart(); diff --git a/scm-webapp/src/main/java/sonia/scm/lifecycle/RestartStrategy.java b/scm-webapp/src/main/java/sonia/scm/lifecycle/RestartStrategy.java index 81fcffff56..c21c66f011 100644 --- a/scm-webapp/src/main/java/sonia/scm/lifecycle/RestartStrategy.java +++ b/scm-webapp/src/main/java/sonia/scm/lifecycle/RestartStrategy.java @@ -24,23 +24,20 @@ package sonia.scm.lifecycle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.Optional; /** * Strategy for restarting SCM-Manager. Implementations must either have a default constructor or one taking the * class loader for the current context as a single argument. */ -public interface RestartStrategy { +public abstract class RestartStrategy { - /** - * Context for Injection in SCM-Manager. - */ - interface InjectionContext { - /** - * Initialize the injection context. - */ - void initialize(); + private static final Logger LOG = LoggerFactory.getLogger(RestartStrategy.class); + interface InternalInjectionContext extends InjectionContext { /** * Destroys the injection context. */ @@ -48,11 +45,43 @@ public interface RestartStrategy { } /** - * Restart SCM-Manager. + * Context for Injection in SCM-Manager. + */ + public interface InjectionContext { + /** + * Initialize the injection context. + */ + void initialize(); + } + + /** + * Restart SCM-Manager by first calling {@link #prepareRestart(InjectionContext)}, destroying the + * current context, and finally calling {@link #executeRestart(InjectionContext)}. * * @param context injection context */ - void restart(InjectionContext context); + public final void restart(InternalInjectionContext context) { + prepareRestart(context); + LOG.warn("destroy injection context"); + context.destroy(); + executeRestart(context); + } + + /** + * Prepare the restart of SCM-Manager. Here you can check whether restart is possible and, + * if necessary, throw a {@link RestartNotSupportedException} to abort the restart. + * + * @param context injection context + */ + protected void prepareRestart(InjectionContext context) { + } + + /** + * Actually restart SCM-Manager. + * + * @param context injection context + */ + protected abstract void executeRestart(InjectionContext context); /** * Returns the configured strategy or empty if restart is not supported by the underlying platform. diff --git a/scm-webapp/src/test/java/sonia/scm/lifecycle/ExitRestartStrategyTest.java b/scm-webapp/src/test/java/sonia/scm/lifecycle/ExitRestartStrategyTest.java index 8fba403120..766fa3bb64 100644 --- a/scm-webapp/src/test/java/sonia/scm/lifecycle/ExitRestartStrategyTest.java +++ b/scm-webapp/src/test/java/sonia/scm/lifecycle/ExitRestartStrategyTest.java @@ -39,7 +39,7 @@ import static org.mockito.Mockito.verify; class ExitRestartStrategyTest { @Mock - private RestartStrategy.InjectionContext context; + private RestartStrategy.InternalInjectionContext context; private ExitRestartStrategy strategy; private CapturingExiter exiter; diff --git a/scm-webapp/src/test/java/sonia/scm/lifecycle/RestartStrategyTest.java b/scm-webapp/src/test/java/sonia/scm/lifecycle/RestartStrategyTest.java index f590281175..2205bfc0d0 100644 --- a/scm-webapp/src/test/java/sonia/scm/lifecycle/RestartStrategyTest.java +++ b/scm-webapp/src/test/java/sonia/scm/lifecycle/RestartStrategyTest.java @@ -117,14 +117,13 @@ class RestartStrategyTest { } } - public static class TestingRestartStrategy implements RestartStrategy { + public static class TestingRestartStrategy extends RestartStrategy { @Override - public void restart(InjectionContext context) { - + protected void executeRestart(InjectionContext context) { } } - public static class ComplexRestartStrategy implements RestartStrategy { + public static class ComplexRestartStrategy extends RestartStrategy { private final ClassLoader classLoader; @@ -133,8 +132,7 @@ class RestartStrategyTest { } @Override - public void restart(InjectionContext context) { - + protected void executeRestart(InjectionContext context) { } }