aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-application
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2013-10-14 01:44:41 +0200
committerSimon Brandhof <simon.brandhof@gmail.com>2013-10-14 01:44:41 +0200
commit2e9a7b616293fbaec0b8715ecd4e781ff04587d7 (patch)
treea264be4744e0bb73cfd471ecc0520a4064994fa9 /sonar-application
parent275da1c743917341256322a09a3172a2ccf04ef3 (diff)
downloadsonarqube-2e9a7b616293fbaec0b8715ecd4e781ff04587d7.tar.gz
sonarqube-2e9a7b616293fbaec0b8715ecd4e781ff04587d7.zip
SONAR-4742 Add support of AJP 1.3 protocol
Diffstat (limited to 'sonar-application')
-rw-r--r--sonar-application/src/main/assembly/conf/sonar.properties17
-rw-r--r--sonar-application/src/main/java/org/sonar/application/Connectors.java66
-rw-r--r--sonar-application/src/test/java/org/sonar/application/ConnectorsTest.java92
3 files changed, 128 insertions, 47 deletions
diff --git a/sonar-application/src/main/assembly/conf/sonar.properties b/sonar-application/src/main/assembly/conf/sonar.properties
index 1ef1d031316..d32af10ba48 100644
--- a/sonar-application/src/main/assembly/conf/sonar.properties
+++ b/sonar-application/src/main/assembly/conf/sonar.properties
@@ -93,13 +93,14 @@ sonar.jdbc.timeBetweenEvictionRunsMillis=30000
# The default value is root context (empty value).
#sonar.web.context=
-# TCP port for incoming HTTP connections
-#sonar.web.http.enable=true
+# TCP port for incoming HTTP connections. Disabled when value is -1.
#sonar.web.port=9000
-# TCP port for incoming HTTPS connections. Disabled by default.
-#sonar.web.https.enable=false
-#sonar.web.https.port=9443
+# TCP port for incoming HTTPS connections. Disabled when value is -1 (default).
+#sonar.web.https.port=-1
+
+# TCP port for AJP 1.3 protocol. Disabled when value is -1 (default).
+#sonar.web.ajp.port=-1
# HTTPS - the alias used to for the server certificate in the keystore.
# If not specified the first key read in the keystore is used.
@@ -133,16 +134,20 @@ sonar.jdbc.timeBetweenEvictionRunsMillis=30000
# based on the sonar.web.connections.acceptCount property. The default value is 50 for each
# enabled connector.
#sonar.web.http.maxThreads=50
+#sonar.web.ajp.maxThreads=50
#sonar.web.https.maxThreads=50
-# The minimum number of threads always kept running. If not specified, the default of 5 is used.
+# The minimum number of threads always kept running. The default value is 5 for each
+# enabled connector.
#sonar.web.http.minThreads=5
+#sonar.web.ajp.minThreads=5
#sonar.web.https.minThreads=5
# The maximum queue length for incoming connection requests when all possible request processing
# threads are in use. Any requests received when the queue is full will be refused.
# The default value is 25 for each enabled connector.
#sonar.web.http.acceptCount=25
+#sonar.web.ajp.acceptCount=25
#sonar.web.https.acceptCount=25
diff --git a/sonar-application/src/main/java/org/sonar/application/Connectors.java b/sonar-application/src/main/java/org/sonar/application/Connectors.java
index 77609d1820d..a61ab9ce445 100644
--- a/sonar-application/src/main/java/org/sonar/application/Connectors.java
+++ b/sonar-application/src/main/java/org/sonar/application/Connectors.java
@@ -24,9 +24,17 @@ import org.apache.catalina.startup.Tomcat;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
class Connectors {
+ private static final int DISABLED_PORT = -1;
+ static final String HTTP_PROTOCOL = "HTTP/1.1";
+ static final String AJP_PROTOCOL = "AJP/1.3";
+
static void configure(Tomcat tomcat, Props props) {
tomcat.getServer().setAddress(props.of("sonar.web.host", "0.0.0.0"));
configureShutdown(tomcat, props);
@@ -34,23 +42,17 @@ class Connectors {
}
private static void configureConnectors(Tomcat tomcat, Props props) {
- Connector http = newHttpConnector(props);
- Connector https = newHttpsConnector(props);
-
- if (http == null) {
- if (https == null) {
- throw new IllegalStateException("Both HTTP and HTTPS connectors are disabled");
- }
- // Enable only HTTPS
- tomcat.setConnector(https);
- tomcat.getService().addConnector(https);
- } else {
- // Both HTTP and HTTPS are enabled
- tomcat.setConnector(http);
- tomcat.getService().addConnector(http);
- if (https != null) {
- tomcat.getService().addConnector(https);
- }
+ List<Connector> connectors = new ArrayList<Connector>();
+ connectors.addAll(Arrays.asList(newHttpConnector(props), newAjpConnector(props), newHttpsConnector(props)));
+ connectors.removeAll(Collections.singleton(null));
+
+ if (connectors.isEmpty()) {
+ throw new IllegalStateException("HTTP connectors are disabled");
+ }
+
+ tomcat.setConnector(connectors.get(0));
+ for (Connector connector : connectors) {
+ tomcat.getService().addConnector(connector);
}
}
@@ -67,10 +69,10 @@ class Connectors {
@Nullable
private static Connector newHttpConnector(Props props) {
Connector connector = null;
- if (props.booleanOf("sonar.web.http.enable", true)) {
- connector = newConnector(props, "http");
- // Not named "sonar.web.http.port" to keep backward-compatibility
- int port = props.intOf("sonar.web.port", 9000);
+ // Not named "sonar.web.http.port" to keep backward-compatibility
+ int port = props.intOf("sonar.web.port", 9000);
+ if (port > DISABLED_PORT) {
+ connector = newConnector(props, HTTP_PROTOCOL, "http");
connector.setPort(port);
info("HTTP connector is enabled on port " + port);
}
@@ -78,11 +80,23 @@ class Connectors {
}
@Nullable
+ private static Connector newAjpConnector(Props props) {
+ Connector connector = null;
+ int port = props.intOf("sonar.web.ajp.port", DISABLED_PORT);
+ if (port > DISABLED_PORT) {
+ connector = newConnector(props, AJP_PROTOCOL, "ajp");
+ connector.setPort(port);
+ info("AJP connector is enabled on port " + port);
+ }
+ return connector;
+ }
+
+ @Nullable
private static Connector newHttpsConnector(Props props) {
Connector connector = null;
- if (props.booleanOf("sonar.web.https.enable")) {
- connector = newConnector(props, "https");
- int port = props.intOf("sonar.web.https.port", 9443);
+ int port = props.intOf("sonar.web.https.port", DISABLED_PORT);
+ if (port > DISABLED_PORT) {
+ connector = newConnector(props, HTTP_PROTOCOL, "https");
connector.setPort(port);
connector.setSecure(true);
connector.setScheme("https");
@@ -101,8 +115,8 @@ class Connectors {
return connector;
}
- private static Connector newConnector(Props props, String scheme) {
- Connector connector = new Connector("HTTP/1.1");
+ private static Connector newConnector(Props props, String protocol, String scheme) {
+ Connector connector = new Connector(protocol);
connector.setURIEncoding("UTF-8");
configurePool(props, connector, scheme);
configureCompression(connector);
diff --git a/sonar-application/src/test/java/org/sonar/application/ConnectorsTest.java b/sonar-application/src/test/java/org/sonar/application/ConnectorsTest.java
index c1594b2c46a..823bc4f3b35 100644
--- a/sonar-application/src/test/java/org/sonar/application/ConnectorsTest.java
+++ b/sonar-application/src/test/java/org/sonar/application/ConnectorsTest.java
@@ -69,25 +69,62 @@ public class ConnectorsTest {
}
@Test
- public void fail_if_both_http_and_https_are_disabled() {
+ public void different_thread_pools_for_connectors() throws Exception {
Properties p = new Properties();
- p.setProperty("sonar.web.http.enable", "false");
- p.setProperty("sonar.web.https.enable", "false");
+ p.setProperty("sonar.web.port", "9000");
+ p.setProperty("sonar.web.http.minThreads", "2");
+ p.setProperty("sonar.web.ajp.port", "9010");
+ p.setProperty("sonar.web.ajp.minThreads", "4");
+ p.setProperty("sonar.web.https.port", "9443");
+ p.setProperty("sonar.web.https.minThreads", "5");
+ Props props = new Props(p);
+
+ Connectors.configure(tomcat, props);
+
+ verify(tomcat.getService()).addConnector(argThat(new ArgumentMatcher<Connector>() {
+ @Override
+ public boolean matches(Object o) {
+ Connector c = (Connector) o;
+ return c.getPort() == 9000 && c.getProperty("minSpareThreads").equals(2);
+ }
+ }));
+ verify(tomcat.getService()).addConnector(argThat(new ArgumentMatcher<Connector>() {
+ @Override
+ public boolean matches(Object o) {
+ Connector c = (Connector) o;
+ return c.getPort() == 9010 && c.getProperty("minSpareThreads").equals(4);
+ }
+ }));
+ verify(tomcat.getService()).addConnector(argThat(new ArgumentMatcher<Connector>() {
+ @Override
+ public boolean matches(Object o) {
+ Connector c = (Connector) o;
+ return c.getPort() == 9443 && c.getProperty("minSpareThreads").equals(5);
+ }
+ }));
+ }
+
+ @Test
+ public void fail_if_http_connectors_are_disabled() {
+ Properties p = new Properties();
+ p.setProperty("sonar.web.port", "-1");
+ p.setProperty("sonar.web.https.port", "-1");
Props props = new Props(p);
try {
Connectors.configure(tomcat, props);
fail();
} catch (IllegalStateException e) {
- assertThat(e.getMessage()).isEqualTo("Both HTTP and HTTPS connectors are disabled");
+ assertThat(e.getMessage()).isEqualTo("HTTP connectors are disabled");
}
}
@Test
public void only_https_is_enabled() {
Properties p = new Properties();
- p.setProperty("sonar.web.http.enable", "false");
- p.setProperty("sonar.web.https.enable", "true");
+ p.setProperty("sonar.web.port", "-1");
+ p.setProperty("sonar.web.ajp.port", "-1");
+ p.setProperty("sonar.web.https.port", "9443");
Props props = new Props(p);
Connectors.configure(tomcat, props);
@@ -95,17 +132,18 @@ public class ConnectorsTest {
verify(tomcat).setConnector(argThat(new ArgumentMatcher<Connector>() {
@Override
public boolean matches(Object o) {
- Connector c = (Connector)o;
- return c.getScheme().equals("https") && c.getPort()==9443;
+ Connector c = (Connector) o;
+ return c.getScheme().equals("https") && c.getPort() == 9443;
}
}));
}
@Test
- public void both_http_and_https_are_enabled() {
+ public void all_connectors_are_enabled() {
Properties p = new Properties();
- p.setProperty("sonar.web.http.enable", "true");
- p.setProperty("sonar.web.https.enable", "true");
+ p.setProperty("sonar.web.port", "9000");
+ p.setProperty("sonar.web.ajp.port", "9010");
+ p.setProperty("sonar.web.https.port", "9443");
Props props = new Props(p);
Connectors.configure(tomcat, props);
@@ -113,15 +151,39 @@ public class ConnectorsTest {
verify(tomcat.getService()).addConnector(argThat(new ArgumentMatcher<Connector>() {
@Override
public boolean matches(Object o) {
- Connector c = (Connector)o;
- return c.getScheme().equals("http") && c.getPort()==9000;
+ Connector c = (Connector) o;
+ return c.getScheme().equals("http") && c.getPort() == 9000 && c.getProtocol().equals(Connectors.HTTP_PROTOCOL);
}
}));
verify(tomcat.getService()).addConnector(argThat(new ArgumentMatcher<Connector>() {
@Override
public boolean matches(Object o) {
- Connector c = (Connector)o;
- return c.getScheme().equals("https") && c.getPort()==9443;
+ Connector c = (Connector) o;
+ return c.getScheme().equals("http") && c.getPort() == 9010 && c.getProtocol().equals(Connectors.AJP_PROTOCOL);
+ }
+ }));
+ verify(tomcat.getService()).addConnector(argThat(new ArgumentMatcher<Connector>() {
+ @Override
+ public boolean matches(Object o) {
+ Connector c = (Connector) o;
+ return c.getScheme().equals("https") && c.getPort() == 9443 && c.getProtocol().equals(Connectors.HTTP_PROTOCOL);
+ }
+ }));
+ }
+
+ @Test
+ public void ajp_connector_is_enabled() {
+ Properties p = new Properties();
+ p.setProperty("sonar.web.ajp.port", "9010");
+ Props props = new Props(p);
+
+ Connectors.configure(tomcat, props);
+
+ verify(tomcat.getService()).addConnector(argThat(new ArgumentMatcher<Connector>() {
+ @Override
+ public boolean matches(Object o) {
+ Connector c = (Connector) o;
+ return c.getScheme().equals("http") && c.getPort() == 9010 && c.getProtocol().equals(Connectors.AJP_PROTOCOL);
}
}));
}