aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2019-08-08 12:28:41 +0200
committerSonarTech <sonartech@sonarsource.com>2019-08-14 20:21:12 +0200
commit4a557e2695c1ff7af001361dba25528f408bb833 (patch)
treeab30f994fb9f15bf399feb2551f76335a3006a4c /server/sonar-server
parent980b9f16b8a34364489d2ed3a8472f725eea4770 (diff)
downloadsonarqube-4a557e2695c1ff7af001361dba25528f408bb833.tar.gz
sonarqube-4a557e2695c1ff7af001361dba25528f408bb833.zip
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
Diffstat (limited to 'server/sonar-server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java124
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/app/NullJarScanner.java49
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/app/ProgrammaticLogbackValve.java46
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/app/TomcatAccessLog.java79
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/app/TomcatConnectors.java94
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/app/TomcatContexts.java127
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/app/TomcatStartupLogs.java50
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java101
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/app/package-info.java23
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/Platform.java400
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel.java220
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java162
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java111
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java69
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java549
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelSafeMode.java78
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java99
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/package-info.java23
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/web/CacheControlFilter.java83
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/web/MasterServletFilter.java138
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/web/PlatformServletContextListener.java69
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/web/RedirectFilter.java110
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/web/RegisterServletFilters.java54
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/web/SecurityServletFilter.java83
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/web/WebPagesCache.java113
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/web/WebPagesFilter.java93
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/web/requestid/RequestIdFilter.java73
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/web/requestid/RequestIdMDCStorage.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/plugins/StaticResourcesServlet.java159
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/user/UserSessionFilter.java105
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/app/EmbeddedTomcatTest.java80
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/app/NullJarScannerTest.java46
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/app/ProgrammaticLogbackValveTest.java49
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/app/StartupLogsTest.java86
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/app/TomcatAccessLogTest.java82
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/app/TomcatConnectorsTest.java145
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/app/TomcatContextsTest.java137
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel1Test.java45
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java90
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevelTest.java91
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/web/CacheControlFilterTest.java111
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/web/MasterServletFilterTest.java202
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/web/RedirectFilterTest.java84
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/web/RootFilterTest.java149
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/web/SecurityServletFilterTest.java127
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/web/WebPagesCacheTest.java168
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/web/WebPagesFilterTest.java121
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/web/requestid/RequestIdFilterTest.java121
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/plugins/StaticResourcesServletTest.java312
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/startup/RegisterServletFiltersTest.java54
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/user/UserSessionFilterTest.java251
-rw-r--r--server/sonar-server/src/test/resources/static/foo.txt0
52 files changed, 6 insertions, 6031 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java b/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java
deleted file mode 100644
index f323f975b49..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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.app;
-
-import com.google.common.base.Throwables;
-import java.io.File;
-import java.util.concurrent.CountDownLatch;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.core.StandardContext;
-import org.apache.catalina.startup.Tomcat;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.process.Props;
-
-import static org.sonar.core.util.FileUtils.deleteQuietly;
-import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;
-
-class EmbeddedTomcat {
-
- private final Props props;
- private Tomcat tomcat = null;
- private volatile StandardContext webappContext;
- private final CountDownLatch stopLatch = new CountDownLatch(1);
-
- EmbeddedTomcat(Props props) {
- this.props = props;
- }
-
- void start() {
- // '%2F' (slash /) and '%5C' (backslash \) are permitted as path delimiters in URLs
- System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
-
- System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");
- // prevent Tomcat from shutting down our logging when stopping
- System.setProperty("logbackDisableServletContainerInitializer", "true");
-
- tomcat = new Tomcat();
- // Initialize directories
- String basedir = tomcatBasedir().getAbsolutePath();
- tomcat.setBaseDir(basedir);
- tomcat.getHost().setAppBase(basedir);
- tomcat.getHost().setAutoDeploy(false);
- tomcat.getHost().setCreateDirs(false);
- tomcat.getHost().setDeployOnStartup(true);
- new TomcatAccessLog().configure(tomcat, props);
- TomcatConnectors.configure(tomcat, props);
- webappContext = new TomcatContexts().configure(tomcat, props);
- try {
- tomcat.start();
- new TomcatStartupLogs(Loggers.get(getClass())).log(tomcat);
- } catch (LifecycleException e) {
- Loggers.get(EmbeddedTomcat.class).error("Fail to start web server", e);
- Throwables.propagate(e);
- }
- }
-
- Status getStatus() {
- if (webappContext == null) {
- return Status.DOWN;
- }
- switch (webappContext.getState()) {
- case NEW:
- case INITIALIZING:
- case INITIALIZED:
- case STARTING_PREP:
- case STARTING:
- return Status.DOWN;
- case STARTED:
- return Status.UP;
- default:
- // problem, stopped or failed
- return Status.FAILED;
- }
- }
-
- public enum Status {
- DOWN, UP, FAILED
- }
-
- private File tomcatBasedir() {
- return new File(props.value(PATH_TEMP.getKey()), "tc");
- }
-
- void terminate() {
- try {
- if (tomcat.getServer().getState().isAvailable()) {
- try {
- tomcat.stop();
- tomcat.destroy();
- } catch (Exception e) {
- Loggers.get(EmbeddedTomcat.class).warn("Failed to stop web server", e);
- }
- }
- deleteQuietly(tomcatBasedir());
- } finally {
- stopLatch.countDown();
- }
- }
-
- void awaitTermination() {
- try {
- // calling tomcat.getServer().await() might block forever if stop fails for whatever reason
- stopLatch.await();
- } catch (InterruptedException e) {
- // quit
- }
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/NullJarScanner.java b/server/sonar-server/src/main/java/org/sonar/server/app/NullJarScanner.java
deleted file mode 100644
index ed2d54a9936..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/app/NullJarScanner.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.app;
-
-import org.apache.tomcat.JarScanFilter;
-import org.apache.tomcat.JarScanType;
-import org.apache.tomcat.JarScanner;
-import org.apache.tomcat.JarScannerCallback;
-
-import javax.servlet.ServletContext;
-
-/**
- * Disable taglib and web-fragment.xml scanning of Tomcat. Should speed up startup.
- */
-
-class NullJarScanner implements JarScanner {
-
- @Override
- public void scan(JarScanType jarScanType, ServletContext servletContext, JarScannerCallback jarScannerCallback) {
- // doing nothing is fast!
- }
-
- @Override
- public JarScanFilter getJarScanFilter() {
- return null;
- }
-
- @Override
- public void setJarScanFilter(JarScanFilter jarScanFilter) {
- // no need to filter
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/ProgrammaticLogbackValve.java b/server/sonar-server/src/main/java/org/sonar/server/app/ProgrammaticLogbackValve.java
deleted file mode 100644
index f0d44b2da04..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/app/ProgrammaticLogbackValve.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.app;
-
-import ch.qos.logback.access.tomcat.LogbackValve;
-import ch.qos.logback.core.util.ExecutorServiceUtil;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleState;
-import org.apache.commons.lang.reflect.FieldUtils;
-
-/**
- * Implementation of {@link ch.qos.logback.access.tomcat.LogbackValve} that does not
- * rely on the required file logback-access.xml. It allows to be configured
- * programmatically.
- */
-public class ProgrammaticLogbackValve extends LogbackValve {
-
- @Override
- public synchronized void startInternal() throws LifecycleException {
- try {
- // direct coupling with LogbackValve implementation
- FieldUtils.writeField(this, "scheduledExecutorService", ExecutorServiceUtil.newScheduledExecutorService(), true);
- FieldUtils.writeField(this, "started", true, true);
- setState(LifecycleState.STARTING);
- } catch (IllegalAccessException e) {
- throw new IllegalStateException(e);
- }
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/TomcatAccessLog.java b/server/sonar-server/src/main/java/org/sonar/server/app/TomcatAccessLog.java
deleted file mode 100644
index 1abf4a9b28d..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/app/TomcatAccessLog.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.app;
-
-import ch.qos.logback.access.PatternLayoutEncoder;
-import ch.qos.logback.core.FileAppender;
-import org.apache.catalina.LifecycleEvent;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.startup.Tomcat;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.process.logging.LogbackHelper;
-import org.sonar.process.Props;
-
-class TomcatAccessLog {
-
- private static final String PROPERTY_ENABLE = "sonar.web.accessLogs.enable";
- private static final String PROPERTY_PATTERN = "sonar.web.accessLogs.pattern";
- private static final String DEFAULT_SQ_ACCESS_LOG_PATTERN = "%h %l %u [%t] \"%r\" %s %b \"%i{Referer}\" \"%i{User-Agent}\" \"%reqAttribute{ID}\"";
-
- void configure(Tomcat tomcat, Props props) {
- tomcat.setSilent(true);
- tomcat.getService().addLifecycleListener(new LifecycleLogger(Loggers.get(TomcatAccessLog.class)));
- configureLogbackAccess(tomcat, props);
- }
-
- private static void configureLogbackAccess(Tomcat tomcat, Props props) {
- if (props.valueAsBoolean(PROPERTY_ENABLE, true)) {
- ProgrammaticLogbackValve valve = new ProgrammaticLogbackValve();
- LogbackHelper helper = new LogbackHelper();
- LogbackHelper.RollingPolicy policy = helper.createRollingPolicy(valve, props, "access");
- FileAppender appender = policy.createAppender("ACCESS_LOG");
- PatternLayoutEncoder fileEncoder = new PatternLayoutEncoder();
- fileEncoder.setContext(valve);
- fileEncoder.setPattern(props.value(PROPERTY_PATTERN, DEFAULT_SQ_ACCESS_LOG_PATTERN));
- fileEncoder.start();
- appender.setEncoder(fileEncoder);
- appender.start();
- valve.addAppender(appender);
- tomcat.getHost().getPipeline().addValve(valve);
- }
- }
-
- static class LifecycleLogger implements LifecycleListener {
- private Logger logger;
-
- LifecycleLogger(Logger logger) {
- this.logger = logger;
- }
-
- @Override
- public void lifecycleEvent(LifecycleEvent event) {
- if ("after_start".equals(event.getType())) {
- logger.debug("Tomcat is started");
-
- } else if ("after_destroy".equals(event.getType())) {
- logger.debug("Tomcat is stopped");
- }
- }
- }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/TomcatConnectors.java b/server/sonar-server/src/main/java/org/sonar/server/app/TomcatConnectors.java
deleted file mode 100644
index e63c28cd312..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/app/TomcatConnectors.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.app;
-
-import javax.annotation.Nullable;
-import org.apache.catalina.connector.Connector;
-import org.apache.catalina.startup.Tomcat;
-import org.sonar.process.Props;
-
-import static java.lang.String.format;
-
-/**
- * Configuration of Tomcat connectors
- */
-class TomcatConnectors {
-
- static final String HTTP_PROTOCOL = "HTTP/1.1";
- static final int MAX_HTTP_HEADER_SIZE_BYTES = 48 * 1024;
- private static final int MAX_POST_SIZE = -1;
-
- private TomcatConnectors() {
- // only static stuff
- }
-
- static void configure(Tomcat tomcat, Props props) {
- Connector httpConnector = newHttpConnector(props);
- tomcat.getService().addConnector(httpConnector);
- }
-
- private static Connector newHttpConnector(Props props) {
- // Not named "sonar.web.http.port" to keep backward-compatibility
- int port = props.valueAsInt("sonar.web.port", 9000);
- if (port < 0) {
- throw new IllegalStateException(format("HTTP port '%s' is invalid", port));
- }
-
- Connector connector = new Connector(HTTP_PROTOCOL);
- connector.setURIEncoding("UTF-8");
- connector.setProperty("address", props.value("sonar.web.host", "0.0.0.0"));
- connector.setProperty("socket.soReuseAddress", "true");
- // see https://tomcat.apache.org/tomcat-8.5-doc/config/http.html
- connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}");
- configurePool(props, connector);
- configureCompression(connector);
- configureMaxHttpHeaderSize(connector);
- connector.setPort(port);
- connector.setMaxPostSize(MAX_POST_SIZE);
- return connector;
- }
-
- /**
- * HTTP header must be at least 48kb to accommodate the authentication token used for
- * negotiate protocol of windows authentication.
- */
- private static void configureMaxHttpHeaderSize(Connector connector) {
- setConnectorAttribute(connector, "maxHttpHeaderSize", MAX_HTTP_HEADER_SIZE_BYTES);
- }
-
- private static void configurePool(Props props, Connector connector) {
- connector.setProperty("acceptorThreadCount", String.valueOf(2));
- connector.setProperty("minSpareThreads", String.valueOf(props.valueAsInt("sonar.web.http.minThreads", 5)));
- connector.setProperty("maxThreads", String.valueOf(props.valueAsInt("sonar.web.http.maxThreads", 50)));
- connector.setProperty("acceptCount", String.valueOf(props.valueAsInt("sonar.web.http.acceptCount", 25)));
- }
-
- private static void configureCompression(Connector connector) {
- connector.setProperty("compression", "on");
- connector.setProperty("compressionMinSize", "1024");
- connector.setProperty("compressableMimeType", "text/html,text/xml,text/plain,text/css,application/json,application/javascript");
- }
-
- private static void setConnectorAttribute(Connector c, String key, @Nullable Object value) {
- if (value != null) {
- c.setAttribute(key, value);
- }
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/TomcatContexts.java b/server/sonar-server/src/main/java/org/sonar/server/app/TomcatContexts.java
deleted file mode 100644
index 81cf3a59b5d..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/app/TomcatContexts.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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.app;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.io.File;
-import java.io.IOException;
-import java.util.Map;
-import org.apache.catalina.core.StandardContext;
-import org.apache.catalina.startup.Tomcat;
-import org.apache.commons.io.FileUtils;
-import org.sonar.api.utils.MessageException;
-import org.sonar.process.Props;
-
-import static java.lang.String.format;
-import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
-import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
-
-/**
- * Configures Tomcat contexts:
- * <ul>
- * <li>/deploy delivers the plugins required by analyzers. It maps directory ${sonar.path.data}/web/deploy.</li>
- * <li>/ is the regular webapp</li>
- * </ul>
- */
-public class TomcatContexts {
-
- private static final String PROPERTY_CONTEXT = "sonar.web.context";
- private static final String WEB_DEPLOY_PATH_RELATIVE_TO_DATA_DIR = "web/deploy";
-
- private final Fs fs;
-
- public TomcatContexts() {
- this.fs = new Fs();
- }
-
- @VisibleForTesting
- TomcatContexts(Fs fs) {
- this.fs = fs;
- }
-
- public StandardContext configure(Tomcat tomcat, Props props) {
- addStaticDir(tomcat, getContextPath(props) + "/deploy", new File(props.nonNullValueAsFile(PATH_DATA.getKey()), WEB_DEPLOY_PATH_RELATIVE_TO_DATA_DIR));
-
- StandardContext webapp = addContext(tomcat, getContextPath(props), webappDir(props));
- for (Map.Entry<Object, Object> entry : props.rawProperties().entrySet()) {
- String key = entry.getKey().toString();
- webapp.addParameter(key, entry.getValue().toString());
- }
- return webapp;
- }
-
- static String getContextPath(Props props) {
- String context = props.value(PROPERTY_CONTEXT, "");
- if ("/".equals(context)) {
- context = "";
- } else if (!"".equals(context) && context != null && !context.startsWith("/")) {
- throw MessageException.of(format("Value of '%s' must start with a forward slash: '%s'", PROPERTY_CONTEXT, context));
- }
- return context;
- }
-
- @VisibleForTesting
- StandardContext addStaticDir(Tomcat tomcat, String contextPath, File dir) {
- try {
- fs.createOrCleanupDir(dir);
- } catch (IOException e) {
- throw new IllegalStateException(format("Fail to create or clean-up directory %s", dir.getAbsolutePath()), e);
- }
-
- return addContext(tomcat, contextPath, dir);
- }
-
- private static StandardContext addContext(Tomcat tomcat, String contextPath, File dir) {
- try {
- StandardContext context = (StandardContext) tomcat.addWebapp(contextPath, dir.getAbsolutePath());
- context.setClearReferencesHttpClientKeepAliveThread(false);
- context.setClearReferencesStopThreads(false);
- context.setClearReferencesStopTimerThreads(false);
- context.setClearReferencesStopTimerThreads(false);
- context.setAntiResourceLocking(false);
- context.setReloadable(false);
- context.setUseHttpOnly(true);
- context.setTldValidation(false);
- context.setXmlValidation(false);
- context.setXmlNamespaceAware(false);
- context.setUseNaming(false);
- context.setDelegate(true);
- context.setJarScanner(new NullJarScanner());
- context.setAllowCasualMultipartParsing(true);
- context.setCookies(false);
- // disable JSP and WebSocket support
- context.setContainerSciFilter("org.apache.tomcat.websocket.server.WsSci|org.apache.jasper.servlet.JasperInitializer");
- return context;
- } catch (Exception e) {
- throw new IllegalStateException("Fail to configure webapp from " + dir, e);
- }
- }
-
- private static File webappDir(Props props) {
- return new File(props.value(PATH_HOME.getKey()), "web");
- }
-
- static class Fs {
- void createOrCleanupDir(File dir) throws IOException {
- FileUtils.forceMkdir(dir);
- org.sonar.core.util.FileUtils.cleanDirectory(dir);
- }
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/TomcatStartupLogs.java b/server/sonar-server/src/main/java/org/sonar/server/app/TomcatStartupLogs.java
deleted file mode 100644
index e9eb5307e90..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/app/TomcatStartupLogs.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.app;
-
-import org.apache.catalina.connector.Connector;
-import org.apache.catalina.startup.Tomcat;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.utils.log.Logger;
-
-class TomcatStartupLogs {
-
- private final Logger log;
-
- TomcatStartupLogs(Logger log) {
- this.log = log;
- }
-
- void log(Tomcat tomcat) {
- Connector[] connectors = tomcat.getService().findConnectors();
- for (Connector connector : connectors) {
- if (StringUtils.equalsIgnoreCase(connector.getScheme(), "http")) {
- logHttp(connector);
- } else {
- throw new IllegalArgumentException("Unsupported connector: " + connector);
- }
- }
- }
-
- private void logHttp(Connector connector) {
- log.info(String.format("HTTP connector enabled on port %d", connector.getPort()));
- }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java b/server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java
deleted file mode 100644
index cfb5493bdbb..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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.app;
-
-import com.google.common.collect.ImmutableMap;
-import java.io.File;
-import org.slf4j.LoggerFactory;
-import org.sonar.process.MinimumViableSystem;
-import org.sonar.process.Monitored;
-import org.sonar.process.ProcessEntryPoint;
-import org.sonar.process.ProcessId;
-import org.sonar.process.Props;
-import org.sonar.process.sharedmemoryfile.DefaultProcessCommands;
-
-public class WebServer implements Monitored {
- public static final String PROPERTY_SHARED_PATH = "process.sharedDir";
-
- private final File sharedDir;
- private final EmbeddedTomcat tomcat;
-
- WebServer(Props props) {
- new MinimumViableSystem()
- .checkWritableTempDir()
- .checkRequiredJavaOptions(ImmutableMap.of("file.encoding", "UTF-8"));
- this.sharedDir = getSharedDir(props);
- this.tomcat = new EmbeddedTomcat(props);
- }
-
- private static File getSharedDir(Props props) {
- return props.nonNullValueAsFile(PROPERTY_SHARED_PATH);
- }
-
- @Override
- public void start() {
- tomcat.start();
- }
-
- @Override
- public Status getStatus() {
- switch (tomcat.getStatus()) {
- case DOWN:
- return Status.DOWN;
- case UP:
- return isOperational() ? Status.OPERATIONAL : Status.UP;
- case FAILED:
- default:
- return Status.FAILED;
- }
- }
-
- private boolean isOperational() {
- try (DefaultProcessCommands processCommands = DefaultProcessCommands.secondary(sharedDir, ProcessId.WEB_SERVER.getIpcIndex())) {
- return processCommands.isOperational();
- }
- }
-
- @Override
- public void stop() {
- // hard stop is as graceful as stop for the WebServer
- hardStop();
- LoggerFactory.getLogger(WebServer.class).info("WebServer stopped");
- }
-
- @Override
- public void hardStop() {
- tomcat.terminate();
- }
-
- @Override
- public void awaitStop() {
- tomcat.awaitTermination();
- }
-
- /**
- * Can't be started as is. Needs to be bootstrapped by sonar-application
- */
- public static void main(String[] args) {
- ProcessEntryPoint entryPoint = ProcessEntryPoint.createForArguments(args);
- Props props = entryPoint.getProps();
- new WebServerProcessLogging().configure(props);
- WebServer server = new WebServer(props);
- entryPoint.launch(server);
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/app/package-info.java
deleted file mode 100644
index 358bed4fd65..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/app/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.app;
-
-import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/server/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
index 121d08f774a..22f3e451a97 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
@@ -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;
- }
- }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel.java
deleted file mode 100644
index 68faf71cfda..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * 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.platformlevel;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Optional;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.core.platform.Module;
-import org.sonar.server.platform.WebServer;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.Objects.requireNonNull;
-
-public abstract class PlatformLevel {
- private final String name;
- @Nullable
- private final PlatformLevel parent;
- private final ComponentContainer container;
- private AddIfStartupLeader addIfStartupLeader;
- private AddIfCluster addIfCluster;
- private AddIfStandalone addIfStandalone;
-
- public PlatformLevel(String name) {
- this.name = name;
- this.parent = null;
- this.container = createContainer(null);
- }
-
- public PlatformLevel(String name, @Nonnull PlatformLevel parent) {
- this.name = checkNotNull(name);
- this.parent = checkNotNull(parent);
- this.container = createContainer(parent.container);
- }
-
- public ComponentContainer getContainer() {
- return container;
- }
-
- public String getName() {
- return name;
- }
-
- /**
- * Intended to be override by subclasses if needed
- */
- protected ComponentContainer createContainer(@Nullable ComponentContainer parent) {
- if (parent == null) {
- return new ComponentContainer();
- }
- return parent.createChild();
- }
-
- public PlatformLevel configure() {
- configureLevel();
-
- List<Module> modules = container.getComponentsByType(Module.class);
- for (Module module : modules) {
- module.configure(container);
- }
-
- return this;
- }
-
- protected abstract void configureLevel();
-
- /**
- * Intended to be override by subclasses if needed
- */
- public PlatformLevel start() {
- container.startComponents();
-
- return this;
- }
-
- /**
- * Intended to be override by subclasses if needed
- */
- public PlatformLevel stop() {
- container.stopComponents();
-
- return this;
- }
-
- /**
- * Intended to be override by subclasses if needed
- */
- public PlatformLevel destroy() {
- if (parent != null) {
- parent.container.removeChild(container);
- }
- return this;
- }
-
- protected <T> T get(Class<T> tClass) {
- return requireNonNull(container.getComponentByType(tClass));
- }
-
- protected <T> List<T> getAll(Class<T> tClass) {
- return container.getComponentsByType(tClass);
- }
-
- protected <T> Optional<T> getOptional(Class<T> tClass) {
- return Optional.ofNullable(container.getComponentByType(tClass));
- }
-
- protected void add(Object... objects) {
- for (Object object : objects) {
- if (object != null) {
- container.addComponent(object, true);
- }
- }
- }
-
- /**
- * Add a component to container only if the web server is startup leader.
- *
- * @throws IllegalStateException if called from PlatformLevel1, when cluster settings are not loaded
- */
- AddIfStartupLeader addIfStartupLeader(Object... objects) {
- if (addIfStartupLeader == null) {
- this.addIfStartupLeader = new AddIfStartupLeader(getWebServer().isStartupLeader());
- }
- addIfStartupLeader.ifAdd(objects);
- return addIfStartupLeader;
- }
-
- /**
- * Add a component to container only if clustering is enabled.
- *
- * @throws IllegalStateException if called from PlatformLevel1, when cluster settings are not loaded
- */
- AddIfCluster addIfCluster(Object... objects) {
- if (addIfCluster == null) {
- addIfCluster = new AddIfCluster(!getWebServer().isStandalone());
- }
- addIfCluster.ifAdd(objects);
- return addIfCluster;
- }
-
- /**
- * Add a component to container only if this is a standalone instance, without clustering.
- *
- * @throws IllegalStateException if called from PlatformLevel1, when cluster settings are not loaded
- */
- AddIfStandalone addIfStandalone(Object... objects) {
- if (addIfStandalone == null) {
- addIfStandalone = new AddIfStandalone(getWebServer().isStandalone());
- }
- addIfStandalone.ifAdd(objects);
- return addIfStandalone;
- }
-
- private WebServer getWebServer() {
- return getOptional(WebServer.class)
- .orElseThrow(() -> new IllegalStateException("WebServer not available in Pico yet"));
- }
-
- private abstract class AddIf {
- private final boolean condition;
-
- private AddIf(boolean condition) {
- this.condition = condition;
- }
-
- public void ifAdd(Object... objects) {
- if (condition) {
- PlatformLevel.this.add(objects);
- }
- }
-
- public void otherwiseAdd(Object... objects) {
- if (!condition) {
- PlatformLevel.this.add(objects);
- }
- }
- }
-
- public final class AddIfStartupLeader extends AddIf {
- private AddIfStartupLeader(boolean condition) {
- super(condition);
- }
- }
-
- public final class AddIfCluster extends AddIf {
- private AddIfCluster(boolean condition) {
- super(condition);
- }
- }
-
- public final class AddIfStandalone extends AddIf {
- private AddIfStandalone(boolean condition) {
- super(condition);
- }
- }
-
- protected void addAll(Collection<?> objects) {
- add(objects.toArray(new Object[objects.size()]));
- }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java
deleted file mode 100644
index 184fd922bc3..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * 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.platformlevel;
-
-import java.time.Clock;
-import java.util.Properties;
-import javax.annotation.Nullable;
-import org.sonar.api.SonarEdition;
-import org.sonar.api.SonarQubeSide;
-import org.sonar.api.SonarQubeVersion;
-import org.sonar.api.internal.MetadataLoader;
-import org.sonar.api.internal.SonarRuntimeImpl;
-import org.sonar.api.utils.System2;
-import org.sonar.api.utils.Version;
-import org.sonar.server.util.TempFolderCleaner;
-import org.sonar.core.config.CorePropertyDefinitions;
-import org.sonar.core.extension.CoreExtensionRepositoryImpl;
-import org.sonar.core.extension.CoreExtensionsLoader;
-import org.sonar.core.util.UuidFactoryImpl;
-import org.sonar.db.DBSessionsImpl;
-import org.sonar.db.DaoModule;
-import org.sonar.db.DbClient;
-import org.sonar.db.DefaultDatabase;
-import org.sonar.db.MyBatis;
-import org.sonar.db.purge.PurgeProfiler;
-import org.sonar.process.NetworkUtilsImpl;
-import org.sonar.process.logging.LogbackHelper;
-import org.sonar.server.app.ProcessCommandWrapperImpl;
-import org.sonar.server.app.RestartFlagHolderImpl;
-import org.sonar.server.app.WebServerProcessLogging;
-import org.sonar.server.config.ConfigurationProvider;
-import org.sonar.server.es.EsModule;
-import org.sonar.server.issue.index.IssueIndex;
-import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
-import org.sonar.server.platform.LogServerVersion;
-import org.sonar.server.platform.Platform;
-import org.sonar.server.platform.ServerFileSystemImpl;
-import org.sonar.server.platform.TempFolderProvider;
-import org.sonar.server.platform.UrlSettings;
-import org.sonar.server.platform.WebCoreExtensionsInstaller;
-import org.sonar.server.platform.WebServerImpl;
-import org.sonar.server.platform.db.EmbeddedDatabaseFactory;
-import org.sonar.server.rule.index.RuleIndex;
-import org.sonar.server.setting.ThreadLocalSettings;
-import org.sonar.server.user.SystemPasscodeImpl;
-import org.sonar.server.user.ThreadLocalUserSession;
-import org.sonar.server.util.GlobalLockManager;
-import org.sonar.server.util.OkHttpClientProvider;
-
-import static org.sonar.core.extension.CoreExtensionsInstaller.noAdditionalSideFilter;
-import static org.sonar.core.extension.PlatformLevelPredicates.hasPlatformLevel;
-
-public class PlatformLevel1 extends PlatformLevel {
- private final Platform platform;
- private final Properties properties;
- @Nullable
- private final Object[] extraRootComponents;
-
- public PlatformLevel1(Platform platform, Properties properties, Object... extraRootComponents) {
- super("level1");
- this.platform = platform;
- this.properties = properties;
- this.extraRootComponents = extraRootComponents;
- }
-
- @Override
- public void configureLevel() {
- add(platform, properties);
- addExtraRootComponents();
- Version apiVersion = MetadataLoader.loadVersion(System2.INSTANCE);
- SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE);
-
- add(
- new SonarQubeVersion(apiVersion),
- SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SERVER, edition),
- ThreadLocalSettings.class,
- new ConfigurationProvider(),
- LogServerVersion.class,
- ProcessCommandWrapperImpl.class,
- RestartFlagHolderImpl.class,
- UuidFactoryImpl.INSTANCE,
- NetworkUtilsImpl.INSTANCE,
- UrlSettings.class,
- EmbeddedDatabaseFactory.class,
- LogbackHelper.class,
- WebServerProcessLogging.class,
- DefaultDatabase.class,
- MyBatis.class,
- PurgeProfiler.class,
- ServerFileSystemImpl.class,
- TempFolderCleaner.class,
- new TempFolderProvider(),
- System2.INSTANCE,
- Clock.systemDefaultZone(),
-
- // user session
- ThreadLocalUserSession.class,
- SystemPasscodeImpl.class,
-
- // DB
- DBSessionsImpl.class,
- DbClient.class,
- DaoModule.class,
-
- // Elasticsearch
- WebAuthorizationTypeSupport.class,
- EsModule.class,
-
- // rules/qprofiles
- RuleIndex.class,
-
- // issues
- IssueIndex.class,
-
- GlobalLockManager.class,
-
- new OkHttpClientProvider(),
-
- CoreExtensionRepositoryImpl.class,
- CoreExtensionsLoader.class,
- WebCoreExtensionsInstaller.class);
- addAll(CorePropertyDefinitions.all());
-
- // cluster
- add(WebServerImpl.class);
- }
-
- private void addExtraRootComponents() {
- if (this.extraRootComponents != null) {
- for (Object extraRootComponent : this.extraRootComponents) {
- add(extraRootComponent);
- }
- }
- }
-
- @Override
- public PlatformLevel start() {
- get(CoreExtensionsLoader.class)
- .load();
- get(WebCoreExtensionsInstaller.class)
- .install(getContainer(), hasPlatformLevel(1), noAdditionalSideFilter());
-
- return super.start();
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java
deleted file mode 100644
index 26da9589616..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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.platformlevel;
-
-import org.sonar.api.utils.Durations;
-import org.sonar.core.extension.CoreExtensionsInstaller;
-import org.sonar.core.i18n.RuleI18nManager;
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.core.platform.PluginClassloaderFactory;
-import org.sonar.core.platform.PluginLoader;
-import org.sonar.server.es.MigrationEsClientImpl;
-import org.sonar.server.l18n.ServerI18n;
-import org.sonar.server.platform.DatabaseServerCompatibility;
-import org.sonar.server.platform.DefaultServerUpgradeStatus;
-import org.sonar.server.platform.OfficialDistribution;
-import org.sonar.server.platform.StartupMetadataProvider;
-import org.sonar.server.platform.WebCoreExtensionsInstaller;
-import org.sonar.server.platform.db.CheckDatabaseCharsetAtStartup;
-import org.sonar.server.platform.db.migration.DatabaseMigrationExecutorServiceImpl;
-import org.sonar.server.platform.db.migration.DatabaseMigrationStateImpl;
-import org.sonar.server.platform.db.migration.MigrationConfigurationModule;
-import org.sonar.server.platform.db.migration.charset.DatabaseCharsetChecker;
-import org.sonar.server.platform.db.migration.history.MigrationHistoryTable;
-import org.sonar.server.platform.db.migration.history.MigrationHistoryTableImpl;
-import org.sonar.server.platform.db.migration.version.DatabaseVersion;
-import org.sonar.server.platform.web.WebPagesCache;
-import org.sonar.server.plugins.InstalledPluginReferentialFactory;
-import org.sonar.server.plugins.PluginFileSystem;
-import org.sonar.server.plugins.ServerPluginJarExploder;
-import org.sonar.server.plugins.ServerPluginRepository;
-import org.sonar.server.plugins.WebServerExtensionInstaller;
-
-import static org.sonar.core.extension.CoreExtensionsInstaller.noAdditionalSideFilter;
-import static org.sonar.core.extension.PlatformLevelPredicates.hasPlatformLevel;
-
-public class PlatformLevel2 extends PlatformLevel {
- public PlatformLevel2(PlatformLevel parent) {
- super("level2", parent);
- }
-
- @Override
- protected void configureLevel() {
- add(
- MigrationConfigurationModule.class,
- DatabaseVersion.class,
- DatabaseServerCompatibility.class,
- MigrationEsClientImpl.class,
-
- new StartupMetadataProvider(),
- DefaultServerUpgradeStatus.class,
- Durations.class,
-
- // index.html cache
- WebPagesCache.class,
-
- // plugins
- ServerPluginRepository.class,
- ServerPluginJarExploder.class,
- PluginLoader.class,
- PluginFileSystem.class,
- PluginClassloaderFactory.class,
- InstalledPluginReferentialFactory.class,
- WebServerExtensionInstaller.class,
-
- // depends on plugins
- ServerI18n.class,
- RuleI18nManager.class,
-
- OfficialDistribution.class);
-
- // Migration state must be kept at level2 to survive moving in and then out of safe mode
- // ExecutorService must be kept at level2 because stopping it when stopping safe mode level causes error making SQ fail
- add(
- MigrationHistoryTableImpl.class,
- DatabaseMigrationStateImpl.class,
- DatabaseMigrationExecutorServiceImpl.class);
-
- addIfStartupLeader(
- DatabaseCharsetChecker.class,
- CheckDatabaseCharsetAtStartup.class);
- }
-
- @Override
- public PlatformLevel start() {
- // ensuring the HistoryTable exists must be the first thing done when this level is started
- getOptional(MigrationHistoryTable.class).ifPresent(MigrationHistoryTable::start);
-
- ComponentContainer container = getContainer();
- CoreExtensionsInstaller coreExtensionsInstaller = get(WebCoreExtensionsInstaller.class);
- coreExtensionsInstaller.install(container, hasPlatformLevel(2), noAdditionalSideFilter());
-
- return super.start();
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java
deleted file mode 100644
index 2bab0b816c2..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.platformlevel;
-
-import org.sonar.api.utils.UriReader;
-import org.sonar.core.extension.CoreExtensionsInstaller;
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.core.util.DefaultHttpDownloader;
-import org.sonar.server.async.AsyncExecutionModule;
-import org.sonar.server.organization.DefaultOrganizationProviderImpl;
-import org.sonar.server.organization.OrganizationFlagsImpl;
-import org.sonar.server.platform.ServerImpl;
-import org.sonar.server.platform.StartupMetadataPersister;
-import org.sonar.server.platform.WebCoreExtensionsInstaller;
-import org.sonar.server.platform.db.migration.NoopDatabaseMigrationImpl;
-import org.sonar.server.platform.serverid.ServerIdModule;
-import org.sonar.server.setting.DatabaseSettingLoader;
-import org.sonar.server.setting.DatabaseSettingsEnabler;
-
-import static org.sonar.core.extension.CoreExtensionsInstaller.noAdditionalSideFilter;
-import static org.sonar.core.extension.PlatformLevelPredicates.hasPlatformLevel;
-
-public class PlatformLevel3 extends PlatformLevel {
- public PlatformLevel3(PlatformLevel parent) {
- super("level3", parent);
- }
-
- @Override
- protected void configureLevel() {
- addIfStartupLeader(StartupMetadataPersister.class);
- add(
- NoopDatabaseMigrationImpl.class,
- ServerIdModule.class,
- ServerImpl.class,
- DatabaseSettingLoader.class,
- DatabaseSettingsEnabler.class,
- UriReader.class,
- DefaultHttpDownloader.class,
- DefaultOrganizationProviderImpl.class,
- OrganizationFlagsImpl.class,
- AsyncExecutionModule.class);
- }
-
- @Override
- public PlatformLevel start() {
- ComponentContainer container = getContainer();
- CoreExtensionsInstaller coreExtensionsInstaller = get(WebCoreExtensionsInstaller.class);
- coreExtensionsInstaller.install(container, hasPlatformLevel(3), noAdditionalSideFilter());
-
- return super.start();
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
deleted file mode 100644
index 8e850fa4449..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * 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.platformlevel;
-
-import java.util.List;
-import org.sonar.api.profiles.AnnotationProfileParser;
-import org.sonar.api.profiles.XMLProfileParser;
-import org.sonar.api.profiles.XMLProfileSerializer;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.ResourceTypes;
-import org.sonar.api.rules.AnnotationRuleParser;
-import org.sonar.api.rules.XMLRuleParser;
-import org.sonar.api.server.rule.RulesDefinitionXmlLoader;
-import org.sonar.ce.task.projectanalysis.notification.ReportAnalysisFailureNotificationModule;
-import org.sonar.core.component.DefaultResourceTypes;
-import org.sonar.core.extension.CoreExtensionsInstaller;
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.core.platform.PlatformEditionProvider;
-import org.sonar.server.authentication.AuthenticationModule;
-import org.sonar.server.authentication.LogOAuthWarning;
-import org.sonar.server.badge.ws.ProjectBadgesWsModule;
-import org.sonar.server.batch.BatchWsModule;
-import org.sonar.server.branch.BranchFeatureProxyImpl;
-import org.sonar.server.branch.pr.ws.PullRequestWsModule;
-import org.sonar.server.branch.ws.BranchWsModule;
-import org.sonar.server.ce.CeModule;
-import org.sonar.server.ce.ws.CeWsModule;
-import org.sonar.server.component.ComponentCleanerService;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.component.ComponentService;
-import org.sonar.server.component.ComponentUpdater;
-import org.sonar.server.component.index.ComponentIndex;
-import org.sonar.server.component.index.ComponentIndexDefinition;
-import org.sonar.server.component.index.ComponentIndexer;
-import org.sonar.server.component.ws.ComponentViewerJsonWriter;
-import org.sonar.server.component.ws.ComponentsWsModule;
-import org.sonar.server.debt.DebtModelPluginRepository;
-import org.sonar.server.debt.DebtModelXMLExporter;
-import org.sonar.server.debt.DebtRulesXMLImporter;
-import org.sonar.server.duplication.ws.DuplicationsParser;
-import org.sonar.server.duplication.ws.DuplicationsWs;
-import org.sonar.server.duplication.ws.ShowResponseBuilder;
-import org.sonar.server.email.ws.EmailsWsModule;
-import org.sonar.server.es.IndexCreator;
-import org.sonar.server.es.IndexDefinitions;
-import org.sonar.server.es.ProjectIndexersImpl;
-import org.sonar.server.es.RecoveryIndexer;
-import org.sonar.server.es.metadata.EsDbCompatibilityImpl;
-import org.sonar.server.es.metadata.MetadataIndexDefinition;
-import org.sonar.server.es.metadata.MetadataIndexImpl;
-import org.sonar.server.extension.CoreExtensionBootstraper;
-import org.sonar.server.extension.CoreExtensionStopper;
-import org.sonar.server.favorite.FavoriteModule;
-import org.sonar.server.health.NodeHealthModule;
-import org.sonar.server.issue.AddTagsAction;
-import org.sonar.server.issue.AssignAction;
-import org.sonar.server.issue.CommentAction;
-import org.sonar.server.issue.IssueChangePostProcessorImpl;
-import org.sonar.server.issue.RemoveTagsAction;
-import org.sonar.server.issue.SetSeverityAction;
-import org.sonar.server.issue.SetTypeAction;
-import org.sonar.server.issue.TransitionAction;
-import org.sonar.server.issue.index.IssueIndexDefinition;
-import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.issue.index.IssueIteratorFactory;
-import org.sonar.server.issue.notification.IssuesChangesNotificationModule;
-import org.sonar.server.issue.notification.MyNewIssuesEmailTemplate;
-import org.sonar.server.issue.notification.MyNewIssuesNotificationHandler;
-import org.sonar.server.issue.notification.NewIssuesEmailTemplate;
-import org.sonar.server.issue.notification.NewIssuesNotificationHandler;
-import org.sonar.server.issue.ws.IssueWsModule;
-import org.sonar.server.language.ws.LanguageWs;
-import org.sonar.server.log.ServerLogging;
-import org.sonar.server.measure.custom.ws.CustomMeasuresWsModule;
-import org.sonar.server.measure.index.ProjectsEsModule;
-import org.sonar.server.measure.live.LiveMeasureModule;
-import org.sonar.server.measure.ws.MeasuresWsModule;
-import org.sonar.server.measure.ws.TimeMachineWs;
-import org.sonar.server.metric.CoreCustomMetrics;
-import org.sonar.server.metric.DefaultMetricFinder;
-import org.sonar.server.metric.ws.MetricsWsModule;
-import org.sonar.server.notification.NotificationModule;
-import org.sonar.server.notification.ws.NotificationWsModule;
-import org.sonar.server.organization.BillingValidationsProxyImpl;
-import org.sonar.server.organization.OrganizationUpdaterImpl;
-import org.sonar.server.organization.OrganizationValidationImpl;
-import org.sonar.server.organization.ws.OrganizationsWsModule;
-import org.sonar.server.permission.GroupPermissionChanger;
-import org.sonar.server.permission.PermissionTemplateService;
-import org.sonar.server.permission.PermissionUpdater;
-import org.sonar.server.permission.UserPermissionChanger;
-import org.sonar.server.permission.index.PermissionIndexer;
-import org.sonar.server.permission.ws.PermissionsWsModule;
-import org.sonar.server.permission.ws.template.DefaultTemplatesResolverImpl;
-import org.sonar.server.platform.BackendCleanup;
-import org.sonar.server.platform.ClusterVerification;
-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;
-import org.sonar.server.platform.ws.HealthActionModule;
-import org.sonar.server.platform.ws.L10nWs;
-import org.sonar.server.platform.ws.LogsAction;
-import org.sonar.server.platform.ws.MigrateDbAction;
-import org.sonar.server.platform.ws.PingAction;
-import org.sonar.server.platform.ws.RestartAction;
-import org.sonar.server.platform.ws.ServerWs;
-import org.sonar.server.platform.ws.StatusAction;
-import org.sonar.server.platform.ws.SystemWs;
-import org.sonar.server.platform.ws.UpgradesAction;
-import org.sonar.server.plugins.PluginDownloader;
-import org.sonar.server.plugins.PluginUninstaller;
-import org.sonar.server.plugins.ServerExtensionInstaller;
-import org.sonar.server.plugins.ws.AvailableAction;
-import org.sonar.server.plugins.ws.CancelAllAction;
-import org.sonar.server.plugins.ws.DownloadAction;
-import org.sonar.server.plugins.ws.InstallAction;
-import org.sonar.server.plugins.ws.InstalledAction;
-import org.sonar.server.plugins.ws.PendingAction;
-import org.sonar.server.plugins.ws.PluginUpdateAggregator;
-import org.sonar.server.plugins.ws.PluginsWs;
-import org.sonar.server.plugins.ws.UninstallAction;
-import org.sonar.server.plugins.ws.UpdatesAction;
-import org.sonar.server.project.ws.ProjectsWsModule;
-import org.sonar.server.projectanalysis.ProjectAnalysisModule;
-import org.sonar.server.projectlink.ws.ProjectLinksModule;
-import org.sonar.server.projecttag.ws.ProjectTagsWsModule;
-import org.sonar.server.property.InternalPropertiesImpl;
-import org.sonar.server.property.ws.PropertiesWs;
-import org.sonar.server.qualitygate.QualityGateModule;
-import org.sonar.server.qualitygate.notification.QGChangeNotificationHandler;
-import org.sonar.server.qualityprofile.BuiltInQPChangeNotificationHandler;
-import org.sonar.server.qualityprofile.BuiltInQPChangeNotificationTemplate;
-import org.sonar.server.qualityprofile.BuiltInQProfileDefinitionsBridge;
-import org.sonar.server.qualityprofile.BuiltInQProfileRepositoryImpl;
-import org.sonar.server.qualityprofile.QProfileBackuperImpl;
-import org.sonar.server.qualityprofile.QProfileComparison;
-import org.sonar.server.qualityprofile.QProfileCopier;
-import org.sonar.server.qualityprofile.QProfileExporters;
-import org.sonar.server.qualityprofile.QProfileFactoryImpl;
-import org.sonar.server.qualityprofile.QProfileResetImpl;
-import org.sonar.server.qualityprofile.QProfileRulesImpl;
-import org.sonar.server.qualityprofile.QProfileTreeImpl;
-import org.sonar.server.qualityprofile.RuleActivator;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
-import org.sonar.server.qualityprofile.ws.QProfilesWsModule;
-import org.sonar.server.root.ws.RootWsModule;
-import org.sonar.server.rule.CommonRuleDefinitionsImpl;
-import org.sonar.server.rule.DeprecatedRulesDefinitionLoader;
-import org.sonar.server.rule.RuleCreator;
-import org.sonar.server.rule.RuleDefinitionsLoader;
-import org.sonar.server.rule.RuleUpdater;
-import org.sonar.server.rule.WebServerRuleFinderImpl;
-import org.sonar.server.rule.index.RuleIndexDefinition;
-import org.sonar.server.rule.index.RuleIndexer;
-import org.sonar.server.rule.ws.ActiveRuleCompleter;
-import org.sonar.server.rule.ws.RepositoriesAction;
-import org.sonar.server.rule.ws.RuleMapper;
-import org.sonar.server.rule.ws.RuleQueryFactory;
-import org.sonar.server.rule.ws.RuleWsSupport;
-import org.sonar.server.rule.ws.RulesWs;
-import org.sonar.server.rule.ws.TagsAction;
-import org.sonar.server.setting.ws.SettingsWsModule;
-import org.sonar.server.source.ws.SourceWsModule;
-import org.sonar.server.startup.LogServerId;
-import org.sonar.server.telemetry.TelemetryClient;
-import org.sonar.server.telemetry.TelemetryDaemon;
-import org.sonar.server.telemetry.TelemetryDataLoader;
-import org.sonar.server.text.MacroInterpreter;
-import org.sonar.server.ui.DeprecatedViews;
-import org.sonar.server.ui.PageDecorations;
-import org.sonar.server.ui.PageRepository;
-import org.sonar.server.ui.WebAnalyticsLoaderImpl;
-import org.sonar.server.ui.ws.NavigationWsModule;
-import org.sonar.server.updatecenter.UpdateCenterModule;
-import org.sonar.server.user.NewUserNotifier;
-import org.sonar.server.user.SecurityRealmFactory;
-import org.sonar.server.user.UserSessionFactoryImpl;
-import org.sonar.server.user.UserUpdater;
-import org.sonar.server.user.index.UserIndex;
-import org.sonar.server.user.index.UserIndexDefinition;
-import org.sonar.server.user.index.UserIndexer;
-import org.sonar.server.user.ws.UsersWsModule;
-import org.sonar.server.usergroups.DefaultGroupCreatorImpl;
-import org.sonar.server.usergroups.DefaultGroupFinder;
-import org.sonar.server.usergroups.ws.UserGroupsModule;
-import org.sonar.server.usertoken.UserTokenModule;
-import org.sonar.server.util.TypeValidationModule;
-import org.sonar.server.view.index.ViewIndex;
-import org.sonar.server.view.index.ViewIndexDefinition;
-import org.sonar.server.view.index.ViewIndexer;
-import org.sonar.server.webhook.WebhookModule;
-import org.sonar.server.webhook.ws.WebhooksWsModule;
-import org.sonar.server.ws.DeprecatedPropertiesWsFilter;
-import org.sonar.server.ws.WebServiceEngine;
-import org.sonar.server.ws.WebServiceFilter;
-import org.sonar.server.ws.WebServiceReroutingFilter;
-import org.sonar.server.ws.ws.WebServicesWsModule;
-
-import static org.sonar.core.extension.CoreExtensionsInstaller.noAdditionalSideFilter;
-import static org.sonar.core.extension.PlatformLevelPredicates.hasPlatformLevel4OrNone;
-
-public class PlatformLevel4 extends PlatformLevel {
-
- private final List<Object> level4AddedComponents;
-
- public PlatformLevel4(PlatformLevel parent, List<Object> level4AddedComponents) {
- super("level4", parent);
- this.level4AddedComponents = level4AddedComponents;
- }
-
- @Override
- protected void configureLevel() {
- addIfStartupLeader(
- IndexCreator.class,
- MetadataIndexDefinition.class,
- MetadataIndexImpl.class,
- EsDbCompatibilityImpl.class);
-
- addIfCluster(NodeHealthModule.class);
-
- add(
- ClusterVerification.class,
- LogServerId.class,
- LogOAuthWarning.class,
- PluginDownloader.class,
- PluginUninstaller.class,
- DeprecatedViews.class,
- PageRepository.class,
- ResourceTypes.class,
- DefaultResourceTypes.get(),
- SettingsChangeNotifier.class,
- PageDecorations.class,
- ServerWs.class,
- BackendCleanup.class,
- IndexDefinitions.class,
- WebPagesFilter.class,
- WebAnalyticsLoaderImpl.class,
-
- // batch
- BatchWsModule.class,
-
- // update center
- UpdateCenterModule.class,
-
- // organizations
- OrganizationValidationImpl.class,
- OrganizationUpdaterImpl.class,
- OrganizationsWsModule.class,
- BillingValidationsProxyImpl.class,
-
- // quality profile
- BuiltInQProfileDefinitionsBridge.class,
- BuiltInQProfileRepositoryImpl.class,
- ActiveRuleIndexer.class,
- XMLProfileParser.class,
- XMLProfileSerializer.class,
- AnnotationProfileParser.class,
- QProfileComparison.class,
- QProfileTreeImpl.class,
- QProfileRulesImpl.class,
- RuleActivator.class,
- QProfileExporters.class,
- QProfileFactoryImpl.class,
- QProfileCopier.class,
- QProfileBackuperImpl.class,
- QProfileResetImpl.class,
- QProfilesWsModule.class,
-
- // rule
- RuleIndexDefinition.class,
- RuleIndexer.class,
- AnnotationRuleParser.class,
- XMLRuleParser.class,
- WebServerRuleFinderImpl.class,
- DeprecatedRulesDefinitionLoader.class,
- RuleDefinitionsLoader.class,
- CommonRuleDefinitionsImpl.class,
- RulesDefinitionXmlLoader.class,
- RuleUpdater.class,
- RuleCreator.class,
- org.sonar.server.rule.ws.UpdateAction.class,
- RulesWs.class,
- RuleWsSupport.class,
- org.sonar.server.rule.ws.SearchAction.class,
- org.sonar.server.rule.ws.ShowAction.class,
- org.sonar.server.rule.ws.CreateAction.class,
- org.sonar.server.rule.ws.DeleteAction.class,
- org.sonar.server.rule.ws.ListAction.class,
- TagsAction.class,
- RuleMapper.class,
- ActiveRuleCompleter.class,
- RepositoriesAction.class,
- RuleQueryFactory.class,
- org.sonar.server.rule.ws.AppAction.class,
-
- // languages
- Languages.class,
- LanguageWs.class,
- org.sonar.server.language.ws.ListAction.class,
-
- // measure
- MetricsWsModule.class,
- MeasuresWsModule.class,
- CustomMeasuresWsModule.class,
- CoreCustomMetrics.class,
- DefaultMetricFinder.class,
- TimeMachineWs.class,
-
- QualityGateModule.class,
-
- // web services
- WebServiceEngine.class,
- WebServicesWsModule.class,
- WebServiceFilter.class,
- DeprecatedPropertiesWsFilter.class,
- WebServiceReroutingFilter.class,
-
- // localization
- L10nWs.class,
- org.sonar.server.platform.ws.IndexAction.class,
-
- // authentication
- AuthenticationModule.class,
-
- // users
- UserSessionFactoryImpl.class,
- SecurityRealmFactory.class,
- NewUserNotifier.class,
- UserIndexDefinition.class,
- UserIndexer.class,
- UserIndex.class,
- UserUpdater.class,
- UsersWsModule.class,
- UserTokenModule.class,
-
- // groups
- UserGroupsModule.class,
- DefaultGroupCreatorImpl.class,
- DefaultGroupFinder.class,
-
- // permissions
- DefaultTemplatesResolverImpl.class,
- PermissionsWsModule.class,
- PermissionTemplateService.class,
- PermissionUpdater.class,
- UserPermissionChanger.class,
- GroupPermissionChanger.class,
-
- // components
- BranchWsModule.class,
- PullRequestWsModule.class,
- ProjectsWsModule.class,
- ProjectsEsModule.class,
- ProjectTagsWsModule.class,
- ComponentsWsModule.class,
- ComponentService.class,
- ComponentUpdater.class,
- ComponentFinder.class,
- QGChangeNotificationHandler.class,
- QGChangeNotificationHandler.newMetadata(),
- ComponentCleanerService.class,
- ComponentIndexDefinition.class,
- ComponentIndex.class,
- ComponentIndexer.class,
- LiveMeasureModule.class,
- ComponentViewerJsonWriter.class,
-
- FavoriteModule.class,
-
- // views
- ViewIndexDefinition.class,
- ViewIndexer.class,
- ViewIndex.class,
-
- // issues
- IssueIndexDefinition.class,
- IssueIndexer.class,
- IssueIteratorFactory.class,
- PermissionIndexer.class,
- IssueWsModule.class,
- NewIssuesEmailTemplate.class,
- MyNewIssuesEmailTemplate.class,
- IssuesChangesNotificationModule.class,
- NewIssuesNotificationHandler.class,
- NewIssuesNotificationHandler.newMetadata(),
- MyNewIssuesNotificationHandler.class,
- MyNewIssuesNotificationHandler.newMetadata(),
-
- // issues actions
- AssignAction.class,
- SetTypeAction.class,
- SetSeverityAction.class,
- CommentAction.class,
- TransitionAction.class,
- AddTagsAction.class,
- RemoveTagsAction.class,
- IssueChangePostProcessorImpl.class,
-
- // technical debt
- DebtModelPluginRepository.class,
- DebtModelXMLExporter.class,
- DebtRulesXMLImporter.class,
-
- // source
- SourceWsModule.class,
-
- // Duplications
- DuplicationsParser.class,
- DuplicationsWs.class,
- ShowResponseBuilder.class,
- org.sonar.server.duplication.ws.ShowAction.class,
-
- // text
- MacroInterpreter.class,
-
- // Notifications
- // Those class are required in order to be able to send emails during startup
- // Without having two NotificationModule (one in StartupLevel and one in Level4)
- BuiltInQPChangeNotificationTemplate.class,
- BuiltInQPChangeNotificationHandler.class,
-
- NotificationModule.class,
- NotificationWsModule.class,
- EmailsWsModule.class,
-
- // Settings
- PersistentSettings.class,
- PropertiesWs.class,
- org.sonar.server.property.ws.IndexAction.class,
- SettingsWsModule.class,
-
- TypeValidationModule.class,
-
- // Project Links
- ProjectLinksModule.class,
-
- // Project Analyses
- ProjectAnalysisModule.class,
-
- // System
- ServerLogging.class,
- RestartAction.class,
- PingAction.class,
- UpgradesAction.class,
- StatusAction.class,
- MigrateDbAction.class,
- LogsAction.class,
- ChangeLogLevelActionModule.class,
- DbMigrationStatusAction.class,
- HealthActionModule.class,
- SystemWs.class,
-
- // Plugins WS
- PluginUpdateAggregator.class,
- InstalledAction.class,
- AvailableAction.class,
- DownloadAction.class,
- UpdatesAction.class,
- PendingAction.class,
- InstallAction.class,
- org.sonar.server.plugins.ws.UpdateAction.class,
- UninstallAction.class,
- CancelAllAction.class,
- PluginsWs.class,
-
- // Branch
- BranchFeatureProxyImpl.class,
-
- // Project badges
- ProjectBadgesWsModule.class,
-
- // Core Extensions
- CoreExtensionBootstraper.class,
- CoreExtensionStopper.class,
-
- // Compute engine (must be after Views and Developer Cockpit)
- ReportAnalysisFailureNotificationModule.class,
- CeModule.class,
- CeWsModule.class,
-
- // SonarSource editions
- PlatformEditionProvider.class,
-
- InternalPropertiesImpl.class,
-
- // UI
- NavigationWsModule.class,
-
- // root
- RootWsModule.class,
-
- // webhooks
- WebhookModule.class,
- WebhooksWsModule.class,
-
- // Http Request ID
- HttpRequestIdModule.class,
-
- RecoveryIndexer.class,
- ProjectIndexersImpl.class,
-
- // telemetry
- TelemetryDataLoader.class,
- TelemetryDaemon.class,
- TelemetryClient.class
-
- );
-
- // system info
- add(WebSystemInfoModule.class);
-
- addAll(level4AddedComponents);
- }
-
- @Override
- public PlatformLevel start() {
- ComponentContainer container = getContainer();
- CoreExtensionsInstaller coreExtensionsInstaller = get(WebCoreExtensionsInstaller.class);
- coreExtensionsInstaller.install(container, hasPlatformLevel4OrNone(), noAdditionalSideFilter());
- ServerExtensionInstaller extensionInstaller = get(ServerExtensionInstaller.class);
- extensionInstaller.installExtensions(container);
-
- super.start();
-
- return this;
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelSafeMode.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelSafeMode.java
deleted file mode 100644
index eea1137d7b4..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelSafeMode.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.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;
-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.StatusAction;
-import org.sonar.server.platform.ws.SystemWs;
-import org.sonar.server.ws.WebServiceEngine;
-import org.sonar.server.ws.WebServiceFilter;
-import org.sonar.server.ws.ws.WebServicesWsModule;
-
-public class PlatformLevelSafeMode extends PlatformLevel {
- public PlatformLevelSafeMode(PlatformLevel parent) {
- super("Safemode", parent);
- }
-
- @Override
- protected void configureLevel() {
- add(
- ServerImpl.class,
- WebPagesFilter.class,
-
- // l10n WS
- L10nWs.class,
- IndexAction.class,
-
- // Server WS
- StatusAction.class,
- MigrateDbAction.class,
- DbMigrationStatusAction.class,
- SafeModeHealthActionModule.class,
- SystemWs.class,
-
- // Listing WS
- WebServicesWsModule.class,
-
- // WS engine
- SafeModeUserSession.class,
- WebServiceEngine.class,
- WebServiceFilter.class,
-
- NoopDefaultOrganizationCache.class);
- addIfStartupLeader(
- DatabaseMigrationImpl.class,
- MigrationEngineModule.class,
- AutoDbMigration.class)
- .otherwiseAdd(NoopDatabaseMigrationImpl.class);
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java
deleted file mode 100644
index 1fb52415beb..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.platformlevel;
-
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.core.platform.EditionProvider;
-import org.sonar.core.platform.PlatformEditionProvider;
-import org.sonar.server.app.ProcessCommandWrapper;
-import org.sonar.server.ce.queue.CeQueueCleaner;
-import org.sonar.server.es.IndexerStartupTask;
-import org.sonar.server.organization.DefaultOrganizationEnforcer;
-import org.sonar.server.platform.ServerLifecycleNotifier;
-import org.sonar.server.platform.web.RegisterServletFilters;
-import org.sonar.server.qualitygate.ProjectsInWarningDaemon;
-import org.sonar.server.qualitygate.RegisterQualityGates;
-import org.sonar.server.qualityprofile.BuiltInQProfileInsertImpl;
-import org.sonar.server.qualityprofile.BuiltInQProfileLoader;
-import org.sonar.server.qualityprofile.BuiltInQProfileUpdateImpl;
-import org.sonar.server.qualityprofile.BuiltInQualityProfilesUpdateListener;
-import org.sonar.server.qualityprofile.RegisterQualityProfiles;
-import org.sonar.server.rule.RegisterRules;
-import org.sonar.server.rule.WebServerRuleFinder;
-import org.sonar.server.startup.GeneratePluginIndex;
-import org.sonar.server.startup.RegisterMetrics;
-import org.sonar.server.startup.RegisterPermissionTemplates;
-import org.sonar.server.startup.RegisterPlugins;
-import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
-import org.sonar.server.user.DoPrivileged;
-import org.sonar.server.user.ThreadLocalUserSession;
-
-public class PlatformLevelStartup extends PlatformLevel {
- public PlatformLevelStartup(PlatformLevel parent) {
- super("startup tasks", parent);
- }
-
- @Override
- protected void configureLevel() {
- add(GeneratePluginIndex.class,
- RegisterPlugins.class,
- ServerLifecycleNotifier.class,
- DefaultOrganizationEnforcer.class);
-
- addIfStartupLeader(
- IndexerStartupTask.class,
- RegisterMetrics.class,
- RegisterQualityGates.class,
- RegisterRules.class);
- add(BuiltInQProfileLoader.class);
- addIfStartupLeader(
- BuiltInQualityProfilesUpdateListener.class,
- BuiltInQProfileInsertImpl.class,
- BuiltInQProfileUpdateImpl.class,
- RegisterQualityProfiles.class,
- RegisterPermissionTemplates.class,
- RenameDeprecatedPropertyKeys.class,
- CeQueueCleaner.class);
-
- // RegisterServletFilters makes the WebService engine of Level4 served by the MasterServletFilter, therefor it
- // must be started after all the other startup tasks
- add(RegisterServletFilters.class);
- }
-
- @Override
- public PlatformLevel start() {
- DoPrivileged.execute(new DoPrivileged.Task(get(ThreadLocalUserSession.class)) {
- @Override
- protected void doPrivileged() {
- PlatformLevelStartup.super.start();
- getOptional(IndexerStartupTask.class).ifPresent(IndexerStartupTask::execute);
- // Need to be executed after indexing as it executes an ES query
- get(ProjectsInWarningDaemon.class).notifyStart();
- get(ServerLifecycleNotifier.class).notifyStart();
- get(ProcessCommandWrapper.class).notifyOperational();
- get(WebServerRuleFinder.class).stopCaching();
- Loggers.get(PlatformLevelStartup.class)
- .info("Running {} Edition", get(PlatformEditionProvider.class).get().map(EditionProvider.Edition::getLabel).orElse(""));
- }
- });
-
- return this;
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/package-info.java
deleted file mode 100644
index a147f3acf02..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.platformlevel;
-
-import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/web/CacheControlFilter.java b/server/sonar-server/src/main/java/org/sonar/server/platform/web/CacheControlFilter.java
deleted file mode 100644
index 1b257aa9ded..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/web/CacheControlFilter.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.web;
-
-import com.google.common.collect.ImmutableMap;
-import java.io.IOException;
-import java.util.Map;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import static java.lang.String.format;
-
-/**
- * This servlet filter sets response headers that enable cache control on some static resources
- */
-public class CacheControlFilter implements Filter {
-
- private static final String CACHE_CONTROL_HEADER = "Cache-Control";
-
- /**
- * Recommended max value for max-age is 1 year
- * @see <a href="https://stackoverflow.com/questions/7071763/max-value-for-cache-control-header-in-http">stackoverflow thread</a>
- */
- private static final int ONE_YEAR_IN_SECONDS = 365 * 24 * 60 * 60;
-
- private static final int FIVE_MINUTES_IN_SECONDS = 5 * 60;
-
- private static final String MAX_AGE_TEMPLATE = "max-age=%d";
-
- private static final Map<String, Integer> MAX_AGE_BY_PATH = ImmutableMap.of(
- // These folders contains files that are suffixed with their content hash : the cache should never be invalidated
- "/js/", ONE_YEAR_IN_SECONDS,
- "/css/", ONE_YEAR_IN_SECONDS,
- // This folder contains static resources from plugins : the cache should be set to a small value
- "/static/", FIVE_MINUTES_IN_SECONDS,
- "/images/", FIVE_MINUTES_IN_SECONDS);
-
- @Override
- public void init(FilterConfig filterConfig) {
- // nothing
- }
-
- @Override
- public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
- String path = ((HttpServletRequest) req).getRequestURI().replaceFirst(((HttpServletRequest) req).getContextPath(), "");
-
- MAX_AGE_BY_PATH.entrySet().stream()
- .filter(m -> path.startsWith(m.getKey()))
- .map(Map.Entry::getValue)
- .findFirst()
- .ifPresent(maxAge -> ((HttpServletResponse) resp).addHeader(CACHE_CONTROL_HEADER, format(MAX_AGE_TEMPLATE, maxAge)));
-
- chain.doFilter(req, resp);
- }
-
- @Override
- public void destroy() {
- // nothing
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/web/MasterServletFilter.java b/server/sonar-server/src/main/java/org/sonar/server/platform/web/MasterServletFilter.java
deleted file mode 100644
index a2de9a5e0b6..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/web/MasterServletFilter.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.web;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-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;
-
-/**
- * Inspired by http://stackoverflow.com/a/7592883/229031
- */
-public class MasterServletFilter implements Filter {
-
- public static volatile MasterServletFilter INSTANCE;
- private ServletFilter[] filters;
- private FilterConfig config;
-
- public MasterServletFilter() {
- if (INSTANCE != null) {
- throw new IllegalStateException("Servlet filter " + getClass().getName() + " is already instantiated");
- }
- INSTANCE = this;
- }
-
- @Override
- 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));
- }
-
- void init(FilterConfig config, List<ServletFilter> filters) {
- this.config = config;
- initFilters(filters);
- }
-
- public void initFilters(List<ServletFilter> filterExtensions) {
- List<ServletFilter> filterList = Lists.newArrayList();
- for (ServletFilter extension : filterExtensions) {
- try {
- Loggers.get(MasterServletFilter.class).info(String.format("Initializing servlet filter %s [pattern=%s]", extension, extension.doGetPattern().label()));
- extension.init(config);
- filterList.add(extension);
- } catch (Exception e) {
- throw new IllegalStateException("Fail to initialize servlet filter: " + extension + ". Message: " + e.getMessage(), e);
- }
- }
- filters = filterList.toArray(new ServletFilter[filterList.size()]);
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
- HttpServletRequest hsr = (HttpServletRequest) request;
- if (filters.length == 0) {
- chain.doFilter(hsr, response);
- } else {
- String path = hsr.getRequestURI().replaceFirst(hsr.getContextPath(), "");
- GodFilterChain godChain = new GodFilterChain(chain);
-
- for (ServletFilter filter : filters) {
- if (filter.doGetPattern().matches(path)) {
- godChain.addFilter(filter);
- }
- }
- godChain.doFilter(hsr, response);
- }
- }
-
- @Override
- public void destroy() {
- for (ServletFilter filter : filters) {
- filter.destroy();
- }
- }
-
- @VisibleForTesting
- ServletFilter[] getFilters() {
- return filters;
- }
-
- private static final class GodFilterChain implements FilterChain {
- private FilterChain chain;
- private List<Filter> filters = Lists.newLinkedList();
- private Iterator<Filter> iterator;
-
- public GodFilterChain(FilterChain chain) {
- this.chain = chain;
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
- if (iterator == null) {
- iterator = filters.iterator();
- }
- if (iterator.hasNext()) {
- iterator.next().doFilter(request, response, this);
- } else {
- chain.doFilter(request, response);
- }
- }
-
- public void addFilter(Filter filter) {
- Preconditions.checkState(iterator == null);
- filters.add(filter);
- }
- }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/web/PlatformServletContextListener.java b/server/sonar-server/src/main/java/org/sonar/server/platform/web/PlatformServletContextListener.java
deleted file mode 100644
index cfc68edd915..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/web/PlatformServletContextListener.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.web;
-
-import java.util.Enumeration;
-import java.util.Properties;
-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;
-
-public final class PlatformServletContextListener implements ServletContextListener {
- static final String STARTED_ATTRIBUTE = "sonarqube.started";
-
- @Override
- public void contextInitialized(ServletContextEvent event) {
- try {
- Properties props = new Properties();
- ServletContext servletContext = event.getServletContext();
- Enumeration<String> paramKeys = servletContext.getInitParameterNames();
- while (paramKeys.hasMoreElements()) {
- String key = paramKeys.nextElement();
- props.put(key, servletContext.getInitParameter(key));
- }
- Platform.getInstance().init(props, servletContext);
- Platform.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());
- stopQuietly();
- } catch (Throwable t) {
- Loggers.get(Platform.class).error("Web server startup failed", t);
- stopQuietly();
- throw new AbortTomcatStartException();
- }
- }
-
- private void stopQuietly() {
- try {
- Platform.getInstance().doStop();
- } catch (Exception e) {
- // ignored, but an error during startup generally prevents pico to be correctly stopped
- }
- }
-
- @Override
- public void contextDestroyed(ServletContextEvent event) {
- Platform.getInstance().doStop();
- }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/web/RedirectFilter.java b/server/sonar-server/src/main/java/org/sonar/server/platform/web/RedirectFilter.java
deleted file mode 100644
index 64a17466641..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/web/RedirectFilter.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.web;
-
-import com.google.common.collect.ImmutableList;
-import java.io.IOException;
-import java.util.List;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.sonar.core.util.stream.MoreCollectors;
-
-import static java.lang.String.format;
-
-public class RedirectFilter implements Filter {
-
- private static final String EMPTY = "";
-
- private static final List<Redirect> REDIRECTS = ImmutableList.of(
- newSimpleRedirect("/api", "/api/webservices/list"));
-
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
- HttpServletRequest request = (HttpServletRequest) servletRequest;
- HttpServletResponse response = (HttpServletResponse) servletResponse;
- String path = extractPath(request);
- Predicate<Redirect> match = redirect -> redirect.test(path);
- List<Redirect> redirects = REDIRECTS.stream()
- .filter(match)
- .collect(MoreCollectors.toList());
-
- switch (redirects.size()) {
- case 0:
- chain.doFilter(request, response);
- break;
- case 1:
- response.sendRedirect(redirects.get(0).apply(request));
- break;
- default:
- throw new IllegalStateException(format("Multiple redirects have been found for '%s'", path));
- }
- }
-
- public static Redirect newSimpleRedirect(String from, String to) {
- return new Redirect() {
- @Override
- public boolean test(String path) {
- return from.equals(path);
- }
-
- @Override
- public String apply(HttpServletRequest request) {
- return format("%s%s", request.getContextPath(), to);
- }
- };
- }
-
- @Override
- public void init(FilterConfig filterConfig) {
- // Nothing
- }
-
- @Override
- public void destroy() {
- // Nothing
- }
-
- private interface Redirect extends Predicate<String>, Function<HttpServletRequest, String> {
- @Override
- boolean test(String path);
-
- @Override
- String apply(HttpServletRequest request);
- }
-
- private static String extractPath(HttpServletRequest request) {
- return sanitizePath(request.getRequestURI().replaceFirst(request.getContextPath(), EMPTY));
- }
-
- private static String sanitizePath(String path) {
- if (path.length() > 1 && path.endsWith("/")) {
- return path.substring(0, path.length() - 1);
- }
- return path;
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/web/RegisterServletFilters.java b/server/sonar-server/src/main/java/org/sonar/server/platform/web/RegisterServletFilters.java
deleted file mode 100644
index 88b1692362e..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/web/RegisterServletFilters.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.web;
-
-import java.util.Arrays;
-import org.picocontainer.Startable;
-import org.sonar.api.web.ServletFilter;
-
-/**
- * @since 3.5
- */
-public class RegisterServletFilters implements Startable {
- private final ServletFilter[] filters;
-
- public RegisterServletFilters(ServletFilter[] filters) {
- this.filters = filters;
- }
-
- public RegisterServletFilters() {
- this(new ServletFilter[0]);
- }
-
- @Override
- public void start() {
- if (MasterServletFilter.INSTANCE != null) {
- // Probably a database upgrade. MasterSlaveFilter was instantiated by the servlet container
- // while picocontainer was not completely up.
- // See https://jira.sonarsource.com/browse/SONAR-3612
- MasterServletFilter.INSTANCE.initFilters(Arrays.asList(filters));
- }
- }
-
- @Override
- public void stop() {
- // nothing to do
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/web/SecurityServletFilter.java b/server/sonar-server/src/main/java/org/sonar/server/platform/web/SecurityServletFilter.java
deleted file mode 100644
index a8d1dd55cae..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/web/SecurityServletFilter.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.web;
-
-import com.google.common.collect.ImmutableSet;
-import java.io.IOException;
-import java.util.Set;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * This servlet filter sets response headers that enable browser protection against several classes if Web attacks.
- */
-public class SecurityServletFilter implements Filter {
-
- private static final Set<String> ALLOWED_HTTP_METHODS = ImmutableSet.of("DELETE", "GET", "HEAD", "POST", "PUT");
-
- @Override
- public void init(FilterConfig filterConfig) {
- // nothing
- }
-
- @Override
- public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
- doHttpFilter((HttpServletRequest) req, (HttpServletResponse) resp, chain);
- }
-
- private static void doHttpFilter(HttpServletRequest httpRequest, HttpServletResponse httpResponse, FilterChain chain) throws IOException, ServletException {
- // SONAR-6881 Disable OPTIONS and TRACE methods
- if (!ALLOWED_HTTP_METHODS.contains(httpRequest.getMethod())) {
- httpResponse.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
- return;
- }
-
- // WARNING, headers must be added before the doFilter, otherwise they won't be added when response is already committed (for instance when a WS is called)
-
- // Clickjacking protection
- // See https://www.owasp.org/index.php/Clickjacking_Protection_for_Java_EE
- // The protection is disabled on purpose for integration in external systems like VSTS (/integration/vsts/index.html).
- String path = httpRequest.getRequestURI().replaceFirst(httpRequest.getContextPath(), "");
- if (!path.startsWith("/integration/")) {
- httpResponse.addHeader("X-Frame-Options", "SAMEORIGIN");
- }
-
- // Cross-site scripting
- // See https://www.owasp.org/index.php/List_of_useful_HTTP_headers
- httpResponse.addHeader("X-XSS-Protection", "1; mode=block");
-
- // MIME-sniffing
- // See https://www.owasp.org/index.php/List_of_useful_HTTP_headers
- httpResponse.addHeader("X-Content-Type-Options", "nosniff");
-
- chain.doFilter(httpRequest, httpResponse);
- }
-
- @Override
- public void destroy() {
- // nothing
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/web/WebPagesCache.java b/server/sonar-server/src/main/java/org/sonar/server/platform/web/WebPagesCache.java
deleted file mode 100644
index ba4eedbc85d..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/web/WebPagesCache.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.web;
-
-import com.google.common.collect.ImmutableSet;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import javax.servlet.ServletContext;
-import org.apache.commons.io.IOUtils;
-import org.sonar.api.config.Configuration;
-import org.sonar.server.platform.OfficialDistribution;
-import org.sonar.server.platform.Platform;
-import org.sonar.server.platform.Platform.Status;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static java.util.Objects.requireNonNull;
-import static org.sonar.process.ProcessProperties.Property.SONARCLOUD_ENABLED;
-import static org.sonar.server.platform.Platform.Status.UP;
-
-public class WebPagesCache {
-
- private static final String WEB_CONTEXT_PLACEHOLDER = "%WEB_CONTEXT%";
- private static final String SERVER_STATUS_PLACEHOLDER = "%SERVER_STATUS%";
- private static final String INSTANCE_PLACEHOLDER = "%INSTANCE%";
- private static final String OFFICIAL_PLACEHOLDER = "%OFFICIAL%";
-
- private static final String SONARCLOUD_INSTANCE_VALUE = "SonarCloud";
- private static final String SONARQUBE_INSTANCE_VALUE = "SonarQube";
-
- private static final String INDEX_HTML_PATH = "/index.html";
-
- private static final Set<String> HTML_PATHS = ImmutableSet.of(INDEX_HTML_PATH, "/integration/vsts/index.html");
-
- private final Platform platform;
- private final Configuration configuration;
- private final OfficialDistribution officialDistribution;
-
- private ServletContext servletContext;
- private Map<String, String> indexHtmlByPath;
- private Status status;
-
- public WebPagesCache(Platform platform, Configuration configuration, OfficialDistribution officialDistribution) {
- this.platform = platform;
- this.configuration = configuration;
- this.indexHtmlByPath = new HashMap<>();
- this.officialDistribution = officialDistribution;
- }
-
- public void init(ServletContext servletContext) {
- this.servletContext = servletContext;
- generate(platform.status());
- }
-
- public String getContent(String path) {
- String htmlPath = HTML_PATHS.contains(path) ? path : INDEX_HTML_PATH;
- checkState(servletContext != null, "init has not been called");
- // Optimization to not have to call platform.currentStatus on each call
- if (Objects.equals(status, UP)) {
- return indexHtmlByPath.get(htmlPath);
- }
- Status currentStatus = platform.status();
- if (!Objects.equals(status, currentStatus)) {
- generate(currentStatus);
- }
- return indexHtmlByPath.get(htmlPath);
- }
-
- private void generate(Status status) {
- this.status = status;
- HTML_PATHS.forEach(path -> indexHtmlByPath.put(path, provide(path)));
- }
-
- private String provide(String path) {
- getClass().getResourceAsStream(INDEX_HTML_PATH);
- boolean isSonarCloud = configuration.getBoolean(SONARCLOUD_ENABLED.getKey()).orElse(false);
- String instance = isSonarCloud ? SONARCLOUD_INSTANCE_VALUE : SONARQUBE_INSTANCE_VALUE;
- return loadHtmlFile(path, status.name(), instance);
- }
-
- private String loadHtmlFile(String path, String serverStatus, String instance) {
- try (InputStream input = servletContext.getResourceAsStream(path)) {
- String template = IOUtils.toString(requireNonNull(input), UTF_8);
- return template
- .replaceAll(WEB_CONTEXT_PLACEHOLDER, servletContext.getContextPath())
- .replaceAll(SERVER_STATUS_PLACEHOLDER, serverStatus)
- .replaceAll(INSTANCE_PLACEHOLDER, instance)
- .replaceAll(OFFICIAL_PLACEHOLDER, String.valueOf(officialDistribution.check()));
- } catch (Exception e) {
- throw new IllegalStateException("Fail to load file " + path, e);
- }
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/web/WebPagesFilter.java b/server/sonar-server/src/main/java/org/sonar/server/platform/web/WebPagesFilter.java
deleted file mode 100644
index d464f62f603..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/web/WebPagesFilter.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.web;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.io.IOException;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-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 static java.nio.charset.StandardCharsets.UTF_8;
-import static java.util.Locale.ENGLISH;
-import static java.util.Objects.requireNonNull;
-import static org.apache.commons.io.IOUtils.write;
-import static org.sonar.api.web.ServletFilter.UrlPattern.Builder.staticResourcePatterns;
-import static org.sonarqube.ws.MediaTypes.HTML;
-
-/**
- * This filter provide the HTML file that will be used to display every web pages.
- * The same file should be provided for any URLs except WS and static resources.
- */
-public class WebPagesFilter implements Filter {
-
- private static final String CACHE_CONTROL_HEADER = "Cache-Control";
- private static final String CACHE_CONTROL_VALUE = "no-cache, no-store, must-revalidate";
-
- private static final ServletFilter.UrlPattern URL_PATTERN = ServletFilter.UrlPattern
- .builder()
- .excludes(staticResourcePatterns())
- .build();
-
- private WebPagesCache webPagesCache;
-
- public WebPagesFilter() {
- this(Platform.getInstance().getContainer().getComponentByType(WebPagesCache.class));
- }
-
- @VisibleForTesting
- WebPagesFilter(WebPagesCache webPagesCache) {
- this.webPagesCache = webPagesCache;
- }
-
- @Override
- public void init(FilterConfig filterConfig) {
- webPagesCache.init(filterConfig.getServletContext());
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- HttpServletRequest httpServletRequest = (HttpServletRequest) request;
- HttpServletResponse httpServletResponse = (HttpServletResponse) response;
- String path = httpServletRequest.getRequestURI().replaceFirst(httpServletRequest.getContextPath(), "");
- if (!URL_PATTERN.matches(path)) {
- chain.doFilter(request, response);
- return;
- }
- httpServletResponse.setContentType(HTML);
- httpServletResponse.setCharacterEncoding(UTF_8.name().toLowerCase(ENGLISH));
- httpServletResponse.setHeader(CACHE_CONTROL_HEADER, CACHE_CONTROL_VALUE);
-
- String htmlContent = requireNonNull(webPagesCache.getContent(path));
- write(htmlContent, httpServletResponse.getOutputStream(), UTF_8);
- }
-
- @Override
- public void destroy() {
- // Nothing to do
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/web/requestid/RequestIdFilter.java b/server/sonar-server/src/main/java/org/sonar/server/platform/web/requestid/RequestIdFilter.java
deleted file mode 100644
index ea9e5d5acf5..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/web/requestid/RequestIdFilter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.web.requestid;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.io.IOException;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import org.sonar.server.platform.Platform;
-
-/**
- * A {@link Filter} that puts and removes the HTTP request ID from the {@link org.slf4j.MDC}.
- */
-public class RequestIdFilter implements Filter {
-
- private final Platform platform;
-
- public RequestIdFilter() {
- this(Platform.getInstance());
- }
-
- @VisibleForTesting
- RequestIdFilter(Platform platform) {
- this.platform = platform;
- }
-
- @Override
- public void init(FilterConfig filterConfig) {
- // nothing to do
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- RequestIdGenerator requestIdGenerator = platform.getContainer().getComponentByType(RequestIdGenerator.class);
-
- if (requestIdGenerator == null) {
- chain.doFilter(request, response);
- } else {
- String requestId = requestIdGenerator.generate();
- try (RequestIdMDCStorage mdcStorage = new RequestIdMDCStorage(requestId)) {
- request.setAttribute("ID", requestId);
- chain.doFilter(request, response);
- }
- }
- }
-
- @Override
- public void destroy() {
- // nothing to do
- }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/web/requestid/RequestIdMDCStorage.java b/server/sonar-server/src/main/java/org/sonar/server/platform/web/requestid/RequestIdMDCStorage.java
index 7e23a7627a7..53b4bf49e33 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/web/requestid/RequestIdMDCStorage.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/web/requestid/RequestIdMDCStorage.java
@@ -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"));
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/StaticResourcesServlet.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/StaticResourcesServlet.java
deleted file mode 100644
index d32cc9e64f9..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/plugins/StaticResourcesServlet.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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.plugins;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import javax.annotation.CheckForNull;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.catalina.connector.ClientAbortException;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
-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.sonarqube.ws.MediaTypes;
-
-import static java.lang.String.format;
-import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
-import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
-
-public class StaticResourcesServlet extends HttpServlet {
-
- private static final Logger LOG = Loggers.get(StaticResourcesServlet.class);
- private static final long serialVersionUID = -2577454614650178426L;
-
- private final System system;
-
- @VisibleForTesting
- StaticResourcesServlet(System system) {
- this.system = system;
- }
-
- public StaticResourcesServlet() {
- this.system = new System();
- }
-
- @Override
- public void doGet(HttpServletRequest request, HttpServletResponse response) {
- String pluginKey = getPluginKey(request);
- String resource = getResourcePath(request);
- InputStream in = null;
- OutputStream out = null;
- try {
- CoreExtensionRepository coreExtensionRepository = system.getCoreExtensionRepository();
- PluginRepository pluginRepository = system.getPluginRepository();
-
- boolean coreExtension = coreExtensionRepository.isInstalled(pluginKey);
- if (!coreExtension && !pluginRepository.hasPlugin(pluginKey)) {
- silentlySendError(response, SC_NOT_FOUND);
- return;
- }
-
- in = coreExtension ? system.openCoreExtensionResourceStream(resource) : system.openPluginResourceStream(pluginKey, resource, pluginRepository);
- if (in == null) {
- silentlySendError(response, SC_NOT_FOUND);
- return;
- }
-
- // mime type must be set before writing response body
- completeContentType(response, resource);
- out = response.getOutputStream();
- IOUtils.copy(in, out);
- } catch (ClientAbortException e) {
- LOG.trace("Client canceled loading resource [{}] from plugin [{}]: {}", resource, pluginKey, e);
- } catch (Exception e) {
- LOG.error(format("Unable to load resource [%s] from plugin [%s]", resource, pluginKey), e);
- silentlySendError(response, SC_INTERNAL_SERVER_ERROR);
- } finally {
- IOUtils.closeQuietly(in);
- IOUtils.closeQuietly(out);
- }
- }
-
- private void silentlySendError(HttpServletResponse response, int error) {
- if (system.isCommitted(response)) {
- LOG.trace("Response is committed. Cannot send error response code {}", error);
- return;
- }
- try {
- system.sendError(response, error);
- } catch (IOException e) {
- LOG.trace("Failed to send error code {}: {}", error, e);
- }
- }
-
- /**
- * @return part of request URL after servlet path
- */
- private static String getPluginKeyAndResourcePath(HttpServletRequest request) {
- return StringUtils.substringAfter(request.getRequestURI(), request.getContextPath() + request.getServletPath() + "/");
- }
-
- private static String getPluginKey(HttpServletRequest request) {
- return StringUtils.substringBefore(getPluginKeyAndResourcePath(request), "/");
- }
-
- /**
- * Note that returned value should not have a leading "/" - see {@link Class#resolveName(String)}.
- */
- private static String getResourcePath(HttpServletRequest request) {
- return "static/" + StringUtils.substringAfter(getPluginKeyAndResourcePath(request), "/");
- }
-
- private static void completeContentType(HttpServletResponse response, String filename) {
- response.setContentType(MediaTypes.getByFilename(filename));
- }
-
- static class System {
- PluginRepository getPluginRepository() {
- return Platform.getInstance().getContainer().getComponentByType(PluginRepository.class);
- }
-
- CoreExtensionRepository getCoreExtensionRepository() {
- return Platform.getInstance().getContainer().getComponentByType(CoreExtensionRepository.class);
- }
-
- @CheckForNull
- InputStream openPluginResourceStream(String pluginKey, String resource, PluginRepository pluginRepository) throws Exception {
- ClassLoader pluginClassLoader = pluginRepository.getPluginInstance(pluginKey).getClass().getClassLoader();
- return pluginClassLoader.getResourceAsStream(resource);
- }
-
- @CheckForNull
- InputStream openCoreExtensionResourceStream(String resource) throws Exception {
- return getClass().getClassLoader().getResourceAsStream(resource);
- }
-
- boolean isCommitted(HttpServletResponse response) {
- return response.isCommitted();
- }
-
- void sendError(HttpServletResponse response, int error) throws IOException {
- response.sendError(error);
- }
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/UserSessionFilter.java b/server/sonar-server/src/main/java/org/sonar/server/user/UserSessionFilter.java
deleted file mode 100644
index bac3d96138d..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/user/UserSessionFilter.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.user;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.io.IOException;
-import javax.annotation.Nullable;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.sonar.db.DBSessions;
-import org.sonar.api.utils.log.Logger;
-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.setting.ThreadLocalSettings;
-
-public class UserSessionFilter implements Filter {
- private static final Logger LOG = Loggers.get(UserSessionFilter.class);
- private final Platform platform;
-
- public UserSessionFilter() {
- this.platform = Platform.getInstance();
- }
-
- @VisibleForTesting
- UserSessionFilter(Platform platform) {
- this.platform = platform;
- }
-
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
- HttpServletRequest request = (HttpServletRequest) servletRequest;
- HttpServletResponse response = (HttpServletResponse) servletResponse;
-
- DBSessions dbSessions = platform.getContainer().getComponentByType(DBSessions.class);
- ThreadLocalSettings settings = platform.getContainer().getComponentByType(ThreadLocalSettings.class);
- DefaultOrganizationCache defaultOrganizationCache = platform.getContainer().getComponentByType(DefaultOrganizationCache.class);
- UserSessionInitializer userSessionInitializer = platform.getContainer().getComponentByType(UserSessionInitializer.class);
-
- LOG.trace("{} serves {}", Thread.currentThread(), request.getRequestURI());
- dbSessions.enableCaching();
- try {
- defaultOrganizationCache.load();
- try {
- settings.load();
- try {
- doFilter(request, response, chain, userSessionInitializer);
- } finally {
- settings.unload();
- }
- } finally {
- defaultOrganizationCache.unload();
- }
- } finally {
- dbSessions.disableCaching();
- }
- }
-
- private static void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
- @Nullable UserSessionInitializer userSessionInitializer) throws IOException, ServletException {
- try {
- if (userSessionInitializer == null || userSessionInitializer.initUserSession(request, response)) {
- chain.doFilter(request, response);
- }
- } finally {
- if (userSessionInitializer != null) {
- userSessionInitializer.removeUserSession();
- }
- }
- }
-
- @Override
- public void init(FilterConfig filterConfig) {
- // nothing to do
- }
-
- @Override
- public void destroy() {
- // nothing to do
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/EmbeddedTomcatTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/EmbeddedTomcatTest.java
deleted file mode 100644
index 26c2d23a37e..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/app/EmbeddedTomcatTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.app;
-
-import java.io.File;
-import java.net.ConnectException;
-import java.net.InetAddress;
-import java.net.URL;
-import java.util.Properties;
-import org.apache.commons.io.FileUtils;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.process.NetworkUtilsImpl;
-import org.sonar.process.Props;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-
-public class EmbeddedTomcatTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Test
- public void start() throws Exception {
- Props props = new Props(new Properties());
-
- // prepare file system
- File home = temp.newFolder();
- File data = temp.newFolder();
- File webDir = new File(home, "web");
- FileUtils.write(new File(home, "web/WEB-INF/web.xml"), "<web-app/>");
- props.set("sonar.path.home", home.getAbsolutePath());
- props.set("sonar.path.data", data.getAbsolutePath());
- props.set("sonar.path.web", webDir.getAbsolutePath());
- props.set("sonar.path.logs", temp.newFolder().getAbsolutePath());
-
- // start server on a random port
- InetAddress address = InetAddress.getLoopbackAddress();
- int httpPort = NetworkUtilsImpl.INSTANCE.getNextAvailablePort(address);
- props.set("sonar.web.host", address.getHostAddress());
- props.set("sonar.web.port", String.valueOf(httpPort));
- EmbeddedTomcat tomcat = new EmbeddedTomcat(props);
- assertThat(tomcat.getStatus()).isEqualTo(EmbeddedTomcat.Status.DOWN);
- tomcat.start();
- assertThat(tomcat.getStatus()).isEqualTo(EmbeddedTomcat.Status.UP);
-
- // check that http connector accepts requests
- URL url = new URL("http://" + address.getHostAddress() + ":" + httpPort);
- url.openConnection().connect();
-
- // stop server
- tomcat.terminate();
- // tomcat.isUp() must not be called. It is used to wait for server startup, not shutdown.
- try {
- url.openConnection().connect();
- fail();
- } catch (ConnectException e) {
- // expected
- }
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/NullJarScannerTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/NullJarScannerTest.java
deleted file mode 100644
index de2919ca2ef..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/app/NullJarScannerTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.app;
-
-import org.apache.tomcat.JarScanFilter;
-import org.apache.tomcat.JarScanType;
-import org.apache.tomcat.JarScannerCallback;
-import org.junit.Test;
-
-import javax.servlet.ServletContext;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-public class NullJarScannerTest {
- @Test
- public void does_nothing() {
- ServletContext context = mock(ServletContext.class);
- JarScannerCallback callback = mock(JarScannerCallback.class);
-
- NullJarScanner scanner = new NullJarScanner();
-
- scanner.scan(JarScanType.PLUGGABILITY, context, callback);
- verifyZeroInteractions(context, callback);
- scanner.setJarScanFilter(mock(JarScanFilter.class));
- assertThat(scanner.getJarScanFilter()).isNull();
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/ProgrammaticLogbackValveTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/ProgrammaticLogbackValveTest.java
deleted file mode 100644
index fe5f4121e11..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/app/ProgrammaticLogbackValveTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.app;
-
-import org.apache.catalina.Container;
-import org.junit.AfterClass;
-import org.junit.Test;
-import org.sonar.process.logging.LogbackHelper;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class ProgrammaticLogbackValveTest {
-
- @AfterClass
- public static void resetLogback() throws Exception {
- new LogbackHelper().resetFromXml("/logback-test.xml");
- }
-
- @Test
- public void startInternal() throws Exception {
- ProgrammaticLogbackValve valve = new ProgrammaticLogbackValve();
- valve.setContainer(mock(Container.class));
-
- valve.start();
- assertThat(valve.isStarted()).isTrue();
-
- valve.stop();
- assertThat(valve.isStarted()).isFalse();
- }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/StartupLogsTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/StartupLogsTest.java
deleted file mode 100644
index e0d26e33749..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/app/StartupLogsTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.app;
-
-import org.apache.catalina.connector.Connector;
-import org.apache.catalina.startup.Tomcat;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.Mockito;
-import org.sonar.api.utils.log.Logger;
-
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-public class StartupLogsTest {
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
- private Logger logger = mock(Logger.class);
- private TomcatStartupLogs underTest = new TomcatStartupLogs(logger);
-
- @Test
- public void fail_with_IAE_on_unsupported_protocol() {
- Connector connector = newConnector("AJP/1.3", "ajp");
- when(tomcat.getService().findConnectors()).thenReturn(new Connector[] {connector});
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Unsupported connector: Connector[AJP/1.3-1234]");
-
- underTest.log(tomcat);
- }
-
- @Test
- public void logHttp() {
- Connector connector = newConnector("HTTP/1.1", "http");
- when(tomcat.getService().findConnectors()).thenReturn(new Connector[] {connector});
-
- underTest.log(tomcat);
-
- verify(logger).info("HTTP connector enabled on port 1234");
- verifyNoMoreInteractions(logger);
- }
-
- @Test
- public void unsupported_connector() {
- Connector connector = mock(Connector.class, Mockito.RETURNS_DEEP_STUBS);
- when(connector.getProtocol()).thenReturn("SPDY/1.1");
- when(connector.getScheme()).thenReturn("spdy");
- when(tomcat.getService().findConnectors()).thenReturn(new Connector[] {connector});
- try {
- underTest.log(tomcat);
- fail();
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- private Connector newConnector(String protocol, String schema) {
- Connector httpConnector = new Connector(protocol);
- httpConnector.setScheme(schema);
- httpConnector.setPort(1234);
- return httpConnector;
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/TomcatAccessLogTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/TomcatAccessLogTest.java
deleted file mode 100644
index 750c77ce376..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/app/TomcatAccessLogTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.app;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Properties;
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleEvent;
-import org.apache.catalina.startup.Tomcat;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.mockito.Mockito;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.process.Props;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
-
-public class TomcatAccessLogTest {
-
- TomcatAccessLog underTest = new TomcatAccessLog();
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Before
- public void setHome() throws IOException {
- File homeDir = temp.newFolder("home");
- System.setProperty("SONAR_HOME", homeDir.getAbsolutePath());
- }
-
- @Test
- public void enable_access_logs_by_Default() throws Exception {
- Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
- Props props = new Props(new Properties());
- props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());
- underTest.configure(tomcat, props);
-
- verify(tomcat.getHost().getPipeline()).addValve(any(ProgrammaticLogbackValve.class));
- }
-
- @Test
- public void log_when_started_and_stopped() {
- Logger logger = mock(Logger.class);
- TomcatAccessLog.LifecycleLogger listener = new TomcatAccessLog.LifecycleLogger(logger);
-
- LifecycleEvent event = new LifecycleEvent(mock(Lifecycle.class), "before_init", null);
- listener.lifecycleEvent(event);
- verifyZeroInteractions(logger);
-
- event = new LifecycleEvent(mock(Lifecycle.class), "after_start", null);
- listener.lifecycleEvent(event);
- verify(logger).debug("Tomcat is started");
-
- event = new LifecycleEvent(mock(Lifecycle.class), "after_destroy", null);
- listener.lifecycleEvent(event);
- verify(logger).debug("Tomcat is stopped");
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/TomcatConnectorsTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/TomcatConnectorsTest.java
deleted file mode 100644
index 27035ac9480..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/app/TomcatConnectorsTest.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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.app;
-
-import com.google.common.collect.ImmutableMap;
-import java.net.InetAddress;
-import java.util.Map;
-import java.util.Properties;
-import org.apache.catalina.startup.Tomcat;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.sonar.process.Props;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-public class TomcatConnectorsTest {
-
- private static final int DEFAULT_PORT = 9000;
- private Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
-
- @Test
- public void configure_thread_pool() {
- Properties p = new Properties();
- p.setProperty("sonar.web.http.minThreads", "2");
- p.setProperty("sonar.web.http.maxThreads", "30");
- p.setProperty("sonar.web.http.acceptCount", "20");
- Props props = new Props(p);
-
- TomcatConnectors.configure(tomcat, props);
-
- verifyHttpConnector(DEFAULT_PORT, ImmutableMap.of("minSpareThreads", 2, "maxThreads", 30, "acceptCount", 20));
- }
-
- @Test
- public void configure_defaults() {
- Props props = new Props(new Properties());
-
- TomcatConnectors.configure(tomcat, props);
-
- verifyHttpConnector(DEFAULT_PORT, ImmutableMap.of("minSpareThreads", 5, "maxThreads", 50, "acceptCount", 25));
- }
-
- @Test
- public void different_thread_pools_for_connectors() {
- Properties p = new Properties();
- p.setProperty("sonar.web.http.minThreads", "2");
- Props props = new Props(p);
-
- TomcatConnectors.configure(tomcat, props);
-
- verifyHttpConnector(DEFAULT_PORT, ImmutableMap.of("minSpareThreads", 2));
- }
-
- @Test
- public void fail_with_ISE_if_http_port_is_invalid() {
- Properties p = new Properties();
- p.setProperty("sonar.web.port", "-1");
-
- try {
- TomcatConnectors.configure(tomcat, new Props(p));
- fail();
- } catch (IllegalStateException e) {
- assertThat(e).hasMessage("HTTP port '-1' is invalid");
- }
- }
-
- @Test
- public void bind_to_all_addresses_by_default() {
- Properties p = new Properties();
- p.setProperty("sonar.web.port", "9000");
-
- TomcatConnectors.configure(tomcat, new Props(p));
-
- verify(tomcat.getService()).addConnector(argThat(c -> c.getScheme().equals("http") && c.getPort() == 9000 && ((InetAddress) c.getProperty("address")).getHostAddress().equals("0.0.0.0")));
- }
-
- @Test
- public void bind_to_specific_address() {
- Properties p = new Properties();
- p.setProperty("sonar.web.port", "9000");
- p.setProperty("sonar.web.host", "1.2.3.4");
-
- TomcatConnectors.configure(tomcat, new Props(p));
-
- verify(tomcat.getService())
- .addConnector(argThat(c -> c.getScheme().equals("http") && c.getPort() == 9000 && ((InetAddress) c.getProperty("address")).getHostAddress().equals("1.2.3.4")));
- }
-
- @Test
- public void test_max_http_header_size_for_http_connection() {
- TomcatConnectors.configure(tomcat, new Props(new Properties()));
-
- verifyHttpConnector(DEFAULT_PORT, ImmutableMap.of("maxHttpHeaderSize", TomcatConnectors.MAX_HTTP_HEADER_SIZE_BYTES));
- }
-
- @Test
- public void test_max_post_size_for_http_connection() {
- Properties properties = new Properties();
-
- Props props = new Props(properties);
- TomcatConnectors.configure(tomcat, props);
- verify(tomcat.getService()).addConnector(argThat(c -> c.getMaxPostSize() == -1));
- }
-
- private void verifyHttpConnector(int expectedPort, Map<String, Object> expectedProps) {
- verify(tomcat.getService()).addConnector(argThat(c -> {
- if (!c.getScheme().equals("http")) {
- return false;
- }
- if (!c.getProtocol().equals(TomcatConnectors.HTTP_PROTOCOL)) {
- return false;
- }
- if (c.getPort() != expectedPort) {
- return false;
- }
- for (Map.Entry<String, Object> expectedProp : expectedProps.entrySet()) {
- if (!expectedProp.getValue().equals(c.getProperty(expectedProp.getKey()))) {
- return false;
- }
- }
- return true;
- }));
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/TomcatContextsTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/TomcatContextsTest.java
deleted file mode 100644
index b9a0c808d61..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/app/TomcatContextsTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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.app;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Properties;
-import org.apache.catalina.core.StandardContext;
-import org.apache.catalina.startup.Tomcat;
-import org.apache.commons.io.FileUtils;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.utils.MessageException;
-import org.sonar.process.Props;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.sonar.process.ProcessProperties.Property;
-
-public class TomcatContextsTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- Tomcat tomcat = mock(Tomcat.class);
-
- Properties props = new Properties();
- TomcatContexts underTest = new TomcatContexts();
-
- @Before
- public void setUp() throws Exception {
- props.setProperty(Property.PATH_DATA.getKey(), temp.newFolder("data").getAbsolutePath());
- when(tomcat.addWebapp(anyString(), anyString())).thenReturn(mock(StandardContext.class));
- }
-
- @Test
- public void configure_root_webapp() throws Exception {
- props.setProperty("foo", "bar");
- StandardContext context = mock(StandardContext.class);
- when(tomcat.addWebapp(anyString(), anyString())).thenReturn(context);
-
- underTest.configure(tomcat, new Props(props));
-
- // configure webapp with properties
- verify(context).addParameter("foo", "bar");
- }
-
- @Test
- public void create_dir_and_configure_static_directory() throws Exception {
- File dir = temp.newFolder();
- dir.delete();
-
- underTest.addStaticDir(tomcat, "/deploy", dir);
-
- assertThat(dir).isDirectory().exists();
- verify(tomcat).addWebapp("/deploy", dir.getAbsolutePath());
- }
-
- @Test
- public void cleanup_static_directory_if_already_exists() throws Exception {
- File dir = temp.newFolder();
- FileUtils.touch(new File(dir, "foo.txt"));
-
- underTest.addStaticDir(tomcat, "/deploy", dir);
-
- assertThat(dir).isDirectory().exists();
- assertThat(dir.listFiles()).isEmpty();
- }
-
- @Test
- public void fail_if_static_directory_can_not_be_initialized() throws Exception {
- File dir = temp.newFolder();
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("Fail to create or clean-up directory " + dir.getAbsolutePath());
-
- TomcatContexts.Fs fs = mock(TomcatContexts.Fs.class);
- doThrow(new IOException()).when(fs).createOrCleanupDir(any(File.class));
-
- new TomcatContexts(fs).addStaticDir(tomcat, "/deploy", dir);
- }
-
- @Test
- public void context_path() {
- props.setProperty("sonar.web.context", "/foo");
-
- assertThat(TomcatContexts.getContextPath(new Props(props))).isEqualTo("/foo");
- }
-
- @Test
- public void context_path_must_start_with_slash() {
- props.setProperty("sonar.web.context", "foo");
-
- expectedException.expect(MessageException.class);
- expectedException.expectMessage("Value of 'sonar.web.context' must start with a forward slash: 'foo'");
- underTest.configure(tomcat, new Props(props));
- }
-
- @Test
- public void root_context_path_must_be_blank() {
- props.setProperty("sonar.web.context", "/");
-
- assertThat(TomcatContexts.getContextPath(new Props(props))).isEqualTo("");
- }
-
- @Test
- public void default_context_path_is_root() {
- String context = TomcatContexts.getContextPath(new Props(new Properties()));
- assertThat(context).isEqualTo("");
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel1Test.java b/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel1Test.java
deleted file mode 100644
index 7bed9b1f319..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel1Test.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.platformlevel;
-
-import java.util.Properties;
-import org.junit.Test;
-import org.sonar.api.config.PropertyDefinition;
-import org.sonar.api.utils.System2;
-import org.sonar.server.platform.Platform;
-import org.sonar.server.platform.WebServer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-
-public class PlatformLevel1Test {
-
- private PlatformLevel1 underTest = new PlatformLevel1(mock(Platform.class), new Properties());
-
- @Test
- public void no_missing_dependencies_between_components() {
- underTest.configureLevel();
-
- assertThat(underTest.getAll(PropertyDefinition.class)).isNotEmpty();
- assertThat(underTest.getOptional(WebServer.class)).isPresent();
- assertThat(underTest.getOptional(System2.class)).isPresent();
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java b/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java
deleted file mode 100644
index f196aa6f135..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.platformlevel;
-
-import java.util.Properties;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.utils.System2;
-import org.sonar.core.platform.PluginRepository;
-import org.sonar.server.platform.Platform;
-import org.sonar.server.platform.WebServer;
-import org.sonar.server.platform.db.migration.charset.DatabaseCharsetChecker;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
-import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
-import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;
-
-public class PlatformLevel2Test {
-
- @Rule
- public TemporaryFolder tempFolder = new TemporaryFolder();
-
- private Properties props = new Properties();
-
- @Before
- public void setUp() throws Exception {
- // these are mandatory settings declared by bootstrap process
- props.setProperty(PATH_HOME.getKey(), tempFolder.newFolder().getAbsolutePath());
- props.setProperty(PATH_DATA.getKey(), tempFolder.newFolder().getAbsolutePath());
- props.setProperty(PATH_TEMP.getKey(), tempFolder.newFolder().getAbsolutePath());
- }
-
- @Test
- public void add_all_components_by_default() {
- PlatformLevel1 level1 = new PlatformLevel1(mock(Platform.class), props);
- level1.configure();
-
- PlatformLevel2 underTest = new PlatformLevel2(level1);
- underTest.configure();
-
- // some level1 components
- assertThat(underTest.getOptional(WebServer.class)).isPresent();
- assertThat(underTest.getOptional(System2.class)).isPresent();
-
- // level2 component that does not depend on cluster state
- assertThat(underTest.getOptional(PluginRepository.class)).isPresent();
-
- // level2 component that is injected only on "startup leaders"
- assertThat(underTest.getOptional(DatabaseCharsetChecker.class)).isPresent();
- }
-
- @Test
- public void do_not_add_all_components_when_startup_follower() {
- props.setProperty("sonar.cluster.enabled", "true");
- PlatformLevel1 level1 = new PlatformLevel1(mock(Platform.class), props);
- level1.configure();
-
- PlatformLevel2 underTest = new PlatformLevel2(level1);
- underTest.configure();
-
- assertThat(underTest.get(WebServer.class).isStartupLeader()).isFalse();
-
- // level2 component that does not depend on cluster state
- assertThat(underTest.getOptional(PluginRepository.class)).isPresent();
-
- // level2 component that is injected only on "startup leaders"
- assertThat(underTest.getOptional(DatabaseCharsetChecker.class)).isNotPresent();
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevelTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevelTest.java
deleted file mode 100644
index b3d70118df1..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevelTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.platformlevel;
-
-import java.util.Random;
-import java.util.stream.IntStream;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.Mockito;
-import org.sonar.server.platform.WebServer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class PlatformLevelTest {
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private PlatformLevel underTest = new PlatformLevel("name") {
-
- @Override
- protected void configureLevel() {
-
- }
- };
-
- @Test
- public void addIfStartupLeader_throws_ISE_if_container_does_not_have_WebServer_object() {
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("WebServer not available in Pico yet");
-
- underTest.addIfStartupLeader();
- }
-
- @Test
- public void addIfStartupLeader_always_returns_the_same_instance() {
- underTest.add(Mockito.mock(WebServer.class));
-
- PlatformLevel.AddIfStartupLeader addIfStartupLeader = underTest.addIfStartupLeader();
- IntStream.range(0, 1 + new Random().nextInt(4)).forEach(i -> assertThat(underTest.addIfStartupLeader()).isSameAs(addIfStartupLeader));
- }
-
- @Test
- public void addIfCluster_throws_ISE_if_container_does_not_have_WebServer_object() {
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("WebServer not available in Pico yet");
-
- underTest.addIfCluster();
- }
-
- @Test
- public void addIfCluster_always_returns_the_same_instance() {
- underTest.add(Mockito.mock(WebServer.class));
-
- PlatformLevel.AddIfCluster addIfCluster = underTest.addIfCluster();
- IntStream.range(0, 1 + new Random().nextInt(4)).forEach(i -> assertThat(underTest.addIfCluster()).isSameAs(addIfCluster));
- }
-
- @Test
- public void addIfStandalone_throws_ISE_if_container_does_not_have_WebServer_object() {
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("WebServer not available in Pico yet");
-
- underTest.addIfCluster();
- }
-
- @Test
- public void addIfStandalone_always_returns_the_same_instance() {
- underTest.add(Mockito.mock(WebServer.class));
-
- PlatformLevel.AddIfCluster addIfCluster = underTest.addIfCluster();
- IntStream.range(0, 1 + new Random().nextInt(4)).forEach(i -> assertThat(underTest.addIfCluster()).isSameAs(addIfCluster));
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/web/CacheControlFilterTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/web/CacheControlFilterTest.java
deleted file mode 100644
index 5b541f9e859..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/web/CacheControlFilterTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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.web;
-
-import javax.servlet.FilterChain;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.junit.Test;
-
-import static java.lang.String.format;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class CacheControlFilterTest {
-
- private HttpServletResponse response = mock(HttpServletResponse.class);
- private FilterChain chain = mock(FilterChain.class);
-
- private CacheControlFilter underTest = new CacheControlFilter();
-
- @Test
- public void max_age_is_set_to_one_year_on_js() throws Exception {
- HttpServletRequest request = newRequest("/js/sonar.js");
-
- underTest.doFilter(request, response, chain);
-
- verify(response).addHeader("Cache-Control", format("max-age=%s", 31_536_000));
- }
-
- @Test
- public void max_age_is_set_to_one_year_on_css() throws Exception {
- HttpServletRequest request = newRequest("/css/sonar.css");
-
- underTest.doFilter(request, response, chain);
-
- verify(response).addHeader("Cache-Control", format("max-age=%s", 31_536_000));
- }
-
- @Test
- public void max_age_is_set_to_five_minutes_on_images() throws Exception {
- HttpServletRequest request = newRequest("/images/logo.png");
-
- underTest.doFilter(request, response, chain);
-
- verify(response).addHeader("Cache-Control", format("max-age=%s", 300));
- }
-
- @Test
- public void max_age_is_set_to_five_minutes_on_static() throws Exception {
- HttpServletRequest request = newRequest("/static/something");
-
- underTest.doFilter(request, response, chain);
-
- verify(response).addHeader("Cache-Control", format("max-age=%s", 300));
- }
-
- @Test
- public void max_age_is_set_to_five_minutes_on_css_of_static() throws Exception {
- HttpServletRequest request = newRequest("/static/css/custom.css");
-
- underTest.doFilter(request, response, chain);
-
- verify(response).addHeader("Cache-Control", format("max-age=%s", 300));
- }
-
- @Test
- public void does_nothing_on_home() throws Exception {
- HttpServletRequest request = newRequest("/");
-
- underTest.doFilter(request, response, chain);
-
- verifyZeroInteractions(response);
- }
-
- @Test
- public void does_nothing_on_web_service() throws Exception {
- HttpServletRequest request = newRequest("/api/ping");
-
- underTest.doFilter(request, response, chain);
-
- verifyZeroInteractions(response);
- }
-
- private static HttpServletRequest newRequest(String path) {
- HttpServletRequest req = mock(HttpServletRequest.class);
- when(req.getMethod()).thenReturn("GET");
- when(req.getRequestURI()).thenReturn(path);
- when(req.getContextPath()).thenReturn("");
- return req;
- }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/web/MasterServletFilterTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/web/MasterServletFilterTest.java
deleted file mode 100644
index 3999670c143..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/web/MasterServletFilterTest.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.web;
-
-import java.io.IOException;
-import java.util.Collections;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.utils.log.LogTester;
-import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.api.web.ServletFilter;
-import org.sonar.api.web.ServletFilter.UrlPattern;
-
-import static java.util.Arrays.asList;
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class MasterServletFilterTest {
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- @Rule
- public LogTester logTester = new LogTester();
-
- @Before
- public void resetSingleton() {
- MasterServletFilter.INSTANCE = null;
- }
-
- @Test
- public void should_init_and_destroy_filters() throws Exception {
- ServletFilter filter = createMockFilter();
- FilterConfig config = mock(FilterConfig.class);
- MasterServletFilter master = new MasterServletFilter();
- master.init(config, singletonList(filter));
-
- assertThat(master.getFilters()).containsOnly(filter);
- verify(filter).init(config);
-
- master.destroy();
- verify(filter).destroy();
- }
-
- @Test
- public void servlet_container_should_instantiate_only_a_single_master_instance() {
- new MasterServletFilter();
-
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("Servlet filter org.sonar.server.platform.web.MasterServletFilter is already instantiated");
- new MasterServletFilter();
- }
-
- @Test
- public void should_propagate_initialization_failure() throws Exception {
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("foo");
-
- ServletFilter filter = createMockFilter();
- doThrow(new IllegalStateException("foo")).when(filter).init(any(FilterConfig.class));
-
- FilterConfig config = mock(FilterConfig.class);
- MasterServletFilter filters = new MasterServletFilter();
- filters.init(config, singletonList(filter));
- }
-
- @Test
- public void filters_should_be_optional() throws Exception {
- FilterConfig config = mock(FilterConfig.class);
- MasterServletFilter filters = new MasterServletFilter();
- filters.init(config, Collections.emptyList());
-
- ServletRequest request = mock(HttpServletRequest.class);
- ServletResponse response = mock(HttpServletResponse.class);
- FilterChain chain = mock(FilterChain.class);
- filters.doFilter(request, response, chain);
-
- verify(chain).doFilter(request, response);
- }
-
- @Test
- public void should_keep_filter_ordering() throws Exception {
- TrueFilter filter1 = new TrueFilter();
- TrueFilter filter2 = new TrueFilter();
-
- MasterServletFilter filters = new MasterServletFilter();
- filters.init(mock(FilterConfig.class), asList(filter1, filter2));
-
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getRequestURI()).thenReturn("/foo/bar");
- when(request.getContextPath()).thenReturn("");
- ServletResponse response = mock(HttpServletResponse.class);
- FilterChain chain = mock(FilterChain.class);
- filters.doFilter(request, response, chain);
-
- assertThat(filter1.count).isEqualTo(1);
- assertThat(filter2.count).isEqualTo(2);
- }
-
- @Test
- public void display_servlet_filter_patterns_in_INFO_log() throws Exception {
- ServletFilter filter = new PatternFilter(UrlPattern.builder().includes("/api/issues").excludes("/batch/projects").build());
- FilterConfig config = mock(FilterConfig.class);
- MasterServletFilter master = new MasterServletFilter();
-
- master.init(config, singletonList(filter));
-
- assertThat(logTester.logs(LoggerLevel.INFO)).containsOnly("Initializing servlet filter PatternFilter [pattern=UrlPattern{inclusions=[/api/issues], exclusions=[/batch/projects]}]");
- }
-
- private static ServletFilter createMockFilter() {
- ServletFilter filter = mock(ServletFilter.class);
- when(filter.doGetPattern()).thenReturn(UrlPattern.builder().build());
- return filter;
- }
-
- private static final class TrueFilter extends ServletFilter {
- private static int globalCount = 0;
- private int count = 0;
-
- @Override
- public void init(FilterConfig filterConfig) {
- }
-
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- globalCount++;
- count = globalCount;
- filterChain.doFilter(servletRequest, servletResponse);
- }
-
- @Override
- public void destroy() {
- }
- }
-
- private static class PatternFilter extends ServletFilter {
-
- private final UrlPattern urlPattern;
-
- PatternFilter(UrlPattern urlPattern) {
- this.urlPattern = urlPattern;
- }
-
- @Override
- public UrlPattern doGetPattern() {
- return urlPattern;
- }
-
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
- // Nothing to do
- }
-
- @Override
- public void init(FilterConfig filterConfig) {
- // Nothing to do
- }
-
- @Override
- public void destroy() {
- // Nothing to do
- }
-
- @Override
- public String toString() {
- return "PatternFilter";
- }
- }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/web/RedirectFilterTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/web/RedirectFilterTest.java
deleted file mode 100644
index 255e97509cc..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/web/RedirectFilterTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.web;
-
-import java.io.IOException;
-import javax.annotation.Nullable;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class RedirectFilterTest {
-
- private HttpServletRequest request = mock(HttpServletRequest.class);
- private HttpServletResponse response = mock(HttpServletResponse.class);
- private FilterChain chain = mock(FilterChain.class);
-
- private RedirectFilter underTest = new RedirectFilter();
-
- @Before
- public void setUp() throws Exception {
- when(request.getContextPath()).thenReturn("/sonarqube");
- }
-
- @Test
- public void send_redirect_when_url_contains_only_api() throws Exception {
- verifyRedirection("/api", null, "/sonarqube/api/webservices/list");
- verifyRedirection("/api/", null, "/sonarqube/api/webservices/list");
- }
-
- @Test
- public void does_not_redirect_and_execute_remaining_filter_on_unknown_path() throws Exception {
- verifyNoRedirection("/api/issues/search", null);
- }
-
- private void verifyRedirection(String requestUrl, @Nullable String queryString, String expectedRedirection) throws Exception {
- when(request.getRequestURI()).thenReturn(requestUrl);
- when(request.getQueryString()).thenReturn(queryString);
-
- underTest.doFilter(request, response, chain);
-
- verify(response).sendRedirect(expectedRedirection);
- verifyZeroInteractions(chain);
- reset(response, chain);
- }
-
- private void verifyNoRedirection(String requestUrl, @Nullable String queryString) throws IOException, ServletException {
- when(request.getRequestURI()).thenReturn(requestUrl);
- when(request.getQueryString()).thenReturn(queryString);
- when(request.getParameter(anyString())).thenReturn(null);
-
- underTest.doFilter(request, response, chain);
-
- verify(chain).doFilter(request, response);
- verifyZeroInteractions(response);
- reset(response, chain);
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/web/RootFilterTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/web/RootFilterTest.java
deleted file mode 100644
index e700d9983a8..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/web/RootFilterTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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.web;
-
-import java.util.List;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.ArgumentCaptor;
-import org.sonar.api.utils.log.LogTester;
-import org.sonar.api.utils.log.LoggerLevel;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class RootFilterTest {
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
- @Rule
- public LogTester logTester = new LogTester();
-
- private FilterChain chain = mock(FilterChain.class);
- private RootFilter underTest;
-
- @Before
- public void initialize() {
- FilterConfig filterConfig = mock(FilterConfig.class);
- ServletContext context = mock(ServletContext.class);
- when(context.getContextPath()).thenReturn("/context");
- when(filterConfig.getServletContext()).thenReturn(context);
- underTest = new RootFilter();
- underTest.init(filterConfig);
- }
-
- @Test
- public void throwable_in_doFilter_is_caught_and_500_error_returned_if_response_is_not_committed() throws Exception {
- doThrow(new RuntimeException()).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
- HttpServletResponse response = mockHttpResponse(false);
- underTest.doFilter(request("POST", "/context/service/call", "param=value"), response, chain);
-
- verify(response).sendError(500);
- }
-
- @Test
- public void throwable_in_doFilter_is_caught_but_no_500_response_is_sent_if_response_already_committed() throws Exception {
- doThrow(new RuntimeException()).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
- HttpServletResponse response = mockHttpResponse(true);
- underTest.doFilter(request("POST", "/context/service/call", "param=value"), response, chain);
-
- verify(response, never()).sendError(500);
- }
-
- @Test
- public void throwable_in_doFilter_is_logged_in_debug_if_response_is_already_committed() throws Exception {
- doThrow(new RuntimeException()).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
- HttpServletResponse response = mockHttpResponse(true);
- underTest.doFilter(request("POST", "/context/service/call", "param=value"), response, chain);
-
- List<String> debugLogs = logTester.logs(LoggerLevel.DEBUG);
- assertThat(debugLogs.size()).isEqualTo(1);
- assertThat(debugLogs.get(0)).contains("Processing of request", "failed");
- }
-
-
- @Test
- public void request_used_in_chain_do_filter_is_a_servlet_wrapper_when_static_resource() throws Exception {
- underTest.doFilter(request("GET", "/context/static/image.png", null), mock(HttpServletResponse.class), chain);
- ArgumentCaptor<ServletRequest> requestArgumentCaptor = ArgumentCaptor.forClass(ServletRequest.class);
-
- verify(chain).doFilter(requestArgumentCaptor.capture(), any(HttpServletResponse.class));
-
- assertThat(requestArgumentCaptor.getValue()).isInstanceOf(RootFilter.ServletRequestWrapper.class);
- }
-
- @Test
- public void request_used_in_chain_do_filter_is_a_servlet_wrapper_when_service_call() throws Exception {
- underTest.doFilter(request("POST", "/context/service/call", "param=value"), mock(HttpServletResponse.class), chain);
- ArgumentCaptor<ServletRequest> requestArgumentCaptor = ArgumentCaptor.forClass(ServletRequest.class);
-
- verify(chain).doFilter(requestArgumentCaptor.capture(), any(HttpServletResponse.class));
-
- assertThat(requestArgumentCaptor.getValue()).isInstanceOf(RootFilter.ServletRequestWrapper.class);
- }
-
- @Test
- public void fail_to_get_session_from_request() throws Exception {
- underTest.doFilter(request("GET", "/context/static/image.png", null), mock(HttpServletResponse.class), chain);
- ArgumentCaptor<ServletRequest> requestArgumentCaptor = ArgumentCaptor.forClass(ServletRequest.class);
- verify(chain).doFilter(requestArgumentCaptor.capture(), any(ServletResponse.class));
-
- expectedException.expect(UnsupportedOperationException.class);
- ((HttpServletRequest) requestArgumentCaptor.getValue()).getSession();
- }
-
- @Test
- public void fail_to_get_session_with_create_from_request() throws Exception {
- underTest.doFilter(request("GET", "/context/static/image.png", null), mock(HttpServletResponse.class), chain);
- ArgumentCaptor<ServletRequest> requestArgumentCaptor = ArgumentCaptor.forClass(ServletRequest.class);
- verify(chain).doFilter(requestArgumentCaptor.capture(), any(ServletResponse.class));
-
- expectedException.expect(UnsupportedOperationException.class);
- ((HttpServletRequest) requestArgumentCaptor.getValue()).getSession(true);
- }
-
- private HttpServletRequest request(String method, String path, String query) {
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getMethod()).thenReturn(method);
- when(request.getRequestURI()).thenReturn(path);
- when(request.getQueryString()).thenReturn(query);
- return request;
- }
-
- private static HttpServletResponse mockHttpResponse(boolean committed) {
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.isCommitted()).thenReturn(committed);
- return response;
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/web/SecurityServletFilterTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/web/SecurityServletFilterTest.java
deleted file mode 100644
index e01eb8947ee..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/web/SecurityServletFilterTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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.web;
-
-import java.io.IOException;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.junit.Test;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class SecurityServletFilterTest {
-
- private SecurityServletFilter underTest = new SecurityServletFilter();
- private HttpServletResponse response = mock(HttpServletResponse.class);
- private FilterChain chain = mock(FilterChain.class);
-
- @Test
- public void allow_GET_method() throws IOException, ServletException {
- assertThatMethodIsAllowed("GET");
- }
-
- @Test
- public void allow_HEAD_method() throws IOException, ServletException {
- assertThatMethodIsAllowed("HEAD");
- }
-
- @Test
- public void allow_PUT_method() throws IOException, ServletException {
- assertThatMethodIsAllowed("PUT");
- }
-
- @Test
- public void allow_POST_method() throws IOException, ServletException {
- assertThatMethodIsAllowed("POST");
- }
-
- private void assertThatMethodIsAllowed(String httpMethod) throws IOException, ServletException {
- HttpServletRequest request = newRequest(httpMethod, "/");
- underTest.doFilter(request, response, chain);
- verify(response, never()).setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
- verify(chain).doFilter(request, response);
- }
-
- @Test
- public void deny_OPTIONS_method() throws IOException, ServletException {
- assertThatMethodIsDenied("OPTIONS");
- }
-
- @Test
- public void deny_TRACE_method() throws IOException, ServletException {
- assertThatMethodIsDenied("TRACE");
- }
-
- private void assertThatMethodIsDenied(String httpMethod) throws IOException, ServletException {
- underTest.doFilter(newRequest(httpMethod, "/"), response, chain);
- verify(response).setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
- }
-
- @Test
- public void set_security_headers() throws Exception {
- HttpServletRequest request = newRequest("GET", "/");
-
- underTest.doFilter(request, response, chain);
-
- verify(response).addHeader("X-Frame-Options", "SAMEORIGIN");
- verify(response).addHeader("X-XSS-Protection", "1; mode=block");
- verify(response).addHeader("X-Content-Type-Options", "nosniff");
- }
-
- @Test
- public void do_not_set_frame_protection_on_integration_resources() throws Exception {
- HttpServletRequest request = newRequest("GET", "/integration/vsts/index.html");
-
- underTest.doFilter(request, response, chain);
-
- verify(response, never()).addHeader(eq("X-Frame-Options"), anyString());
- verify(response).addHeader("X-XSS-Protection", "1; mode=block");
- verify(response).addHeader("X-Content-Type-Options", "nosniff");
- }
-
- @Test
- public void do_not_set_frame_protection_on_integration_resources_with_context() throws Exception {
- HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getMethod()).thenReturn("GET");
- when(request.getRequestURI()).thenReturn("/sonarqube/integration/vsts/index.html");
- when(request.getContextPath()).thenReturn("/sonarqube");
-
- underTest.doFilter(request, response, chain);
-
- verify(response, never()).addHeader(eq("X-Frame-Options"), anyString());
- verify(response).addHeader("X-XSS-Protection", "1; mode=block");
- verify(response).addHeader("X-Content-Type-Options", "nosniff");
- }
-
- private static HttpServletRequest newRequest(String httpMethod, String path) {
- HttpServletRequest req = mock(HttpServletRequest.class);
- when(req.getMethod()).thenReturn(httpMethod);
- when(req.getRequestURI()).thenReturn(path);
- when(req.getContextPath()).thenReturn("");
- return req;
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/web/WebPagesCacheTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/web/WebPagesCacheTest.java
deleted file mode 100644
index 5551c269c15..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/web/WebPagesCacheTest.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * 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.web;
-
-import java.io.InputStream;
-import javax.servlet.ServletContext;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.stubbing.Answer;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.server.platform.OfficialDistribution;
-import org.sonar.server.platform.Platform;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.commons.io.IOUtils.toInputStream;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.sonar.server.platform.Platform.Status.BOOTING;
-import static org.sonar.server.platform.Platform.Status.STARTING;
-import static org.sonar.server.platform.Platform.Status.UP;
-
-public class WebPagesCacheTest {
-
- private static final String TEST_CONTEXT = "/sonarqube";
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private ServletContext servletContext = mock(ServletContext.class);
-
- private OfficialDistribution officialDistribution = mock(OfficialDistribution.class);
- private Platform platform = mock(Platform.class);
- private MapSettings mapSettings = new MapSettings();
-
- private WebPagesCache underTest = new WebPagesCache(platform, mapSettings.asConfig(), officialDistribution);
-
- @Before
- public void setUp() throws Exception {
- 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%]",
- UTF_8));
- when(servletContext.getResourceAsStream("/integration/vsts/index.html"))
- .thenAnswer((Answer<InputStream>) invocationOnMock -> toInputStream("Content of vsts index.html with context [%WEB_CONTEXT%]", UTF_8));
- }
-
- @Test
- public void check_paths() {
- doInit();
- when(platform.status()).thenReturn(UP);
-
- assertThat(underTest.getContent("/foo")).contains(TEST_CONTEXT).contains("default");
- assertThat(underTest.getContent("/foo.html")).contains(TEST_CONTEXT).contains("default");
- assertThat(underTest.getContent("/index")).contains(TEST_CONTEXT).contains("default");
- assertThat(underTest.getContent("/index.html")).contains(TEST_CONTEXT).contains("default");
- assertThat(underTest.getContent("/integration/vsts/index.html")).contains(TEST_CONTEXT).contains("vsts");
- }
-
- @Test
- public void contains_web_context() {
- doInit();
-
- assertThat(underTest.getContent("/foo"))
- .contains(TEST_CONTEXT);
- }
-
- @Test
- public void status_is_starting() {
- doInit();
- when(platform.status()).thenReturn(STARTING);
-
- assertThat(underTest.getContent("/foo"))
- .contains(STARTING.name());
- }
-
- @Test
- public void status_is_up() {
- doInit();
- when(platform.status()).thenReturn(UP);
-
- assertThat(underTest.getContent("/foo"))
- .contains(UP.name());
- }
-
- @Test
- public void no_sonarcloud_setting() {
- doInit();
-
- assertThat(underTest.getContent("/foo"))
- .contains("SonarQube");
- }
-
- @Test
- public void sonarcloud_setting_is_false() {
- mapSettings.setProperty("sonar.sonarcloud.enabled", false);
- doInit();
-
- assertThat(underTest.getContent("/foo"))
- .contains("SonarQube");
- }
-
- @Test
- public void sonarcloud_setting_is_true() {
- mapSettings.setProperty("sonar.sonarcloud.enabled", true);
- doInit();
-
- assertThat(underTest.getContent("/foo"))
- .contains("SonarCloud");
- }
-
- @Test
- public void content_is_updated_when_status_has_changed() {
- doInit();
- when(platform.status()).thenReturn(STARTING);
- assertThat(underTest.getContent("/foo"))
- .contains(STARTING.name());
-
- when(platform.status()).thenReturn(UP);
- assertThat(underTest.getContent("/foo"))
- .contains(UP.name());
- }
-
- @Test
- public void content_is_not_updated_when_status_is_up() {
- doInit();
- when(platform.status()).thenReturn(UP);
- assertThat(underTest.getContent("/foo"))
- .contains(UP.name());
-
- when(platform.status()).thenReturn(STARTING);
- assertThat(underTest.getContent("/foo"))
- .contains(UP.name());
- }
-
- @Test
- public void fail_to_get_content_when_init_has_not_been_called() {
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("init has not been called");
-
- underTest.getContent("/foo");
- }
-
- private void doInit() {
- when(platform.status()).thenReturn(BOOTING);
- underTest.init(servletContext);
- }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/web/WebPagesFilterTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/web/WebPagesFilterTest.java
deleted file mode 100644
index d2949b6afc8..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/web/WebPagesFilterTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.web;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.WriteListener;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.RETURNS_MOCKS;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class WebPagesFilterTest {
-
- private static final String TEST_CONTEXT = "/sonarqube";
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private ServletContext servletContext = mock(ServletContext.class, RETURNS_MOCKS);
- private WebPagesCache webPagesCache = mock(WebPagesCache.class);
-
- private HttpServletRequest request = mock(HttpServletRequest.class);
- private HttpServletResponse response = mock(HttpServletResponse.class);
- private FilterChain chain = mock(FilterChain.class);
-
- private WebPagesFilter underTest = new WebPagesFilter(webPagesCache);
-
- @Before
- public void setUp() throws Exception {
- when(servletContext.getContextPath()).thenReturn(TEST_CONTEXT);
- }
-
- @Test
- public void return_web_page_content() throws Exception {
- String path = "/index.html";
- when(webPagesCache.getContent(path)).thenReturn("test");
- when(request.getRequestURI()).thenReturn(path);
- when(request.getContextPath()).thenReturn(TEST_CONTEXT);
- StringOutputStream outputStream = new StringOutputStream();
- when(response.getOutputStream()).thenReturn(outputStream);
-
- underTest.doFilter(request, response, chain);
-
- verify(response).setContentType("text/html");
- verify(response).setCharacterEncoding("utf-8");
- verify(response).setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
- assertThat(outputStream.toString()).isEqualTo("test");
- }
-
- @Test
- public void does_nothing_when_static_resource() throws Exception{
- when(request.getRequestURI()).thenReturn("/static");
- when(request.getContextPath()).thenReturn(TEST_CONTEXT);
-
- underTest.doFilter(request, response, chain);
-
- verify(chain).doFilter(request, response);
- verifyZeroInteractions(webPagesCache);
- }
-
- class StringOutputStream extends ServletOutputStream {
- private final StringBuilder buf = new StringBuilder();
-
- StringOutputStream() {
- }
-
- @Override
- public boolean isReady() {
- return false;
- }
-
- @Override
- public void setWriteListener(WriteListener listener) {
-
- }
-
- public void write(byte[] b) {
- this.buf.append(new String(b));
- }
-
- public void write(byte[] b, int off, int len) {
- this.buf.append(new String(b, off, len));
- }
-
- public void write(int b) {
- byte[] bytes = new byte[] {(byte) b};
- this.buf.append(new String(bytes));
- }
-
- public String toString() {
- return this.buf.toString();
- }
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/web/requestid/RequestIdFilterTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/web/requestid/RequestIdFilterTest.java
deleted file mode 100644
index b119cf59424..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/web/requestid/RequestIdFilterTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.web.requestid;
-
-import java.io.IOException;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.MDC;
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.server.platform.Platform;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.fail;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class RequestIdFilterTest {
- private Platform platform = mock(Platform.class);
- private RequestIdGenerator requestIdGenerator = mock(RequestIdGenerator.class);
- private ServletRequest servletRequest = mock(ServletRequest.class);
- private ServletResponse servletResponse = mock(ServletResponse.class);
- private FilterChain filterChain = mock(FilterChain.class);
- private RequestIdFilter underTest = new RequestIdFilter(platform);
-
- @Before
- public void setUp() throws Exception {
- ComponentContainer container = new ComponentContainer();
- container.add(requestIdGenerator);
- when(platform.getContainer()).thenReturn(container);
- }
-
- @Test
- public void filter_put_id_in_MDC_and_remove_it_after_chain_has_executed() throws IOException, ServletException {
- String requestId = "request id";
- when(requestIdGenerator.generate()).thenReturn(requestId);
- doAnswer(invocation -> assertThat(MDC.get("HTTP_REQUEST_ID")).isEqualTo(requestId))
- .when(filterChain)
- .doFilter(servletRequest, servletResponse);
-
- underTest.doFilter(servletRequest, servletResponse, filterChain);
-
- assertThat(MDC.get("HTTP_REQUEST_ID")).isNull();
- }
-
- @Test
- public void filter_put_id_in_MDC_and_remove_it_after_chain_throws_exception() throws IOException, ServletException {
- RuntimeException exception = new RuntimeException("Simulating chain failing");
- String requestId = "request id";
- when(requestIdGenerator.generate()).thenReturn(requestId);
- doAnswer(invocation -> {
- assertThat(MDC.get("HTTP_REQUEST_ID")).isEqualTo(requestId);
- throw exception;
- })
- .when(filterChain)
- .doFilter(servletRequest, servletResponse);
-
- try {
- underTest.doFilter(servletRequest, servletResponse, filterChain);
- fail("A runtime exception should have been raised");
- } catch (RuntimeException e) {
- assertThat(e).isEqualTo(exception);
- } finally {
- assertThat(MDC.get("HTTP_REQUEST_ID")).isNull();
- }
- }
-
- @Test
- public void filter_adds_requestId_to_request_passed_on_to_chain() throws IOException, ServletException {
- String requestId = "request id";
- when(requestIdGenerator.generate()).thenReturn(requestId);
-
- underTest.doFilter(servletRequest, servletResponse, filterChain);
-
- verify(servletRequest).setAttribute("ID", requestId);
- }
-
- @Test
- public void filter_does_not_fail_when_there_is_no_RequestIdGenerator_in_container() throws IOException, ServletException {
- Platform platform = mock(Platform.class);
- when(platform.getContainer()).thenReturn(new ComponentContainer());
- RequestIdFilter underTest = new RequestIdFilter(platform);
-
- underTest.doFilter(servletRequest, servletResponse, filterChain);
- }
-
- @Test
- public void filter_does_not_add_requestId_to_request_passed_on_to_chain_when_there_is_no_RequestIdGenerator_in_container() throws IOException, ServletException {
- Platform platform = mock(Platform.class);
- when(platform.getContainer()).thenReturn(new ComponentContainer());
- RequestIdFilter underTest = new RequestIdFilter(platform);
-
- underTest.doFilter(servletRequest, servletResponse, filterChain);
-
- verify(servletRequest, times(0)).setAttribute(anyString(), anyString());
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/StaticResourcesServletTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/StaticResourcesServletTest.java
deleted file mode 100644
index 84795711fb9..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/plugins/StaticResourcesServletTest.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * 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.plugins;
-
-import java.io.IOException;
-import java.io.InputStream;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import javax.servlet.http.HttpServletResponse;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
-import org.apache.catalina.connector.ClientAbortException;
-import org.apache.commons.io.IOUtils;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.utils.log.LogTester;
-import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.core.platform.PluginInfo;
-import org.sonar.core.platform.PluginRepository;
-import org.sonar.core.extension.CoreExtensionRepository;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class StaticResourcesServletTest {
-
- @Rule
- public LogTester logTester = new LogTester();
- private Server jetty;
-
- private PluginRepository pluginRepository = mock(PluginRepository.class);
- private CoreExtensionRepository coreExtensionRepository = mock(CoreExtensionRepository.class);
- private TestSystem system = new TestSystem(pluginRepository, coreExtensionRepository);
-
- @Before
- public void setUp() throws Exception {
- jetty = new Server(0);
- ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
- context.setContextPath("/");
- ServletHolder servletHolder = new ServletHolder(new StaticResourcesServlet(system));
- context.addServlet(servletHolder, "/static/*");
- jetty.setHandler(context);
- jetty.start();
- }
-
- @After
- public void tearDown() throws Exception {
- if (jetty != null) {
- jetty.stop();
- }
- }
-
- private Response call(String path) throws Exception {
- OkHttpClient client = new OkHttpClient();
- Request request = new Request.Builder()
- .url(jetty.getURI().resolve(path).toString())
- .build();
- return client.newCall(request).execute();
- }
-
- @Test
- public void return_content_if_exists_in_installed_plugin() throws Exception {
- system.pluginStream = IOUtils.toInputStream("bar");
- when(pluginRepository.hasPlugin("myplugin")).thenReturn(true);
-
- Response response = call("/static/myplugin/foo.txt");
-
- assertThat(response.isSuccessful()).isTrue();
- assertThat(response.body().string()).isEqualTo("bar");
- assertThat(system.pluginResource).isEqualTo("static/foo.txt");
- }
-
- @Test
- public void return_content_of_folder_of_installed_plugin() throws Exception {
- system.pluginStream = IOUtils.toInputStream("bar");
- when(pluginRepository.hasPlugin("myplugin")).thenReturn(true);
-
- Response response = call("/static/myplugin/foo/bar.txt");
-
- assertThat(response.isSuccessful()).isTrue();
- assertThat(response.body().string()).isEqualTo("bar");
- assertThat(system.pluginResource).isEqualTo("static/foo/bar.txt");
- }
-
- @Test
- public void return_content_of_folder_of_installed_core_extension() throws Exception {
- system.coreExtensionStream = IOUtils.toInputStream("bar");
- when(coreExtensionRepository.isInstalled("coreext")).thenReturn(true);
-
- Response response = call("/static/coreext/foo/bar.txt");
-
- assertThat(response.isSuccessful()).isTrue();
- assertThat(response.body().string()).isEqualTo("bar");
- assertThat(system.coreExtensionResource).isEqualTo("static/foo/bar.txt");
- }
-
- @Test
- public void return_content_of_folder_of_installed_core_extension_over_installed_plugin_in_case_of_key_conflict() throws Exception {
- system.coreExtensionStream = IOUtils.toInputStream("bar of plugin");
- when(coreExtensionRepository.isInstalled("samekey")).thenReturn(true);
- system.coreExtensionStream = IOUtils.toInputStream("bar of core extension");
- when(coreExtensionRepository.isInstalled("samekey")).thenReturn(true);
-
- Response response = call("/static/samekey/foo/bar.txt");
-
- assertThat(response.isSuccessful()).isTrue();
- assertThat(response.body().string()).isEqualTo("bar of core extension");
- assertThat(system.pluginResource).isNull();
- assertThat(system.coreExtensionResource).isEqualTo("static/foo/bar.txt");
- }
-
- @Test
- public void mime_type_is_set_on_response() throws Exception {
- system.pluginStream = IOUtils.toInputStream("bar");
- when(pluginRepository.hasPlugin("myplugin")).thenReturn(true);
-
- Response response = call("/static/myplugin/foo.css");
-
- assertThat(response.header("Content-Type")).isEqualTo("text/css");
- assertThat(response.body().string()).isEqualTo("bar");
- }
-
- @Test
- public void return_404_if_resource_not_found_in_installed_plugin() throws Exception {
- system.pluginStream = null;
- when(pluginRepository.hasPlugin("myplugin")).thenReturn(true);
-
- Response response = call("/static/myplugin/foo.css");
-
- assertThat(response.code()).isEqualTo(404);
- assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty();
- assertThat(logTester.logs(LoggerLevel.WARN)).isEmpty();
- }
-
- @Test
- public void return_404_if_plugin_does_not_exist() throws Exception {
- system.pluginStream = null;
- when(pluginRepository.hasPlugin("myplugin")).thenReturn(false);
-
- Response response = call("/static/myplugin/foo.css");
-
- assertThat(response.code()).isEqualTo(404);
- assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty();
- assertThat(logTester.logs(LoggerLevel.WARN)).isEmpty();
- }
-
- @Test
- public void return_resource_if_exists_in_requested_plugin() throws Exception {
- system.pluginStream = IOUtils.toInputStream("bar");
- when(pluginRepository.hasPlugin("myplugin")).thenReturn(true);
- when(pluginRepository.getPluginInfo("myplugin")).thenReturn(new PluginInfo("myplugin"));
-
- Response response = call("/static/myplugin/foo.css");
-
- assertThat(response.isSuccessful()).isTrue();
- assertThat(response.body().string()).isEqualTo("bar");
- assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty();
- assertThat(logTester.logs(LoggerLevel.WARN)).isEmpty();
- }
-
- @Test
- public void do_not_fail_nor_log_ERROR_when_response_is_already_committed_and_plugin_does_not_exist() throws Exception {
- system.pluginStream = null;
- system.isCommitted = true;
- when(pluginRepository.hasPlugin("myplugin")).thenReturn(false);
-
- Response response = call("/static/myplugin/foo.css");
-
- assertThat(response.code()).isEqualTo(200);
- assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty();
- assertThat(logTester.logs(LoggerLevel.TRACE)).contains("Response is committed. Cannot send error response code 404");
- }
-
- @Test
- public void do_not_fail_nor_log_ERROR_when_sendError_throws_IOException_and_plugin_does_not_exist() throws Exception {
- system.sendErrorException = new IOException("Simulating sendError throwing IOException");
- when(pluginRepository.hasPlugin("myplugin")).thenReturn(false);
-
- Response response = call("/static/myplugin/foo.css");
-
- assertThat(response.code()).isEqualTo(200);
- assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty();
- assertThat(logTester.logs(LoggerLevel.TRACE)).contains("Failed to send error code 404: java.io.IOException: Simulating sendError throwing IOException");
- }
-
- @Test
- public void do_not_fail_nor_log_ERROR_when_response_is_already_committed_and_resource_does_not_exist_in_installed_plugin() throws Exception {
- system.isCommitted = true;
- system.pluginStream = null;
- when(pluginRepository.hasPlugin("myplugin")).thenReturn(true);
-
- Response response = call("/static/myplugin/foo.css");
-
- assertThat(response.code()).isEqualTo(200);
- assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty();
- assertThat(logTester.logs(LoggerLevel.TRACE)).contains("Response is committed. Cannot send error response code 404");
- }
-
- @Test
- public void do_not_fail_nor_log_not_attempt_to_send_error_if_ClientAbortException_is_raised() throws Exception {
- system.pluginStreamException = new ClientAbortException("Simulating ClientAbortException");
- when(pluginRepository.hasPlugin("myplugin")).thenReturn(true);
-
- Response response = call("/static/myplugin/foo.css");
-
- assertThat(response.code()).isEqualTo(200);
- assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty();
- assertThat(logTester.logs(LoggerLevel.TRACE)).contains(
- "Client canceled loading resource [static/foo.css] from plugin [myplugin]: org.apache.catalina.connector.ClientAbortException: Simulating ClientAbortException");
- }
-
- @Test
- public void do_not_fail_when_response_is_committed_after_other_error() throws Exception {
- system.isCommitted = true;
- system.pluginStreamException = new RuntimeException("Simulating a error");
- when(pluginRepository.hasPlugin("myplugin")).thenReturn(true);
-
- Response response = call("/static/myplugin/foo.css");
-
- assertThat(response.code()).isEqualTo(200);
- assertThat(logTester.logs(LoggerLevel.ERROR)).contains("Unable to load resource [static/foo.css] from plugin [myplugin]");
- }
-
- private static class TestSystem extends StaticResourcesServlet.System {
- private final PluginRepository pluginRepository;
- private final CoreExtensionRepository coreExtensionRepository;
- @Nullable
- private InputStream pluginStream;
- private Exception pluginStreamException = null;
- @Nullable
- private String pluginResource;
- @Nullable
- private InputStream coreExtensionStream;
- private Exception coreExtensionStreamException = null;
- private String coreExtensionResource;
- private boolean isCommitted = false;
- private IOException sendErrorException = null;
-
- TestSystem(PluginRepository pluginRepository, CoreExtensionRepository coreExtensionRepository) {
- this.pluginRepository = pluginRepository;
- this.coreExtensionRepository = coreExtensionRepository;
- }
-
- @Override
- PluginRepository getPluginRepository() {
- return pluginRepository;
- }
-
- @Override
- CoreExtensionRepository getCoreExtensionRepository() {
- return this.coreExtensionRepository;
- }
-
- @CheckForNull
- @Override
- InputStream openPluginResourceStream(String pluginKey, String resource, PluginRepository pluginRepository) throws Exception {
- pluginResource = resource;
- if (pluginStreamException != null) {
- throw pluginStreamException;
- }
- return pluginStream;
- }
-
- @CheckForNull
- @Override
- InputStream openCoreExtensionResourceStream(String resource) throws Exception {
- coreExtensionResource = resource;
- if (coreExtensionStreamException != null) {
- throw coreExtensionStreamException;
- }
- return coreExtensionStream;
- }
-
- @Override
- boolean isCommitted(HttpServletResponse response) {
- return isCommitted;
- }
-
- @Override
- void sendError(HttpServletResponse response, int error) throws IOException {
- if (sendErrorException != null) {
- throw sendErrorException;
- } else {
- super.sendError(response, error);
- }
- }
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/startup/RegisterServletFiltersTest.java b/server/sonar-server/src/test/java/org/sonar/server/startup/RegisterServletFiltersTest.java
deleted file mode 100644
index 0543dcdf32b..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/startup/RegisterServletFiltersTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.startup;
-
-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;
-import static org.mockito.Mockito.verify;
-
-public class RegisterServletFiltersTest {
- @Test
- public void should_not_fail_if_master_filter_is_not_up() throws ServletException {
- MasterServletFilter.INSTANCE = null;
- new RegisterServletFilters(new ServletFilter[2]).start();
- }
-
- @Test
- public void should_register_filters_if_master_filter_is_up() throws ServletException {
- MasterServletFilter.INSTANCE = mock(MasterServletFilter.class);
- new RegisterServletFilters(new ServletFilter[2]).start();
-
- verify(MasterServletFilter.INSTANCE).initFilters(anyList());
- }
-
- @Test
- public void filters_should_be_optional() throws ServletException {
- MasterServletFilter.INSTANCE = mock(MasterServletFilter.class);
- new RegisterServletFilters().start();
- // do not fail
- verify(MasterServletFilter.INSTANCE).initFilters(anyList());
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/UserSessionFilterTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/UserSessionFilterTest.java
deleted file mode 100644
index 3465fba2a10..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/user/UserSessionFilterTest.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * 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.user;
-
-import java.io.IOException;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.InOrder;
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.db.DBSessions;
-import org.sonar.server.authentication.UserSessionInitializer;
-import org.sonar.server.organization.DefaultOrganizationCache;
-import org.sonar.server.platform.Platform;
-import org.sonar.server.setting.ThreadLocalSettings;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.fail;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class UserSessionFilterTest {
-
- private UserSessionInitializer userSessionInitializer = mock(UserSessionInitializer.class);
- private ComponentContainer container = new ComponentContainer();
- private Platform platform = mock(Platform.class);
- private HttpServletRequest request = mock(HttpServletRequest.class);
- private HttpServletResponse response = mock(HttpServletResponse.class);
- private FilterChain chain = mock(FilterChain.class);
- private DBSessions dbSessions = mock(DBSessions.class);
- private ThreadLocalSettings settings = mock(ThreadLocalSettings.class);
- private DefaultOrganizationCache defaultOrganizationCache = mock(DefaultOrganizationCache.class);
- private UserSessionFilter underTest = new UserSessionFilter(platform);
-
- @Before
- public void setUp() {
- container.add(dbSessions, settings, defaultOrganizationCache);
- when(platform.getContainer()).thenReturn(container);
- }
-
- @Test
- public void cleanup_user_session_after_request_handling() throws IOException, ServletException {
- mockUserSessionInitializer(true);
-
- underTest.doFilter(request, response, chain);
-
- verify(chain).doFilter(request, response);
- verify(userSessionInitializer).initUserSession(request, response);
- }
-
- @Test
- public void stop_when_user_session_return_false() throws Exception {
- mockUserSessionInitializer(false);
-
- underTest.doFilter(request, response, chain);
-
- verify(chain, never()).doFilter(request, response);
- verify(userSessionInitializer).initUserSession(request, response);
- }
-
- @Test
- public void does_nothing_when_not_initialized() throws Exception {
- underTest.doFilter(request, response, chain);
-
- verify(chain).doFilter(request, response);
- verifyZeroInteractions(userSessionInitializer);
- }
-
- @Test
- public void doFilter_loads_and_unloads_settings() throws Exception {
- underTest.doFilter(request, response, chain);
-
- InOrder inOrder = inOrder(settings);
- inOrder.verify(settings).load();
- inOrder.verify(settings).unload();
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void doFilter_unloads_Settings_even_if_chain_throws_exception() throws Exception {
- RuntimeException thrown = mockChainDoFilterError();
-
- try {
- underTest.doFilter(request, response, chain);
- fail("A RuntimeException should have been thrown");
- } catch (RuntimeException e) {
- assertThat(e).isSameAs(thrown);
- verify(settings).unload();
- }
- }
-
- @Test
- public void doFilter_enables_and_disables_caching_in_DbSessions() throws Exception {
- underTest.doFilter(request, response, chain);
-
- InOrder inOrder = inOrder(dbSessions);
- inOrder.verify(dbSessions).enableCaching();
- inOrder.verify(dbSessions).disableCaching();
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void doFilter_disables_caching_in_DbSessions_even_if_chain_throws_exception() throws Exception {
- RuntimeException thrown = mockChainDoFilterError();
-
- try {
- underTest.doFilter(request, response, chain);
- fail("A RuntimeException should have been thrown");
- } catch (RuntimeException e) {
- assertThat(e).isSameAs(thrown);
- verify(dbSessions).disableCaching();
- }
- }
-
- @Test
- public void doFilter_unloads_Settings_even_if_DefaultOrganizationCache_unload_fails() throws Exception {
- RuntimeException thrown = new RuntimeException("Faking DefaultOrganizationCache.unload failing");
- doThrow(thrown)
- .when(defaultOrganizationCache)
- .unload();
-
- try {
- underTest.doFilter(request, response, chain);
- fail("A RuntimeException should have been thrown");
- } catch (RuntimeException e) {
- assertThat(e).isSameAs(thrown);
- verify(settings).unload();
- }
- }
-
- @Test
- public void doFilter_unloads_Settings_even_if_UserSessionInitializer_removeUserSession_fails() throws Exception {
- RuntimeException thrown = mockUserSessionInitializerRemoveUserSessionFailing();
-
- try {
- underTest.doFilter(request, response, chain);
- fail("A RuntimeException should have been thrown");
- } catch (RuntimeException e) {
- assertThat(e).isSameAs(thrown);
- verify(settings).unload();
- }
- }
-
- @Test
- public void doFilter_loads_and_unloads_DefaultOrganizationCache() throws Exception {
- underTest.doFilter(request, response, chain);
-
- InOrder inOrder = inOrder(defaultOrganizationCache);
- inOrder.verify(defaultOrganizationCache).load();
- inOrder.verify(defaultOrganizationCache).unload();
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void doFilter_unloads_DefaultOrganizationCache_even_if_chain_throws_exception() throws Exception {
- RuntimeException thrown = mockChainDoFilterError();
-
- try {
- underTest.doFilter(request, response, chain);
- fail("A RuntimeException should have been thrown");
- } catch (RuntimeException e) {
- assertThat(e).isSameAs(thrown);
- verify(defaultOrganizationCache).unload();
- }
- }
-
- @Test
- public void doFilter_unloads_DefaultOrganizationCache_even_if_Settings_unload_fails() throws Exception {
- RuntimeException thrown = new RuntimeException("Faking Settings.unload failing");
- doThrow(thrown)
- .when(settings)
- .unload();
-
- try {
- underTest.doFilter(request, response, chain);
- fail("A RuntimeException should have been thrown");
- } catch (RuntimeException e) {
- assertThat(e).isSameAs(thrown);
- verify(defaultOrganizationCache).unload();
- }
- }
-
- @Test
- public void doFilter_unloads_DefaultOrganizationCache_even_if_UserSessionInitializer_removeUserSession_fails() throws Exception {
- RuntimeException thrown = mockUserSessionInitializerRemoveUserSessionFailing();
-
- try {
- underTest.doFilter(request, response, chain);
- fail("A RuntimeException should have been thrown");
- } catch (RuntimeException e) {
- assertThat(e).isSameAs(thrown);
- verify(defaultOrganizationCache).unload();
- }
- }
-
- @Test
- public void just_for_fun_and_coverage() throws ServletException {
- UserSessionFilter filter = new UserSessionFilter();
- filter.init(mock(FilterConfig.class));
- filter.destroy();
- // do not fail
- }
-
- private void mockUserSessionInitializer(boolean value) {
- container.add(userSessionInitializer);
- when(userSessionInitializer.initUserSession(request, response)).thenReturn(value);
- }
-
- private RuntimeException mockUserSessionInitializerRemoveUserSessionFailing() {
- container.add(userSessionInitializer);
- RuntimeException thrown = new RuntimeException("Faking UserSessionInitializer.removeUserSession failing");
- doThrow(thrown)
- .when(userSessionInitializer)
- .removeUserSession();
- return thrown;
- }
-
- private RuntimeException mockChainDoFilterError() throws IOException, ServletException {
- RuntimeException thrown = new RuntimeException("Faking chain.doFilter failing");
- doThrow(thrown)
- .when(chain)
- .doFilter(request, response);
- return thrown;
- }
-}
diff --git a/server/sonar-server/src/test/resources/static/foo.txt b/server/sonar-server/src/test/resources/static/foo.txt
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/server/sonar-server/src/test/resources/static/foo.txt
+++ /dev/null