Browse Source

create sonar-webserver from sonar-server

contains the Web Server "executable", the Pico Container definition (to allow building it up from multiple modules) and Tomcat/JEE specific code
tags/8.0
Sébastien Lesaint 4 years ago
parent
commit
4a557e2695
60 changed files with 563 additions and 432 deletions
  1. 5
    395
      server/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
  2. 1
    1
      server/sonar-server/src/main/java/org/sonar/server/platform/web/requestid/RequestIdMDCStorage.java
  3. 3
    3
      server/sonar-web/public/WEB-INF/web.xml
  4. 26
    0
      server/sonar-webserver/build.gradle
  5. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/app/EmbeddedTomcat.java
  6. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/app/NullJarScanner.java
  7. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/app/ProgrammaticLogbackValve.java
  8. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/app/TomcatAccessLog.java
  9. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/app/TomcatConnectors.java
  10. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/app/TomcatContexts.java
  11. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/app/TomcatStartupLogs.java
  12. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/app/WebServer.java
  13. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/app/package-info.java
  14. 423
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/PlatformImpl.java
  15. 23
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/package-info.java
  16. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel.java
  17. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java
  18. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java
  19. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java
  20. 0
    2
      server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
  21. 1
    3
      server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelSafeMode.java
  22. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java
  23. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/package-info.java
  24. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/web/CacheControlFilter.java
  25. 2
    2
      server/sonar-webserver/src/main/java/org/sonar/server/platform/web/MasterServletFilter.java
  26. 7
    7
      server/sonar-webserver/src/main/java/org/sonar/server/platform/web/PlatformServletContextListener.java
  27. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/web/RedirectFilter.java
  28. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/web/RegisterServletFilters.java
  29. 5
    2
      server/sonar-webserver/src/main/java/org/sonar/server/platform/web/RequestIdFilter.java
  30. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/web/SecurityServletFilter.java
  31. 4
    4
      server/sonar-webserver/src/main/java/org/sonar/server/platform/web/StaticResourcesServlet.java
  32. 3
    2
      server/sonar-webserver/src/main/java/org/sonar/server/platform/web/UserSessionFilter.java
  33. 0
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/web/WebPagesCache.java
  34. 2
    2
      server/sonar-webserver/src/main/java/org/sonar/server/platform/web/WebPagesFilter.java
  35. 23
    0
      server/sonar-webserver/src/main/java/org/sonar/server/platform/web/package-info.java
  36. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/app/EmbeddedTomcatTest.java
  37. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/app/NullJarScannerTest.java
  38. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/app/ProgrammaticLogbackValveTest.java
  39. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/app/StartupLogsTest.java
  40. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/app/TomcatAccessLogTest.java
  41. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/app/TomcatConnectorsTest.java
  42. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/app/TomcatContextsTest.java
  43. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel1Test.java
  44. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java
  45. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevelTest.java
  46. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/platform/web/CacheControlFilterTest.java
  47. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/platform/web/MasterServletFilterTest.java
  48. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/platform/web/RedirectFilterTest.java
  49. 1
    3
      server/sonar-webserver/src/test/java/org/sonar/server/platform/web/RegisterServletFiltersTest.java
  50. 3
    2
      server/sonar-webserver/src/test/java/org/sonar/server/platform/web/RequestIdFilterTest.java
  51. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/platform/web/RootFilterTest.java
  52. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/platform/web/SecurityServletFilterTest.java
  53. 1
    1
      server/sonar-webserver/src/test/java/org/sonar/server/platform/web/StaticResourcesServletTest.java
  54. 1
    1
      server/sonar-webserver/src/test/java/org/sonar/server/platform/web/UserSessionFilterTest.java
  55. 1
    1
      server/sonar-webserver/src/test/java/org/sonar/server/platform/web/WebPagesCacheTest.java
  56. 0
    0
      server/sonar-webserver/src/test/java/org/sonar/server/platform/web/WebPagesFilterTest.java
  57. 26
    0
      server/sonar-webserver/src/test/resources/logback-test.xml
  58. 0
    0
      server/sonar-webserver/src/test/resources/static/foo.txt
  59. 1
    0
      settings.gradle
  60. 1
    1
      sonar-application/build.gradle

+ 5
- 395
server/sonar-server/src/main/java/org/sonar/server/platform/Platform.java View File

@@ -19,406 +19,16 @@
*/
package org.sonar.server.platform;

import com.google.common.collect.Lists;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import javax.servlet.ServletContext;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.api.utils.log.Profiler;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.server.app.ProcessCommandWrapper;
import org.sonar.server.platform.db.migration.version.DatabaseVersion;
import org.sonar.server.platform.platformlevel.PlatformLevel;
import org.sonar.server.platform.platformlevel.PlatformLevel1;
import org.sonar.server.platform.platformlevel.PlatformLevel2;
import org.sonar.server.platform.platformlevel.PlatformLevel3;
import org.sonar.server.platform.platformlevel.PlatformLevel4;
import org.sonar.server.platform.platformlevel.PlatformLevelSafeMode;
import org.sonar.server.platform.platformlevel.PlatformLevelStartup;

