diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2013-10-14 01:44:41 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2013-10-14 01:44:41 +0200 |
commit | 2e9a7b616293fbaec0b8715ecd4e781ff04587d7 (patch) | |
tree | a264be4744e0bb73cfd471ecc0520a4064994fa9 /sonar-application | |
parent | 275da1c743917341256322a09a3172a2ccf04ef3 (diff) | |
download | sonarqube-2e9a7b616293fbaec0b8715ecd4e781ff04587d7.tar.gz sonarqube-2e9a7b616293fbaec0b8715ecd4e781ff04587d7.zip |
SONAR-4742 Add support of AJP 1.3 protocol
Diffstat (limited to 'sonar-application')
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); } })); } |