import java.util.Map; | import java.util.Map; | ||||
import java.util.Optional; | import java.util.Optional; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
import org.sonar.api.internal.MetadataLoader; | |||||
import org.sonar.api.utils.Version; | |||||
import org.sonar.application.es.EsInstallation; | import org.sonar.application.es.EsInstallation; | ||||
import org.sonar.application.es.EsLogging; | import org.sonar.application.es.EsLogging; | ||||
import org.sonar.application.es.EsSettings; | import org.sonar.application.es.EsSettings; | ||||
import org.sonar.process.Props; | import org.sonar.process.Props; | ||||
import org.sonar.process.System2; | import org.sonar.process.System2; | ||||
import static org.sonar.process.ProcessProperties.Property.WEB_GRACEFUL_STOP_TIMEOUT; | |||||
import static org.sonar.process.ProcessProperties.parseTimeoutMs; | |||||
import static org.sonar.process.ProcessProperties.Property.CE_GRACEFUL_STOP_TIMEOUT; | import static org.sonar.process.ProcessProperties.Property.CE_GRACEFUL_STOP_TIMEOUT; | ||||
import static org.sonar.process.ProcessProperties.Property.CE_JAVA_ADDITIONAL_OPTS; | import static org.sonar.process.ProcessProperties.Property.CE_JAVA_ADDITIONAL_OPTS; | ||||
import static org.sonar.process.ProcessProperties.Property.CE_JAVA_OPTS; | import static org.sonar.process.ProcessProperties.Property.CE_JAVA_OPTS; | ||||
import static org.sonar.process.ProcessProperties.Property.SEARCH_JAVA_OPTS; | import static org.sonar.process.ProcessProperties.Property.SEARCH_JAVA_OPTS; | ||||
import static org.sonar.process.ProcessProperties.Property.SOCKS_PROXY_HOST; | import static org.sonar.process.ProcessProperties.Property.SOCKS_PROXY_HOST; | ||||
import static org.sonar.process.ProcessProperties.Property.SOCKS_PROXY_PORT; | import static org.sonar.process.ProcessProperties.Property.SOCKS_PROXY_PORT; | ||||
import static org.sonar.process.ProcessProperties.Property.WEB_GRACEFUL_STOP_TIMEOUT; | |||||
import static org.sonar.process.ProcessProperties.Property.WEB_JAVA_ADDITIONAL_OPTS; | import static org.sonar.process.ProcessProperties.Property.WEB_JAVA_ADDITIONAL_OPTS; | ||||
import static org.sonar.process.ProcessProperties.Property.WEB_JAVA_OPTS; | import static org.sonar.process.ProcessProperties.Property.WEB_JAVA_OPTS; | ||||
import static org.sonar.process.ProcessProperties.parseTimeoutMs; | |||||
public class CommandFactoryImpl implements CommandFactory { | public class CommandFactoryImpl implements CommandFactory { | ||||
private static final String ENV_VAR_JAVA_TOOL_OPTIONS = "JAVA_TOOL_OPTIONS"; | private static final String ENV_VAR_JAVA_TOOL_OPTIONS = "JAVA_TOOL_OPTIONS"; | ||||
SOCKS_PROXY_HOST.getKey(), | SOCKS_PROXY_HOST.getKey(), | ||||
SOCKS_PROXY_PORT.getKey()}; | SOCKS_PROXY_PORT.getKey()}; | ||||
private static final Version SQ_VERSION = MetadataLoader.loadVersion(org.sonar.api.utils.System2.INSTANCE); | |||||
private final Props props; | private final Props props; | ||||
private final File tempDir; | private final File tempDir; | ||||
private final System2 system2; | private final System2 system2; | ||||
.setEnvVariable(PATH_LOGS.getKey(), props.nonNullValue(PATH_LOGS.getKey())) | .setEnvVariable(PATH_LOGS.getKey(), props.nonNullValue(PATH_LOGS.getKey())) | ||||
.setArgument("sonar.cluster.web.startupLeader", Boolean.toString(leader)) | .setArgument("sonar.cluster.web.startupLeader", Boolean.toString(leader)) | ||||
.setClassName("org.sonar.server.app.WebServer") | .setClassName("org.sonar.server.app.WebServer") | ||||
.addClasspath("./lib/common/*"); | |||||
.addClasspath("./lib/sonar-application-" + SQ_VERSION + ".jar"); | |||||
String driverPath = props.value(JDBC_DRIVER_PATH.getKey()); | String driverPath = props.value(JDBC_DRIVER_PATH.getKey()); | ||||
if (driverPath != null) { | if (driverPath != null) { | ||||
command.addClasspath(driverPath); | command.addClasspath(driverPath); | ||||
.setJvmOptions(jvmOptions) | .setJvmOptions(jvmOptions) | ||||
.setGracefulStopTimeoutMs(getGracefulStopTimeoutMs(props, CE_GRACEFUL_STOP_TIMEOUT)) | .setGracefulStopTimeoutMs(getGracefulStopTimeoutMs(props, CE_GRACEFUL_STOP_TIMEOUT)) | ||||
.setClassName("org.sonar.ce.app.CeServer") | .setClassName("org.sonar.ce.app.CeServer") | ||||
.addClasspath("./lib/common/*"); | |||||
.addClasspath("./lib/sonar-application-" + SQ_VERSION + ".jar"); | |||||
String driverPath = props.value(JDBC_DRIVER_PATH.getKey()); | String driverPath = props.value(JDBC_DRIVER_PATH.getKey()); | ||||
if (driverPath != null) { | if (driverPath != null) { | ||||
command.addClasspath(driverPath); | command.addClasspath(driverPath); |
assertThat(command.getClassName()).isEqualTo("org.sonar.server.app.WebServer"); | assertThat(command.getClassName()).isEqualTo("org.sonar.server.app.WebServer"); | ||||
assertThat(command.getWorkDir().getAbsolutePath()).isEqualTo(homeDir.getAbsolutePath()); | assertThat(command.getWorkDir().getAbsolutePath()).isEqualTo(homeDir.getAbsolutePath()); | ||||
assertThat(command.getClasspath()) | |||||
.containsExactly("./lib/common/*"); | |||||
assertThat(command.getClasspath()).hasSize(1).allMatch(p -> p.toString().startsWith("./lib/sonar-application-")); | |||||
assertThat(command.getJvmOptions().getAll()) | assertThat(command.getJvmOptions().getAll()) | ||||
// enforced values | // enforced values | ||||
.contains("-Djava.awt.headless=true", "-Dfile.encoding=UTF-8") | .contains("-Djava.awt.headless=true", "-Dfile.encoding=UTF-8") | ||||
assertThat(command.getClassName()).isEqualTo("org.sonar.ce.app.CeServer"); | assertThat(command.getClassName()).isEqualTo("org.sonar.ce.app.CeServer"); | ||||
assertThat(command.getWorkDir().getAbsolutePath()).isEqualTo(homeDir.getAbsolutePath()); | assertThat(command.getWorkDir().getAbsolutePath()).isEqualTo(homeDir.getAbsolutePath()); | ||||
assertThat(command.getClasspath()) | |||||
.containsExactly("./lib/common/*"); | |||||
assertThat(command.getClasspath()).hasSize(1).allMatch(p -> p.toString().startsWith("./lib/sonar-application-")); | |||||
assertThat(command.getJvmOptions().getAll()) | assertThat(command.getJvmOptions().getAll()) | ||||
// enforced values | // enforced values | ||||
.contains("-Djava.awt.headless=true", "-Dfile.encoding=UTF-8") | .contains("-Djava.awt.headless=true", "-Dfile.encoding=UTF-8") | ||||
props.setProperty("sonar.jdbc.driverPath", driverFile.getAbsolutePath()); | props.setProperty("sonar.jdbc.driverPath", driverFile.getAbsolutePath()); | ||||
JavaCommand command = newFactory(props).createWebCommand(true); | JavaCommand command = newFactory(props).createWebCommand(true); | ||||
assertThat(command.getClasspath()) | |||||
.containsExactlyInAnyOrder("./lib/common/*", driverFile.getAbsolutePath()); | |||||
assertThat(command.getClasspath()).hasSize(2); | |||||
assertThat(command.getClasspath().get(0).toString()).startsWith("./lib/sonar-application-"); | |||||
assertThat(command.getClasspath().get(1)).isEqualTo(driverFile.getAbsolutePath()); | |||||
} | } | ||||
private void prepareEsFileSystem() throws IOException { | private void prepareEsFileSystem() throws IOException { |
import org.apache.tools.ant.filters.ReplaceTokens | import org.apache.tools.ant.filters.ReplaceTokens | ||||
apply plugin: 'com.github.johnrengelman.shadow' | |||||
sonarqube { | sonarqube { | ||||
properties { | properties { | ||||
property 'sonar.projectName', "${projectTitle} :: Application" | property 'sonar.projectName', "${projectTitle} :: Application" | ||||
} | } | ||||
} | } | ||||
jar.enabled = false | |||||
shadowJar { | |||||
baseName = 'sonar-application' | |||||
classifier = null | |||||
mergeServiceFiles() | |||||
manifest { | |||||
attributes('Main-Class': 'org.sonar.application.App') | |||||
} | |||||
} | |||||
dependencies { | dependencies { | ||||
// please keep list ordered | // please keep list ordered | ||||
compile 'org.slf4j:slf4j-api' | compile 'org.slf4j:slf4j-api' | ||||
// declare dependencies in configuration bundledPlugin to be packaged in lib/extensions | // declare dependencies in configuration bundledPlugin to be packaged in lib/extensions | ||||
apply from: 'bundled_plugins.gradle' | apply from: 'bundled_plugins.gradle' | ||||
jar { | |||||
manifest { | |||||
attributes( | |||||
'Class-Path': configurations.compile.resolvedConfiguration.files.collect { "common/${it.getName()}" }.join(' '), | |||||
'Main-Class': 'org.sonar.application.App' | |||||
) | |||||
} | |||||
} | |||||
task zip(type: Zip, dependsOn: [configurations.compile]) { | task zip(type: Zip, dependsOn: [configurations.compile]) { | ||||
duplicatesStrategy DuplicatesStrategy.EXCLUDE | duplicatesStrategy DuplicatesStrategy.EXCLUDE | ||||
def archiveDir = "sonarqube-$version" | def archiveDir = "sonarqube-$version" | ||||
into("${archiveDir}/") { | into("${archiveDir}/") { | ||||
from file('src/main/assembly') | from file('src/main/assembly') | ||||
exclude 'conf/sonar.properties' | exclude 'conf/sonar.properties' | ||||
exclude 'conf/wrapper.conf' | |||||
exclude 'elasticsearch-patch' | exclude 'elasticsearch-patch' | ||||
// elasticsearch script will be replaced by patched version below | // elasticsearch script will be replaced by patched version below | ||||
exclude 'elasticsearch/bin/elasticsearch' | exclude 'elasticsearch/bin/elasticsearch' | ||||
into("${archiveDir}/conf/") { | into("${archiveDir}/conf/") { | ||||
from file('src/main/assembly/conf/sonar.properties') | from file('src/main/assembly/conf/sonar.properties') | ||||
filter(ReplaceTokens, tokens: [ | |||||
'searchDefaultHeapSize': '512MB', | |||||
'searchJavaOpts' : '-Xmx512m -Xms512m -XX:MaxDirectMemorySize=256m -XX:+HeapDumpOnOutOfMemoryError', | |||||
'ceDefaultHeapSize' : '512MB', | |||||
'ceJavaOpts' : '-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError', | |||||
'webDefaultHeapSize' : '512MB', | |||||
'webJavaOpts' : '-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError' | |||||
]) | |||||
} | |||||
filter(ReplaceTokens, tokens: [ | |||||
'searchDefaultHeapSize': '512MB', | |||||
'searchJavaOpts' : '-Xmx512m -Xms512m -XX:MaxDirectMemorySize=256m -XX:+HeapDumpOnOutOfMemoryError', | |||||
'ceDefaultHeapSize' : '512MB', | |||||
'ceJavaOpts' : '-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError', | |||||
'webDefaultHeapSize' : '512MB', | |||||
'webJavaOpts' : '-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError' | |||||
]) | |||||
} | |||||
into("${archiveDir}/conf/") { | |||||
from file('src/main/assembly/conf/wrapper.conf') | |||||
filter(ReplaceTokens, tokens: [ | |||||
'sqversion': version | |||||
]) | |||||
} | |||||
into("${archiveDir}/elasticsearch/") { | into("${archiveDir}/elasticsearch/") { | ||||
from file('src/main/assembly/elasticsearch-patch') | from file('src/main/assembly/elasticsearch-patch') | ||||
into("${archiveDir}/elasticsearch/") { | into("${archiveDir}/elasticsearch/") { | ||||
from "$buildDir/elasticsearch" | from "$buildDir/elasticsearch" | ||||
} | } | ||||
into("${archiveDir}/lib/") { | |||||
from jar | |||||
} | |||||
into("${archiveDir}/lib/extensions/") { | into("${archiveDir}/lib/extensions/") { | ||||
from configurations.bundledPlugin | from configurations.bundledPlugin | ||||
} | } | ||||
into("${archiveDir}/lib/scanner/") { | into("${archiveDir}/lib/scanner/") { | ||||
from configurations.scanner | from configurations.scanner | ||||
} | } | ||||
into("${archiveDir}/lib/common/") { | |||||
from configurations.compile | |||||
into("${archiveDir}/lib/") { | |||||
from shadowJar | |||||
} | } | ||||
into("${archiveDir}/web/") { | into("${archiveDir}/web/") { | ||||
duplicatesStrategy DuplicatesStrategy.FAIL | duplicatesStrategy DuplicatesStrategy.FAIL |
wrapper.java.additional.1=-Dsonar.wrapped=true | wrapper.java.additional.1=-Dsonar.wrapped=true | ||||
wrapper.java.additional.2=-Djava.awt.headless=true | wrapper.java.additional.2=-Djava.awt.headless=true | ||||
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp | wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp | ||||
wrapper.java.classpath.1=../../lib/jsw/*.jar | |||||
wrapper.java.classpath.2=../../lib/common/*.jar | |||||
wrapper.java.classpath.3=../../lib/*.jar | |||||
wrapper.java.classpath.1=../../lib/sonar-application-@sqversion@.jar | |||||
wrapper.java.classpath.2=../../lib/jsw/wrapper-3.2.3.jar | |||||
wrapper.java.classpath.3=../../lib/sonar-shutdowner-@sqversion@.jar | |||||
wrapper.java.library.path.1=./lib | wrapper.java.library.path.1=./lib | ||||
wrapper.app.parameter.1=org.sonar.application.App | wrapper.app.parameter.1=org.sonar.application.App | ||||
wrapper.java.initmemory=8 | wrapper.java.initmemory=8 |