/**
* @since 2.2
*/
public class Platform {

private static final Logger LOGGER = Loggers.get(Platform.class);

private static final Platform INSTANCE = new Platform();

private final Supplier<AutoStarter> autoStarterSupplier;
private AutoStarter autoStarter = null;
private Properties properties;
private ServletContext servletContext;
private PlatformLevel level1;
private PlatformLevel level2;
private PlatformLevel levelSafeMode;
private PlatformLevel level3;
private PlatformLevel level4;
private PlatformLevel currentLevel;
private boolean dbConnected = false;
private boolean started = false;
private final List<Object> level4AddedComponents = Lists.newArrayList();
private final Profiler profiler = Profiler.createIfTrace(Loggers.get(Platform.class));

private Platform() {
this.autoStarterSupplier = () -> {
ProcessCommandWrapper processCommandWrapper = getContainer().getComponentByType(ProcessCommandWrapper.class);
return new AsynchronousAutoStarter(processCommandWrapper);
};
}

protected Platform(Supplier<AutoStarter> autoStarterSupplier) {
this.autoStarterSupplier = autoStarterSupplier;
}

public static Platform getInstance() {
return INSTANCE;
}

public void init(Properties properties, ServletContext servletContext) {
this.properties = properties;
this.servletContext = servletContext;
if (!dbConnected) {
startLevel1Container();
startLevel2Container();
currentLevel = level2;
dbConnected = true;
}
}

// Platform is injected in Pico, so do not rename this method "start"
public void doStart() {
doStart(Startup.ALL);
}

protected void doStart(Startup startup) {
if (started && !isInSafeMode()) {
return;
}

boolean dbRequiredMigration = dbRequiresMigration();
startSafeModeContainer();
currentLevel = levelSafeMode;
started = true;

// if AutoDbMigration kicked in or no DB migration was required, startup can be resumed in another thread
if (dbRequiresMigration()) {
LOGGER.info("Database needs to be migrated. Please refer to https://docs.sonarqube.org/latest/setup/upgrading");
} else {
this.autoStarter = autoStarterSupplier.get();
this.autoStarter.execute(new AutoStarterRunnable(autoStarter) {
@Override
public void doRun() {
if (dbRequiredMigration) {
LOGGER.info("Database has been automatically updated");
}
runIfNotAborted(Platform.this::startLevel34Containers);

runIfNotAborted(() -> executeStartupTasks(startup));
// switch current container last to avoid giving access to a partially initialized container
runIfNotAborted(() -> {
currentLevel = level4;
LOGGER.info("WebServer is operational");
});

// stop safemode container if it existed
runIfNotAborted(Platform.this::stopSafeModeContainer);
}
});
}
}

private boolean dbRequiresMigration() {
return getDatabaseStatus() != DatabaseVersion.Status.UP_TO_DATE;
}
public interface Platform {
void doStart();

public boolean isStarted() {
return status() == Status.UP;
}

public boolean isInSafeMode() {
return status() == Status.SAFEMODE;
}

public Status status() {
if (!started) {
return Status.BOOTING;
}
PlatformLevel current = this.currentLevel;
PlatformLevel levelSafe = this.levelSafeMode;
if (levelSafe != null && current == levelSafe) {
return isRunning(this.autoStarter) ? Status.STARTING : Status.SAFEMODE;
}
if (current == level4) {
return Status.UP;
}
return Status.BOOTING;
}

private static boolean isRunning(@Nullable AutoStarter autoStarter) {
return autoStarter != null && autoStarter.isRunning();
}

/**
* Starts level 1
*/
private void startLevel1Container() {
level1 = start(new PlatformLevel1(this, properties, servletContext));
}

/**
* Starts level 2
*/
private void startLevel2Container() {
level2 = start(new PlatformLevel2(level1));
}
Status status();

/**
* Starts level 3 and 4
*/
private void startLevel34Containers() {
level3 = start(new PlatformLevel3(level2));
level4 = start(new PlatformLevel4(level3, level4AddedComponents));
}

public void executeStartupTasks() {
executeStartupTasks(Startup.ALL);
}
ComponentContainer getContainer();

private void executeStartupTasks(Startup startup) {
if (startup.ordinal() >= Startup.ALL.ordinal()) {
new PlatformLevelStartup(level4)
.configure()
.start()
.stop()
.destroy();
}
}

private void startSafeModeContainer() {
levelSafeMode = start(new PlatformLevelSafeMode(level2));
}

private PlatformLevel start(PlatformLevel platformLevel) {
profiler.start();
platformLevel.configure();
profiler.stopTrace(String.format("%s configured", platformLevel.getName()));
profiler.start();
platformLevel.start();
profiler.stopTrace(String.format("%s started", platformLevel.getName()));

return platformLevel;
}

/**
* Stops level 1
*/
private void stopLevel1Container() {
if (level1 != null) {
level1.stop();
level1 = null;
}
}

/**
* Stops level 2, 3 and 4 containers cleanly if they exists.
* Call this method before {@link #startLevel1Container()} to avoid duplicate attempt to stop safemode container
* components (since calling stop on a container calls stop on its children too, see
* {@link ComponentContainer#stopComponents()}).
*/
private void stopLevel234Containers() {
if (level2 != null) {
level2.stop();
level2 = null;
level3 = null;
level4 = null;
}
}

/**
* Stops safemode container cleanly if it exists.
* Call this method before {@link #stopLevel234Containers()} and {@link #stopLevel1Container()} to avoid duplicate
* attempt to stop safemode container components (since calling stop on a container calls stops on its children too,
* see {@link ComponentContainer#stopComponents()}).
*/
private void stopSafeModeContainer() {
if (levelSafeMode != null) {
levelSafeMode.stop();
levelSafeMode = null;
}
}

private DatabaseVersion.Status getDatabaseStatus() {
DatabaseVersion version = getContainer().getComponentByType(DatabaseVersion.class);
return version.getStatus();
}

// Do not rename "stop"
public void doStop() {
try {
stopAutoStarter();
stopSafeModeContainer();
stopLevel234Containers();
stopLevel1Container();
currentLevel = null;
dbConnected = false;
started = false;
} catch (Exception e) {
LOGGER.error("Fail to stop server - ignored", e);
}
}

private void stopAutoStarter() {
if (autoStarter != null) {
autoStarter.abort();
autoStarter = null;
}
}

public void addComponents(Collection<?> components) {
level4AddedComponents.addAll(components);
}

public ComponentContainer getContainer() {
return currentLevel.getContainer();
}

public Object getComponent(Object key) {
return getContainer().getComponentByKey(key);
}

public enum Status {
enum Status {
BOOTING, SAFEMODE, STARTING, UP
}

public enum Startup {
NO_STARTUP_TASKS, ALL
}

public interface AutoStarter {
/**
* Let the autostarted execute the provided code.
*/
void execute(Runnable startCode);

/**
* This method is called by executed start code (see {@link #execute(Runnable)} has finished with a failure.
*/
void failure(Throwable t);

/**
* This method is called by executed start code (see {@link #execute(Runnable)} has finished successfully.
*/
void success();

/**
* Indicates whether the AutoStarter is running.
*/
boolean isRunning();

/**
* Requests the startcode (ie. the argument of {@link #execute(Runnable)}) aborts its processing (if it supports it).
*/
void abort();

/**
* Indicates whether {@link #abort()} was invoked.
* <p>
* This method can be used by the start code to check whether it should proceed running or stop.
* </p>
*/
boolean isAborting();

/**
* Called when abortion is complete.
* <p>
* Start code support abortion should call this method once is done processing and if it stopped on abortion.
* </p>
*/
void aborted();
}

private abstract static class AutoStarterRunnable implements Runnable {
private final AutoStarter autoStarter;

AutoStarterRunnable(AutoStarter autoStarter) {
this.autoStarter = autoStarter;
}

@Override
public void run() {
try {
doRun();
} catch (Throwable t) {
autoStarter.failure(t);
} finally {
if (autoStarter.isAborting()) {
autoStarter.aborted();
} else {
autoStarter.success();
}
}
}

abstract void doRun();

void runIfNotAborted(Runnable r) {
if (!autoStarter.isAborting()) {
r.run();
}
}
}

private static final class AsynchronousAutoStarter implements AutoStarter {
private final ProcessCommandWrapper processCommandWrapper;
private boolean running = true;
private boolean abort = false;

private AsynchronousAutoStarter(ProcessCommandWrapper processCommandWrapper) {
this.processCommandWrapper = processCommandWrapper;
}

@Override
public void execute(Runnable startCode) {
new Thread(startCode, "SQ starter").start();
}

@Override
public void failure(Throwable t) {
LOGGER.error("Background initialization failed. Stopping SonarQube", t);
processCommandWrapper.requestHardStop();
this.running = false;
}

@Override
public void success() {
LOGGER.debug("Background initialization of SonarQube done");
this.running = false;
}

@Override
public void aborted() {
LOGGER.debug("Background initialization of SonarQube aborted");
this.running = false;
}

@Override
public boolean isRunning() {
return running;
}

@Override
public void abort() {
this.abort = true;
}

@Override
public boolean isAborting() {
return this.abort;
}
}
}

+ 1
- 1
server/sonar-server/src/main/java/org/sonar/server/platform/web/requestid/RequestIdMDCStorage.java View File

@@ -29,7 +29,7 @@ import static java.util.Objects.requireNonNull;
public class RequestIdMDCStorage implements AutoCloseable {
public static final String HTTP_REQUEST_ID_MDC_KEY = "HTTP_REQUEST_ID";

RequestIdMDCStorage(String requestId) {
public RequestIdMDCStorage(String requestId) {
MDC.put(HTTP_REQUEST_ID_MDC_KEY, requireNonNull(requestId, "Request ID can't be null"));
}


+ 3
- 3
server/sonar-web/public/WEB-INF/web.xml View File

@@ -14,7 +14,7 @@
</filter>
<filter>
<filter-name>UserSessionFilter</filter-name>
<filter-class>org.sonar.server.user.UserSessionFilter</filter-class>
<filter-class>org.sonar.server.platform.web.UserSessionFilter</filter-class>
</filter>
<filter>
<filter-name>SetCharacterEncodingFilter</filter-name>
@@ -38,7 +38,7 @@
</filter>
<filter>
<filter-name>RequestUidFilter</filter-name>
<filter-class>org.sonar.server.platform.web.requestid.RequestIdFilter</filter-class>
<filter-class>org.sonar.server.platform.web.RequestIdFilter</filter-class>
</filter>
<filter>
<filter-name>WebPagesFilter</filter-name>
@@ -89,7 +89,7 @@

<servlet>
<servlet-name>static</servlet-name>
<servlet-class>org.sonar.server.plugins.StaticResourcesServlet</servlet-class>
<servlet-class>org.sonar.server.platform.web.StaticResourcesServlet</servlet-class>
</servlet>

<servlet-mapping>

+ 26
- 0
server/sonar-webserver/build.gradle View File

@@ -0,0 +1,26 @@
description = 'SonarQube WebServer'

sonarqube {
properties {
property 'sonar.projectName', "${projectTitle} :: WebServer"
}
}

dependencies {
// please keep the list grouped by configuration and ordered by name

compile 'com.google.guava:guava'
compile 'org.apache.tomcat.embed:tomcat-embed-core'
compile project(':sonar-core')
compile project(':server:sonar-process')
compile project(':server:sonar-server')
compile project(':server:sonar-server-common')

compileOnly 'com.google.code.findbugs:jsr305'

testCompile 'com.google.code.findbugs:jsr305'
testCompile 'org.eclipse.jetty:jetty-server'
testCompile 'org.eclipse.jetty:jetty-servlet'
testCompile 'org.mockito:mockito-core'
testCompile project(':sonar-testing-harness')
}

server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java → server/sonar-webserver/src/main/java/org/sonar/server/app/EmbeddedTomcat.java View File


server/sonar-server/src/main/java/org/sonar/server/app/NullJarScanner.java → server/sonar-webserver/src/main/java/org/sonar/server/app/NullJarScanner.java View File


server/sonar-server/src/main/java/org/sonar/server/app/ProgrammaticLogbackValve.java → server/sonar-webserver/src/main/java/org/sonar/server/app/ProgrammaticLogbackValve.java View File


server/sonar-server/src/main/java/org/sonar/server/app/TomcatAccessLog.java → server/sonar-webserver/src/main/java/org/sonar/server/app/TomcatAccessLog.java View File


server/sonar-server/src/main/java/org/sonar/server/app/TomcatConnectors.java → server/sonar-webserver/src/main/java/org/sonar/server/app/TomcatConnectors.java View File


server/sonar-server/src/main/java/org/sonar/server/app/TomcatContexts.java → server/sonar-webserver/src/main/java/org/sonar/server/app/TomcatContexts.java View File


server/sonar-server/src/main/java/org/sonar/server/app/TomcatStartupLogs.java → server/sonar-webserver/src/main/java/org/sonar/server/app/TomcatStartupLogs.java View File


server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java → server/sonar-webserver/src/main/java/org/sonar/server/app/WebServer.java View File


server/sonar-server/src/main/java/org/sonar/server/app/package-info.java → server/sonar-webserver/src/main/java/org/sonar/server/app/package-info.java View File


+ 423
- 0
server/sonar-webserver/src/main/java/org/sonar/server/platform/PlatformImpl.java View File

@@ -0,0 +1,423 @@
/*
* SonarQube
* Copyright (C) 2009-2019 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform;

import com.google.common.collect.Lists;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import javax.servlet.ServletContext;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.api.utils.log.Profiler;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.server.app.ProcessCommandWrapper;
import org.sonar.server.platform.db.migration.version.DatabaseVersion;
import org.sonar.server.platform.platformlevel.PlatformLevel;
import org.sonar.server.platform.platformlevel.PlatformLevel1;
import org.sonar.server.platform.platformlevel.PlatformLevel2;
import org.sonar.server.platform.platformlevel.PlatformLevel3;
import org.sonar.server.platform.platformlevel.PlatformLevel4;
import org.sonar.server.platform.platformlevel.PlatformLevelSafeMode;
import org.sonar.server.platform.platformlevel.PlatformLevelStartup;

/**
* @since 2.2
*/
public class PlatformImpl implements Platform {

private static final Logger LOGGER = Loggers.get(Platform.class);

private static final PlatformImpl INSTANCE = new PlatformImpl();

private final Supplier<AutoStarter> autoStarterSupplier;
private AutoStarter autoStarter = null;
private Properties properties;
private ServletContext servletContext;
private PlatformLevel level1;
private PlatformLevel level2;
private PlatformLevel levelSafeMode;
private PlatformLevel level3;
private PlatformLevel level4;
private PlatformLevel currentLevel;
private boolean dbConnected = false;
private boolean started = false;
private final List<Object> level4AddedComponents = Lists.newArrayList();
private final Profiler profiler = Profiler.createIfTrace(Loggers.get(PlatformImpl.class));

private PlatformImpl() {
this.autoStarterSupplier = () -> {
ProcessCommandWrapper processCommandWrapper = getContainer().getComponentByType(ProcessCommandWrapper.class);
return new AsynchronousAutoStarter(processCommandWrapper);
};
}

protected PlatformImpl(Supplier<AutoStarter> autoStarterSupplier) {
this.autoStarterSupplier = autoStarterSupplier;
}

public static PlatformImpl getInstance() {
return INSTANCE;
}

public void init(Properties properties, ServletContext servletContext) {
this.properties = properties;
this.servletContext = servletContext;
if (!dbConnected) {
startLevel1Container();
startLevel2Container();
currentLevel = level2;
dbConnected = true;
}
}

// Platform is injected in Pico, so do not rename this method "start"
@Override
public void doStart() {
doStart(Startup.ALL);
}

protected void doStart(Startup startup) {
if (started && !isInSafeMode()) {
return;
}

boolean dbRequiredMigration = dbRequiresMigration();
startSafeModeContainer();
currentLevel = levelSafeMode;
started = true;

// if AutoDbMigration kicked in or no DB migration was required, startup can be resumed in another thread
if (dbRequiresMigration()) {
LOGGER.info("Database needs to be migrated. Please refer to https://docs.sonarqube.org/latest/setup/upgrading");
} else {
this.autoStarter = autoStarterSupplier.get();
this.autoStarter.execute(new AutoStarterRunnable(autoStarter) {
@Override
public void doRun() {
if (dbRequiredMigration) {
LOGGER.info("Database has been automatically updated");
}
runIfNotAborted(PlatformImpl.this::startLevel34Containers);

runIfNotAborted(() -> executeStartupTasks(startup));
// switch current container last to avoid giving access to a partially initialized container
runIfNotAborted(() -> {
currentLevel = level4;
LOGGER.info("WebServer is operational");
});

// stop safemode container if it existed
runIfNotAborted(PlatformImpl.this::stopSafeModeContainer);
}
});
}
}

private boolean dbRequiresMigration() {
return getDatabaseStatus() != DatabaseVersion.Status.UP_TO_DATE;
}

public boolean isStarted() {
return status() == Status.UP;
}

public boolean isInSafeMode() {
return status() == Status.SAFEMODE;
}

@Override
public Status status() {
if (!started) {
return Status.BOOTING;
}
PlatformLevel current = this.currentLevel;
PlatformLevel levelSafe = this.levelSafeMode;
if (levelSafe != null && current == levelSafe) {
return isRunning(this.autoStarter) ? Status.STARTING : Status.SAFEMODE;
}
if (current == level4) {
return Status.UP;
}
return Status.BOOTING;
}

private static boolean isRunning(@Nullable AutoStarter autoStarter) {
return autoStarter != null && autoStarter.isRunning();
}

/**
* Starts level 1
*/
private void startLevel1Container() {
level1 = start(new PlatformLevel1(this, properties, servletContext));
}

/**
* Starts level 2
*/
private void startLevel2Container() {
level2 = start(new PlatformLevel2(level1));
}

/**
* Starts level 3 and 4
*/
private void startLevel34Containers() {
level3 = start(new PlatformLevel3(level2));
level4 = start(new PlatformLevel4(level3, level4AddedComponents));
}

public void executeStartupTasks() {
executeStartupTasks(Startup.ALL);
}

private void executeStartupTasks(Startup startup) {
if (startup.ordinal() >= Startup.ALL.ordinal()) {
new PlatformLevelStartup(level4)
.configure()
.start()
.stop()
.destroy();
}
}

private void startSafeModeContainer() {
levelSafeMode = start(new PlatformLevelSafeMode(level2));
}

private PlatformLevel start(PlatformLevel platformLevel) {
profiler.start();
platformLevel.configure();
profiler.stopTrace(String.format("%s configured", platformLevel.getName()));
profiler.start();
platformLevel.start();
profiler.stopTrace(String.format("%s started", platformLevel.getName()));

return platformLevel;
}

/**
* Stops level 1
*/
private void stopLevel1Container() {
if (level1 != null) {
level1.stop();
level1 = null;
}
}

/**
* Stops level 2, 3 and 4 containers cleanly if they exists.
* Call this method before {@link #startLevel1Container()} to avoid duplicate attempt to stop safemode container
* components (since calling stop on a container calls stop on its children too, see
* {@link ComponentContainer#stopComponents()}).
*/
private void stopLevel234Containers() {
if (level2 != null) {
level2.stop();
level2 = null;
level3 = null;
level4 = null;
}
}

/**
* Stops safemode container cleanly if it exists.
* Call this method before {@link #stopLevel234Containers()} and {@link #stopLevel1Container()} to avoid duplicate
* attempt to stop safemode container components (since calling stop on a container calls stops on its children too,
* see {@link ComponentContainer#stopComponents()}).
*/
private void stopSafeModeContainer() {
if (levelSafeMode != null) {
levelSafeMode.stop();
levelSafeMode = null;
}
}

private DatabaseVersion.Status getDatabaseStatus() {
DatabaseVersion version = getContainer().getComponentByType(DatabaseVersion.class);
return version.getStatus();
}

// Do not rename "stop"
public void doStop() {
try {
stopAutoStarter();
stopSafeModeContainer();
stopLevel234Containers();
stopLevel1Container();
currentLevel = null;
dbConnected = false;
started = false;
} catch (Exception e) {
LOGGER.error("Fail to stop server - ignored", e);
}
}

private void stopAutoStarter() {
if (autoStarter != null) {
autoStarter.abort();
autoStarter = null;
}
}

public void addComponents(Collection<?> components) {
level4AddedComponents.addAll(components);
}

@Override
public ComponentContainer getContainer() {
return currentLevel.getContainer();
}

public Object getComponent(Object key) {
return getContainer().getComponentByKey(key);
}

public enum Startup {
NO_STARTUP_TASKS, ALL
}

public interface AutoStarter {
/**
* Let the autostarted execute the provided code.
*/
void execute(Runnable startCode);

/**
* This method is called by executed start code (see {@link #execute(Runnable)} has finished with a failure.
*/
void failure(Throwable t);

/**
* This method is called by executed start code (see {@link #execute(Runnable)} has finished successfully.
*/
void success();

/**
* Indicates whether the AutoStarter is running.
*/
boolean isRunning();

/**
* Requests the startcode (ie. the argument of {@link #execute(Runnable)}) aborts its processing (if it supports it).
*/
void abort();

/**
* Indicates whether {@link #abort()} was invoked.
* <p>
* This method can be used by the start code to check whether it should proceed running or stop.
* </p>
*/
boolean isAborting();

/**
* Called when abortion is complete.
* <p>
* Start code support abortion should call this method once is done processing and if it stopped on abortion.
* </p>
*/
void aborted();
}

private abstract static class AutoStarterRunnable implements Runnable {
private final AutoStarter autoStarter;

AutoStarterRunnable(AutoStarter autoStarter) {
this.autoStarter = autoStarter;
}

@Override
public void run() {
try {
doRun();
} catch (Throwable t) {
autoStarter.failure(t);
} finally {
if (autoStarter.isAborting()) {
autoStarter.aborted();
} else {
autoStarter.success();
}
}
}

abstract void doRun();

void runIfNotAborted(Runnable r) {
if (!autoStarter.isAborting()) {
r.run();
}
}
}

private static final class AsynchronousAutoStarter implements AutoStarter {
private final ProcessCommandWrapper processCommandWrapper;
private boolean running = true;
private boolean abort = false;

private AsynchronousAutoStarter(ProcessCommandWrapper processCommandWrapper) {
this.processCommandWrapper = processCommandWrapper;
}

@Override
public void execute(Runnable startCode) {
new Thread(startCode, "SQ starter").start();
}

@Override
public void failure(Throwable t) {
LOGGER.error("Background initialization failed. Stopping SonarQube", t);
processCommandWrapper.requestHardStop();
this.running = false;
}

@Override
public void success() {
LOGGER.debug("Background initialization of SonarQube done");
this.running = false;
}

@Override
public void aborted() {
LOGGER.debug("Background initialization of SonarQube aborted");
this.running = false;
}

@Override
public boolean isRunning() {
return running;
}

@Override
public void abort() {
this.abort = true;
}

@Override
public boolean isAborting() {
return this.abort;
}
}
}

+ 23
- 0
server/sonar-webserver/src/main/java/org/sonar/server/platform/package-info.java View File

@@ -0,0 +1,23 @@
/*
* SonarQube
* Copyright (C) 2009-2019 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@ParametersAreNonnullByDefault
package org.sonar.server.platform;

import javax.annotation.ParametersAreNonnullByDefault;

server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel.java View File


server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java View File


server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java View File


server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java View File


server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java View File

@@ -115,7 +115,6 @@ import org.sonar.server.platform.PersistentSettings;
import org.sonar.server.platform.SettingsChangeNotifier;
import org.sonar.server.platform.WebCoreExtensionsInstaller;
import org.sonar.server.platform.monitoring.WebSystemInfoModule;
import org.sonar.server.platform.web.WebPagesFilter;
import org.sonar.server.platform.web.requestid.HttpRequestIdModule;
import org.sonar.server.platform.ws.ChangeLogLevelActionModule;
import org.sonar.server.platform.ws.DbMigrationStatusAction;
@@ -255,7 +254,6 @@ public class PlatformLevel4 extends PlatformLevel {
ServerWs.class,
BackendCleanup.class,
IndexDefinitions.class,
WebPagesFilter.class,
WebAnalyticsLoaderImpl.class,

// batch

server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelSafeMode.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelSafeMode.java View File

@@ -19,7 +19,6 @@
*/
package org.sonar.server.platform.platformlevel;

import org.sonar.server.platform.ws.SafeModeHealthActionModule;
import org.sonar.server.authentication.SafeModeUserSession;
import org.sonar.server.organization.NoopDefaultOrganizationCache;
import org.sonar.server.platform.ServerImpl;
@@ -27,11 +26,11 @@ import org.sonar.server.platform.db.migration.AutoDbMigration;
import org.sonar.server.platform.db.migration.DatabaseMigrationImpl;
import org.sonar.server.platform.db.migration.MigrationEngineModule;
import org.sonar.server.platform.db.migration.NoopDatabaseMigrationImpl;
import org.sonar.server.platform.web.WebPagesFilter;
import org.sonar.server.platform.ws.DbMigrationStatusAction;
import org.sonar.server.platform.ws.IndexAction;
import org.sonar.server.platform.ws.L10nWs;
import org.sonar.server.platform.ws.MigrateDbAction;
import org.sonar.server.platform.ws.SafeModeHealthActionModule;
import org.sonar.server.platform.ws.StatusAction;
import org.sonar.server.platform.ws.SystemWs;
import org.sonar.server.ws.WebServiceEngine;
@@ -47,7 +46,6 @@ public class PlatformLevelSafeMode extends PlatformLevel {
protected void configureLevel() {
add(
ServerImpl.class,
WebPagesFilter.class,

// l10n WS
L10nWs.class,

server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java View File


server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/package-info.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/package-info.java View File


server/sonar-server/src/main/java/org/sonar/server/platform/web/CacheControlFilter.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/web/CacheControlFilter.java View File


server/sonar-server/src/main/java/org/sonar/server/platform/web/MasterServletFilter.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/web/MasterServletFilter.java View File

@@ -34,7 +34,7 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.sonar.api.utils.log.Loggers;
import org.sonar.api.web.ServletFilter;
import org.sonar.server.platform.Platform;
import org.sonar.server.platform.PlatformImpl;

/**
* Inspired by http://stackoverflow.com/a/7592883/229031
@@ -56,7 +56,7 @@ public class MasterServletFilter implements Filter {
public void init(FilterConfig config) {
// Filters are already available in picocontainer unless a database migration is required. See
// org.sonar.server.startup.RegisterServletFilters.
init(config, Platform.getInstance().getContainer().getComponentsByType(ServletFilter.class));
init(config, PlatformImpl.getInstance().getContainer().getComponentsByType(ServletFilter.class));
}

void init(FilterConfig config, List<ServletFilter> filters) {

server/sonar-server/src/main/java/org/sonar/server/platform/web/PlatformServletContextListener.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/web/PlatformServletContextListener.java View File

@@ -25,7 +25,7 @@ import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.sonar.api.utils.log.Loggers;
import org.sonar.server.platform.Platform;
import org.sonar.server.platform.PlatformImpl;

public final class PlatformServletContextListener implements ServletContextListener {
static final String STARTED_ATTRIBUTE = "sonarqube.started";
@@ -40,14 +40,14 @@ public final class PlatformServletContextListener implements ServletContextListe
String key = paramKeys.nextElement();
props.put(key, servletContext.getInitParameter(key));
}
Platform.getInstance().init(props, servletContext);
Platform.getInstance().doStart();
PlatformImpl.getInstance().init(props, servletContext);
PlatformImpl.getInstance().doStart();
event.getServletContext().setAttribute(STARTED_ATTRIBUTE, Boolean.TRUE);
} catch (org.sonar.api.utils.MessageException | org.sonar.process.MessageException e) {
Loggers.get(Platform.class).error("Web server startup failed: " + e.getMessage());
Loggers.get(PlatformImpl.class).error("Web server startup failed: " + e.getMessage());
stopQuietly();
} catch (Throwable t) {
Loggers.get(Platform.class).error("Web server startup failed", t);
Loggers.get(PlatformImpl.class).error("Web server startup failed", t);
stopQuietly();
throw new AbortTomcatStartException();
}
@@ -55,7 +55,7 @@ public final class PlatformServletContextListener implements ServletContextListe

private void stopQuietly() {
try {
Platform.getInstance().doStop();
PlatformImpl.getInstance().doStop();
} catch (Exception e) {
// ignored, but an error during startup generally prevents pico to be correctly stopped
}
@@ -63,7 +63,7 @@ public final class PlatformServletContextListener implements ServletContextListe

@Override
public void contextDestroyed(ServletContextEvent event) {
Platform.getInstance().doStop();
PlatformImpl.getInstance().doStop();
}

}

server/sonar-server/src/main/java/org/sonar/server/platform/web/RedirectFilter.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/web/RedirectFilter.java View File


server/sonar-server/src/main/java/org/sonar/server/platform/web/RegisterServletFilters.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/web/RegisterServletFilters.java View File


server/sonar-server/src/main/java/org/sonar/server/platform/web/requestid/RequestIdFilter.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/web/RequestIdFilter.java View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform.web.requestid;
package org.sonar.server.platform.web;

import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
@@ -28,6 +28,9 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.sonar.server.platform.Platform;
import org.sonar.server.platform.PlatformImpl;
import org.sonar.server.platform.web.requestid.RequestIdGenerator;
import org.sonar.server.platform.web.requestid.RequestIdMDCStorage;

/**
* A {@link Filter} that puts and removes the HTTP request ID from the {@link org.slf4j.MDC}.
@@ -37,7 +40,7 @@ public class RequestIdFilter implements Filter {
private final Platform platform;

public RequestIdFilter() {
this(Platform.getInstance());
this(PlatformImpl.getInstance());
}

@VisibleForTesting

server/sonar-server/src/main/java/org/sonar/server/platform/web/SecurityServletFilter.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/web/SecurityServletFilter.java View File


server/sonar-server/src/main/java/org/sonar/server/plugins/StaticResourcesServlet.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/web/StaticResourcesServlet.java View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.plugins;
package org.sonar.server.platform.web;

import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
@@ -34,7 +34,7 @@ import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.platform.PluginRepository;
import org.sonar.core.extension.CoreExtensionRepository;
import org.sonar.server.platform.Platform;
import org.sonar.server.platform.PlatformImpl;
import org.sonarqube.ws.MediaTypes;

import static java.lang.String.format;
@@ -130,11 +130,11 @@ public class StaticResourcesServlet extends HttpServlet {

static class System {
PluginRepository getPluginRepository() {
return Platform.getInstance().getContainer().getComponentByType(PluginRepository.class);
return PlatformImpl.getInstance().getContainer().getComponentByType(PluginRepository.class);
}

CoreExtensionRepository getCoreExtensionRepository() {
return Platform.getInstance().getContainer().getComponentByType(CoreExtensionRepository.class);
return PlatformImpl.getInstance().getContainer().getComponentByType(CoreExtensionRepository.class);
}

@CheckForNull

server/sonar-server/src/main/java/org/sonar/server/user/UserSessionFilter.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/web/UserSessionFilter.java View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.user;
package org.sonar.server.platform.web;

import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
@@ -36,6 +36,7 @@ import org.sonar.api.utils.log.Loggers;
import org.sonar.server.authentication.UserSessionInitializer;
import org.sonar.server.organization.DefaultOrganizationCache;
import org.sonar.server.platform.Platform;
import org.sonar.server.platform.PlatformImpl;
import org.sonar.server.setting.ThreadLocalSettings;

public class UserSessionFilter implements Filter {
@@ -43,7 +44,7 @@ public class UserSessionFilter implements Filter {
private final Platform platform;

public UserSessionFilter() {
this.platform = Platform.getInstance();
this.platform = PlatformImpl.getInstance();
}

@VisibleForTesting

server/sonar-server/src/main/java/org/sonar/server/platform/web/WebPagesCache.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/web/WebPagesCache.java View File


server/sonar-server/src/main/java/org/sonar/server/platform/web/WebPagesFilter.java → server/sonar-webserver/src/main/java/org/sonar/server/platform/web/WebPagesFilter.java View File

@@ -30,7 +30,7 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.sonar.api.web.ServletFilter;
import org.sonar.server.platform.Platform;
import org.sonar.server.platform.PlatformImpl;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Locale.ENGLISH;
@@ -56,7 +56,7 @@ public class WebPagesFilter implements Filter {
private WebPagesCache webPagesCache;

public WebPagesFilter() {
this(Platform.getInstance().getContainer().getComponentByType(WebPagesCache.class));
this(PlatformImpl.getInstance().getContainer().getComponentByType(WebPagesCache.class));
}

@VisibleForTesting

+ 23
- 0
server/sonar-webserver/src/main/java/org/sonar/server/platform/web/package-info.java View File

@@ -0,0 +1,23 @@
/*
* SonarQube
* Copyright (C) 2009-2019 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@ParametersAreNonnullByDefault
package org.sonar.server.platform.web;

import javax.annotation.ParametersAreNonnullByDefault;

server/sonar-server/src/test/java/org/sonar/server/app/EmbeddedTomcatTest.java → server/sonar-webserver/src/test/java/org/sonar/server/app/EmbeddedTomcatTest.java View File


server/sonar-server/src/test/java/org/sonar/server/app/NullJarScannerTest.java → server/sonar-webserver/src/test/java/org/sonar/server/app/NullJarScannerTest.java View File


server/sonar-server/src/test/java/org/sonar/server/app/ProgrammaticLogbackValveTest.java → server/sonar-webserver/src/test/java/org/sonar/server/app/ProgrammaticLogbackValveTest.java View File


server/sonar-server/src/test/java/org/sonar/server/app/StartupLogsTest.java → server/sonar-webserver/src/test/java/org/sonar/server/app/StartupLogsTest.java View File


server/sonar-server/src/test/java/org/sonar/server/app/TomcatAccessLogTest.java → server/sonar-webserver/src/test/java/org/sonar/server/app/TomcatAccessLogTest.java View File


server/sonar-server/src/test/java/org/sonar/server/app/TomcatConnectorsTest.java → server/sonar-webserver/src/test/java/org/sonar/server/app/TomcatConnectorsTest.java View File


server/sonar-server/src/test/java/org/sonar/server/app/TomcatContextsTest.java → server/sonar-webserver/src/test/java/org/sonar/server/app/TomcatContextsTest.java View File


server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel1Test.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel1Test.java View File


server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java View File


server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevelTest.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevelTest.java View File


server/sonar-server/src/test/java/org/sonar/server/platform/web/CacheControlFilterTest.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/web/CacheControlFilterTest.java View File


server/sonar-server/src/test/java/org/sonar/server/platform/web/MasterServletFilterTest.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/web/MasterServletFilterTest.java View File


server/sonar-server/src/test/java/org/sonar/server/platform/web/RedirectFilterTest.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/web/RedirectFilterTest.java View File


server/sonar-server/src/test/java/org/sonar/server/startup/RegisterServletFiltersTest.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/web/RegisterServletFiltersTest.java View File

@@ -17,13 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.startup;
package org.sonar.server.platform.web;

import javax.servlet.ServletException;
import org.junit.Test;
import org.sonar.api.web.ServletFilter;
import org.sonar.server.platform.web.MasterServletFilter;
import org.sonar.server.platform.web.RegisterServletFilters;

import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.Mockito.mock;

server/sonar-server/src/test/java/org/sonar/server/platform/web/requestid/RequestIdFilterTest.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/web/RequestIdFilterTest.java View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.platform.web.requestid;
package org.sonar.server.platform.web;

import java.io.IOException;
import javax.servlet.FilterChain;
@@ -29,6 +29,7 @@ import org.junit.Test;
import org.slf4j.MDC;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.server.platform.Platform;
import org.sonar.server.platform.web.requestid.RequestIdGenerator;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
@@ -48,7 +49,7 @@ public class RequestIdFilterTest {
private RequestIdFilter underTest = new RequestIdFilter(platform);

@Before
public void setUp() throws Exception {
public void setUp() {
ComponentContainer container = new ComponentContainer();
container.add(requestIdGenerator);
when(platform.getContainer()).thenReturn(container);

server/sonar-server/src/test/java/org/sonar/server/platform/web/RootFilterTest.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/web/RootFilterTest.java View File


server/sonar-server/src/test/java/org/sonar/server/platform/web/SecurityServletFilterTest.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/web/SecurityServletFilterTest.java View File


server/sonar-server/src/test/java/org/sonar/server/plugins/StaticResourcesServletTest.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/web/StaticResourcesServletTest.java View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.plugins;
package org.sonar.server.platform.web;

import java.io.IOException;
import java.io.InputStream;

server/sonar-server/src/test/java/org/sonar/server/user/UserSessionFilterTest.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/web/UserSessionFilterTest.java View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.user;
package org.sonar.server.platform.web;

import java.io.IOException;
import javax.servlet.FilterChain;

server/sonar-server/src/test/java/org/sonar/server/platform/web/WebPagesCacheTest.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/web/WebPagesCacheTest.java View File

@@ -55,7 +55,7 @@ public class WebPagesCacheTest {
private WebPagesCache underTest = new WebPagesCache(platform, mapSettings.asConfig(), officialDistribution);

@Before
public void setUp() throws Exception {
public void setUp() {
when(servletContext.getContextPath()).thenReturn(TEST_CONTEXT);
when(servletContext.getResourceAsStream("/index.html")).thenAnswer(
(Answer<InputStream>) invocationOnMock -> toInputStream("Content of default index.html with context [%WEB_CONTEXT%], status [%SERVER_STATUS%], instance [%INSTANCE%]",

server/sonar-server/src/test/java/org/sonar/server/platform/web/WebPagesFilterTest.java → server/sonar-webserver/src/test/java/org/sonar/server/platform/web/WebPagesFilterTest.java View File


+ 26
- 0
server/sonar-webserver/src/test/resources/logback-test.xml View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" ?>
<configuration debug="false">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>
%d{yyyy.MM.dd HH:mm:ss} %-5level %msg%n
</pattern>
</encoder>
</appender>

<root>
<level value="INFO"/>
<appender-ref ref="CONSOLE"/>
</root>

<logger name="ch.qos.logback">
<level value="WARN"/>
</logger>

<logger name="okhttp3.mockwebserver">
<level value="WARN"/>
</logger>

</configuration>

server/sonar-server/src/test/resources/static/foo.txt → server/sonar-webserver/src/test/resources/static/foo.txt View File


+ 1
- 0
settings.gradle View File

@@ -17,6 +17,7 @@ include 'server:sonar-server'
include 'server:sonar-server-common'
include 'server:sonar-vsts'
include 'server:sonar-web'
include 'server:sonar-webserver'
include 'server:sonar-webserver-ws'

include 'sonar-application'

+ 1
- 1
sonar-application/build.gradle View File

@@ -34,7 +34,7 @@ dependencies {
compile project(':server:sonar-ce')
compile project(':server:sonar-main')
compile project(':server:sonar-process')
compile project(':server:sonar-server')
compile project(':server:sonar-webserver')
compile project(':sonar-core')
compile project(path: ':sonar-plugin-api', configuration: 'shadow')
compile project(':sonar-plugin-api-impl')

Loading…
Cancel
Save