display error on startup, if previous version is older than 1.60

This commit is contained in:
Sebastian Sdorra
2019-06-13 09:58:30 +02:00
parent 5c7ae749c2
commit 3c5b7ab535
8 changed files with 204 additions and 103 deletions

View File

@@ -63,6 +63,7 @@ import sonia.scm.util.IOUtil;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.DataBindingException;
import javax.xml.bind.JAXB;
import javax.xml.bind.annotation.XmlAccessType;
@@ -141,8 +142,11 @@ public class BootstrapContextListener implements ServletContextListener {
Throwable startupError = SCMContext.getContext().getStartupError();
if (startupError != null) {
contextListener = SingleView.error(startupError);
} else if (Versions.isToOld()) {
contextListener = SingleView.view("/templates/to-old.mustache", HttpServletResponse.SC_CONFLICT);
} else {
createMigrationOrNormalContextListener();
Versions.writeNew();
}
}

View File

@@ -37,6 +37,16 @@ final class SingleView {
return new SingleViewContextListener(controller);
}
static ServletContextListener view(String template, int sc) {
ViewController controller = new SimpleViewController(template, request -> {
Object model = ImmutableMap.of(
"contextPath", request.getContextPath()
);
return new View(sc, model);
});
return new SingleViewContextListener(controller);
}
private static class SingleViewContextListener extends GuiceServletContextListener {
private final ViewController controller;

View File

@@ -0,0 +1,77 @@
package sonia.scm.boot;
import com.google.common.annotations.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.SCMContext;
import sonia.scm.SCMContextProvider;
import sonia.scm.util.IOUtil;
import sonia.scm.version.Version;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
class Versions {
private static final Logger LOG = LoggerFactory.getLogger(Versions.class);
private static final Version MIN_VERSION = Version.parse("1.60");
private final SCMContextProvider contextProvider;
@VisibleForTesting
Versions(SCMContextProvider contextProvider) {
this.contextProvider = contextProvider;
}
@VisibleForTesting
boolean isPreviousVersionToOld() {
return readVersion().map(v -> v.isOlder(MIN_VERSION)).orElse(false);
}
@VisibleForTesting
void writeNewVersion() {
Path config = contextProvider.resolve(Paths.get("config"));
IOUtil.mkdirs(config.toFile());
String version = contextProvider.getVersion();
LOG.debug("write new version {} to file", version);
Path versionFile = config.resolve("version.txt");
try {
Files.write(versionFile, version.getBytes());
} catch (IOException e) {
throw new IllegalStateException("failed to write version file", e);
}
}
private Optional<Version> readVersion() {
Path versionFile = contextProvider.resolve(Paths.get("config", "version.txt"));
if (versionFile.toFile().exists()) {
return Optional.of(readVersionFromFile(versionFile));
}
return Optional.empty();
}
private Version readVersionFromFile(Path versionFile) {
try {
String versionString = new String(Files.readAllBytes(versionFile), StandardCharsets.UTF_8).trim();
LOG.debug("read previous version {} from file", versionString);
return Version.parse(versionString);
} catch (IOException e) {
throw new IllegalStateException("failed to read version file", e);
}
}
static boolean isToOld() {
return new Versions(SCMContext.getContext()).isPreviousVersionToOld();
}
static void writeNew() {
new Versions(SCMContext.getContext()).writeNewVersion();
}
}