Fix exploded war deployment in application container

I0a7ade3c refactored GWT UI serving and considered two major cases:

1. war deployment - prod mode
2. exploded war deployment - dev mode

Unfortunately one use case was missed:

3. exploded war deployment in application container - prod mode

This broke the serving of GWT UI, because in this mode, the launcher
is loaded from exploded war archive, and thus from the path like:

  <path/to/container>/gerrit/WEB-INF/lib/gerrit-launcher-launcher.jar

This path is erroneously detected as war archive and gerrit_ui path
is tried to serve from this JAR, that obviously can't work.

Apply some heuristic on returned path from gerrit launcher source and
reshuffle the code in static servlet to make it work again.

Similar fix was applied to serving polygerrit UI. The simple case
was also fixed, however, it's still broken because polygerrit cannot
handle correctly context path for now. First request is correctly
served for host:port/gerrit/, but subsequent requests are failing
because context "gerrit" is lost: host:port/styles/main.css and not:
host:port/gerrit/styles/main.css

Test Plan:

Scenario I: Prod mode in embedded Jetty

1. deploy gerrit.war in embedded Jetty
2. confirm that it works as expected

Scenario II: Prod mode in standalone application container

1. setup application container (e.g. Tomcat)
2. deploy gerrit in exploded war mode
3. confirm that it works as expected

Scenario III: Development mode in Eclipse

1. start eclipse SDM debug session
2. confirm that it works as expected

Scenario IV: Development mode polygerrit

1. start polygerrit in development mode from the CLI
2. confirm that it works as expected

Bug: Issue 3758
Change-Id: Ia4b252cd7a13bb487baa1368661dc24e1c4b002f
This commit is contained in:
David Ostrovsky
2016-01-10 17:24:38 +01:00
committed by David Pursehouse
parent ad5f4ab17a
commit 6f88ac05b1
2 changed files with 62 additions and 19 deletions

View File

@@ -22,19 +22,23 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
class DeveloperGwtUiServlet extends ResourceServlet {
class DirectoryGwtUiServlet extends ResourceServlet {
private static final long serialVersionUID = 1L;
private static final FileTime NOW = FileTime.fromMillis(TimeUtil.nowMs());
private final Path ui;
DeveloperGwtUiServlet(Cache<Path, Resource> cache, Path unpackedWar)
throws IOException {
DirectoryGwtUiServlet(Cache<Path, Resource> cache, Path unpackedWar,
boolean dev) throws IOException {
super(cache, false);
ui = unpackedWar.resolve("gerrit_ui");
Files.createDirectory(ui);
ui.toFile().deleteOnExit();
if (!Files.exists(ui)) {
Files.createDirectory(ui);
}
if (dev) {
ui.toFile().deleteOnExit();
}
}
@Override

View File

@@ -179,7 +179,11 @@ public class StaticModule extends ServletModule {
}
private Path webappSourcePath(String name) {
return getPaths().buckOut.resolveSibling("gerrit-war").resolve("src")
Paths p = getPaths();
if (p.unpackedWar != null) {
return p.unpackedWar.resolve(name);
}
return p.buckOut.resolveSibling("gerrit-war").resolve("src")
.resolve("main").resolve("webapp").resolve(name);
}
}
@@ -190,7 +194,7 @@ public class StaticModule extends ServletModule {
serveRegex("^/gerrit_ui/(?!rpc/)(.*)$")
.with(Key.get(HttpServlet.class, Names.named(GWT_UI_SERVLET)));
Paths p = getPaths();
if (p.warFs == null && p.buckOut != null) {
if (p.isDev()) {
filter("/").through(new RecompileGwtUiFilter(p.buckOut, p.unpackedWar));
}
}
@@ -204,7 +208,7 @@ public class StaticModule extends ServletModule {
if (p.warFs != null) {
return new WarGwtUiServlet(cache, p.warFs);
} else {
return new DeveloperGwtUiServlet(cache, p.unpackedWar);
return new DirectoryGwtUiServlet(cache, p.unpackedWar, p.isDev());
}
}
}
@@ -244,7 +248,8 @@ public class StaticModule extends ServletModule {
HttpServlet getPolyGerritUiIndexServlet(
@Named(CACHE) Cache<Path, Resource> cache) {
return new SingleFileServlet(
cache, polyGerritBasePath().resolve("index.html"), isDev());
cache, polyGerritBasePath().resolve("index.html"),
getPaths().isDev());
}
@Provides
@@ -261,19 +266,20 @@ public class StaticModule extends ServletModule {
return new BowerComponentsServlet(cache, getPaths().buckOut);
}
private boolean isDev() {
return options.forcePolyGerritDev() || getPaths().warFs == null;
}
private Path polyGerritBasePath() {
Paths p = getPaths();
if (options.forcePolyGerritDev()) {
checkArgument(p.buckOut != null,
"no buck-out directory found for PolyGerrit developer mode");
}
return isDev()
? p.buckOut.getParent().resolve("polygerrit-ui").resolve("app")
: p.warFs.getPath("/polygerrit_ui");
if (p.isDev()) {
return p.buckOut.getParent().resolve("polygerrit-ui").resolve("app");
}
return p.warFs != null
? p.warFs.getPath("/polygerrit_ui")
: p.unpackedWar.resolve("polygerrit_ui");
}
}
@@ -281,19 +287,41 @@ public class StaticModule extends ServletModule {
private final FileSystem warFs;
private final Path buckOut;
private final Path unpackedWar;
private final boolean development;
private Paths() {
try {
warFs = getDistributionArchive();
File launcherLoadedFrom = getLauncherLoadedFrom();
if (launcherLoadedFrom != null
&& launcherLoadedFrom.getName().endsWith(".jar")) {
// Special case: unpacked war archive deployed in container.
// The path is something like:
// <container>/<gerrit>/WEB-INF/lib/launcher.jar
// Switch to exploded war case with <container>/webapp>/<gerrit>
// root directory
warFs = null;
unpackedWar = java.nio.file.Paths.get(launcherLoadedFrom
.getParentFile()
.getParentFile()
.getParentFile()
.toURI());
buckOut = null;
development = false;
return;
}
warFs = getDistributionArchive(launcherLoadedFrom);
if (warFs == null) {
buckOut = getDeveloperBuckOut();
unpackedWar = makeWarTempDir();
development = true;
} else if (options.forcePolyGerritDev()) {
buckOut = getDeveloperBuckOut();
unpackedWar = null;
development = true;
} else {
buckOut = null;
unpackedWar = null;
development = false;
}
} catch (IOException e) {
throw new ProvisionException(
@@ -301,7 +329,14 @@ public class StaticModule extends ServletModule {
}
}
private FileSystem getDistributionArchive() throws IOException {
private FileSystem getDistributionArchive(File war) throws IOException {
if (war == null) {
return null;
}
return GerritLauncher.getZipFileSystem(war.toPath());
}
private File getLauncherLoadedFrom() {
File war;
try {
war = GerritLauncher.getDistributionArchive();
@@ -316,7 +351,11 @@ public class StaticModule extends ServletModule {
throw pe;
}
}
return GerritLauncher.getZipFileSystem(war.toPath());
return war;
}
private boolean isDev() {
return development;
}
private Path getDeveloperBuckOut() {