/*
* Copyright 2016 ThoughtWorks, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.thoughtworks.go.util;
import com.thoughtworks.go.utils.Timeout;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class SystemEnvironment implements Serializable, ConfigDirProvider {
private static final Logger LOG = Logger.getLogger(SystemEnvironment.class);
public static final String CRUISE_LISTEN_HOST = "cruise.listen.host";
private static final String CRUISE_DATABASE_PORT = "cruise.database.port";
public static final String CRUISE_SERVER_PORT = "cruise.server.port";
public static final String CRUISE_SERVER_SSL_PORT = "cruise.server.ssl.port";
static final String AGENT_CONNECTION_TIMEOUT_IN_SECONDS = "agent.connection.timeout";
private static final String JETTY_XML = "jetty.xml";
public static final String CRUISE_SERVER_WAR_PROPERTY = "cruise.server.war";
public static final String CRUISE_CONFIG_REPO_DIR = "cruise.config.repo.dir";
private static final String DB_BASE_DIR = "db/";
private static final String DB_DEFAULT_PATH = DB_BASE_DIR + "h2db";
private static final String CONFIG_REPO_DEFAULT_PATH = DB_BASE_DIR + "config.git";
public static final String CRUISE_DB_CACHE_SIZE = "cruise.db.cache.size";
public static final String CRUISE_DB_CACHE_SIZE_DEFAULT = String.valueOf(128 * 1024); // 128MB Cache Size by default
public static final String ACTIVEMQ_USE_JMX = "activemq.use.jmx";
public static final String ACTIVEMQ_QUEUE_PREFETCH = "activemq.queue.prefetch";
private static final String ACTIVEMQ_CONNECTOR_PORT = "activemq.conn.port";
public static final String PARENT_LOADER_PRIORITY = "parent.loader.priority";
public static final String AGENT_CONTENT_MD5_HEADER = "Agent-Content-MD5";
public static final String AGENT_LAUNCHER_CONTENT_MD5_HEADER = "Agent-Launcher-Content-MD5";
public static final String AGENT_PLUGINS_ZIP_MD5_HEADER = "Agent-Plugins-Content-MD5";
public static final String AGENT_TFS_SDK_MD5_HEADER = "TFS-SDK-Content-MD5";
public static final String EMPTY_STRING = "";
public static final String BLANK_STRING = EMPTY_STRING;
public static final String ENFORCE_SERVERID_MUTABILITY = "go.enforce.serverId.immutability";
public static final String CONFIGURATION_YES = "Y";
public static final String CONFIGURATION_NO = "N";
public static final String RESOLVE_FANIN_REVISIONS = "resolve.fanin.revisions";
public static final String RESOLVE_FANIN_FALLBACK_TRIANGLE = "resolve.fanin.fallback.triangle";
private String hsqlPath = null;
public static final String ENABLE_CONFIG_MERGE_PROPERTY = "enable.config.merge";
public static final GoSystemProperty<Boolean> ENABLE_CONFIG_MERGE_FEATURE = new CachedProperty<>(new GoBooleanSystemProperty(ENABLE_CONFIG_MERGE_PROPERTY, Boolean.TRUE));
private String defaultDbPort = "9153";
private static final String DB_UPGRADE_H2_DELTAS_FOLDER = "h2deltas";
private boolean debug;
public static final String CRUISE_PROPERTIES = "/cruise.properties";
private Properties properties;
public static final String CRUISE_EXPERIMENTAL_ENABLE_ALL = "cruise.experimental.enable-all";
public static final String ARTIFACT_FULL_SIZE_LIMIT = "artifact.full.size.limit";
public static final String DATABASE_FULL_SIZE_LIMIT = "db.full.size.limit";
public static final String ARTIFACT_WARNING_SIZE_LIMIT = "artifact.warning.size.limit";
public static final String DATABASE_WARNING_SIZE_LIMIT = "db.warning.size.limit";
public static final String AGENT_SIZE_LIMIT = "agent.size.limit";
private static final String DISK_SPACE_CACHE_REFRESHER_INTERVAL = "disk.space.cache.refresher.interval";
private static final String COMMAND_REPOSITORY_WARNING_TIMEOUT = "command.repo.warning.timeout";
public static final String AGENT_SOCKET_TYPE_NIO = "nio";
private static final String AGENT_SOCKET_TYPE_PROPERTY = "agent.socket.type";
public static final String CONFIG_FILE_PROPERTY = "cruise.config.file";
public static final String INTERVAL = "cruise.console.publish.interval";
public static final String SERVICE_URL = "serviceUrl";
public static final String AGENT_SSL_VERIFICATION_MODE = "sslVerificationMode";
public static final String AGENT_ROOT_CERT_FILE = "rootCertFile";
public static final String CONFIG_DIR_PROPERTY = "cruise.config.dir";
public static final String CONFIG_CIPHER = "cipher";
public static final String HOSTNAME_SHINE_USES = "localhost";
public static final int TFS_SOCKET_TIMEOUT_IN_MILLISECONDS = 20 * 60 * 1000;
public static final String TFS_SOCKET_TIMEOUT_PROPERTY = "tfs.socket.block.timeout";
public static GoSystemProperty<Integer> RESOLVE_FANIN_MAX_BACK_TRACK_LIMIT = new CachedProperty<>(new GoIntSystemProperty("resolve.fanin.max.backtrack.limit", 100));
public static GoSystemProperty<Integer> MATERIAL_UPDATE_INACTIVE_TIMEOUT = new CachedProperty<>(new GoIntSystemProperty("material.update.inactive.timeout", 15));
public static GoSystemProperty<Integer> H2_DB_TRACE_LEVEL = new GoIntSystemProperty("h2.trace.level", 1);
public static GoSystemProperty<Integer> H2_DB_TRACE_FILE_SIZE_MB = new GoIntSystemProperty("h2.trace.file.size.mb", 16);
private static GoSystemProperty<String> CRUISE_DATABASE_DIR = new GoStringSystemProperty("cruise.database.dir", DB_DEFAULT_PATH);
public static final String MATERIAL_UPDATE_IDLE_INTERVAL_PROPERTY = "material.update.idle.interval";
private static GoSystemProperty<Long> MATERIAL_UPDATE_IDLE_INTERVAL = new GoLongSystemProperty(MATERIAL_UPDATE_IDLE_INTERVAL_PROPERTY, 60000L);
public static GoSystemProperty<Integer> PLUGIN_LOCATION_MONITOR_INTERVAL_IN_SECONDS = new GoIntSystemProperty("pluginLocationMonitor.sleepTimeInSecs", -1);
public static final String PLUGINS_PATH = "plugins";
public static GoSystemProperty<String> PLUGIN_GO_PROVIDED_PATH = new GoStringSystemProperty("plugins.go.provided.path", PLUGINS_PATH + System.getProperty("file.separator") + "bundled");
public static GoSystemProperty<String> PLUGIN_EXTERNAL_PROVIDED_PATH = new GoStringSystemProperty("plugins.external.provided.path", PLUGINS_PATH + System.getProperty("file.separator") + "external");
public static GoSystemProperty<String> PLUGIN_BUNDLE_PATH = new CachedProperty<>(new GoStringSystemProperty("plugins.work.path", "plugins_work"));
public static GoSystemProperty<String> PLUGIN_ACTIVATOR_JAR_PATH = new CachedProperty<>(new GoStringSystemProperty("plugins.activator.jar.path", "lib/go-plugin-activator.jar"));
public static GoSystemProperty<String> ALL_PLUGINS_ZIP_PATH = new GoStringSystemProperty("plugins.all.zip.path", new File(PLUGINS_PATH, "go-plugins-all.zip").getAbsolutePath());
public static GoSystemProperty<String> ADDONS_PATH = new GoStringSystemProperty("addons.path", "addons");
public static GoSystemProperty<String> AVAILABLE_FEATURE_TOGGLES_FILE_PATH = new GoStringSystemProperty("available.toggles.path", "/available.toggles");
public static GoSystemProperty<String> USER_FEATURE_TOGGLES_FILE_PATH_RELATIVE_TO_CONFIG_DIR = new GoStringSystemProperty("user.toggles.path", "go.feature.toggles");
public static GoSystemProperty<String> DEFAULT_COMMAND_SNIPPETS_ZIP = new CachedProperty<>(
new GoStringSystemProperty("default.command.snippets.zip.location", "/defaultFiles/defaultCommandSnippets.zip"));
public static GoSystemProperty<String> DEFAULT_PLUGINS_ZIP = new CachedProperty<>(
new GoStringSystemProperty("default.plugins.zip.location", "/defaultFiles/plugins.zip"));
public static final GoSystemProperty<String> AGENT_PLUGINS_PATH = new CachedProperty<>(new GoStringSystemProperty("agent.plugins.path", PLUGINS_PATH));
public static GoSystemProperty<String> VERSION_FILE_IN_DEFAULT_COMMAND_REPOSITORY = new CachedProperty<>(new GoStringSystemProperty("version.file.in.command.repository", "version.txt"));
public static GoSystemProperty<Integer> COMMAND_REPOSITORY_CACHE_TIME_IN_SECONDS = new CachedProperty<>(new GoIntSystemProperty("command.repo.cache.timeout.in.secs", 30 * 60));
public static GoSystemProperty<String> COMMAND_REPOSITORY_DIRECTORY = new CachedProperty<>(new GoStringSystemProperty("command.repo.dir", DB_BASE_DIR + "command_repository"));
public static GoSystemProperty<Integer> IDLE_TIMEOUT = new GoIntSystemProperty("idle.timeout", 30000);
public static GoSystemProperty<Integer> RESPONSE_BUFFER_SIZE = new GoIntSystemProperty("response.buffer.size", 32768);
public static final GoSystemProperty<Integer> API_REQUEST_IDLE_TIMEOUT_IN_SECONDS = new GoIntSystemProperty("api.request.idle.timeout.seconds", 300);
public static GoSystemProperty<Integer> PLUGIN_NOTIFICATION_LISTENER_COUNT = new CachedProperty<>(new GoIntSystemProperty("plugin.notification.listener.count", 1));
/* DATABASE CONFIGURATION - Defaults are of H2 */
public static GoSystemProperty<String> GO_DATABASE_HOST = new GoStringSystemProperty("db.host", "localhost");
public static GoSystemProperty<String> GO_DATABASE_PORT = new GoStringSystemProperty("db.port", "");
public static GoSystemProperty<String> GO_DATABASE_NAME = new GoStringSystemProperty("db.name", "cruise");
public static GoSystemProperty<String> GO_DATABASE_USER = new GoStringSystemProperty("db.user", "sa");
public static GoSystemProperty<String> GO_DATABASE_PASSWORD = new GoStringSystemProperty("db.password", "");
public static GoIntSystemProperty GO_DATABASE_MAX_ACTIVE = new GoIntSystemProperty("db.maxActive", 32);
public static GoIntSystemProperty GO_DATABASE_MAX_IDLE = new GoIntSystemProperty("db.maxIdle", 32);
public static final String H2_DATABASE = "com.thoughtworks.go.server.database.H2Database";
public static GoStringSystemProperty GO_DATABASE_PROVIDER = new GoStringSystemProperty("go.database.provider", H2_DATABASE);
public static GoSystemProperty<Boolean> SHOULD_VALIDATE_XML_AGAINST_DTD = new GoBooleanSystemProperty("validate.xml.against.dtd", false);
public static GoSystemProperty<String> JETTY_XML_FILE_NAME = new GoStringSystemProperty("jetty.xml.file.name", JETTY_XML);
public static final String JETTY9 = "com.thoughtworks.go.server.Jetty9Server";
public static GoSystemProperty<String> APP_SERVER = new CachedProperty<>(new GoStringSystemProperty("app.server", JETTY9));
public static GoSystemProperty<Boolean> TFS_SDK_10 = new CachedProperty<>(new GoBooleanSystemProperty("tfs.sdk.old", false));
public static GoSystemProperty<String> GO_SERVER_STATE = new GoStringSystemProperty("go.server.state", "active");
public static GoSystemProperty<String> GO_LANDING_PAGE = new GoStringSystemProperty("go.landing.page", "/pipelines");
public static GoSystemProperty<Boolean> FETCH_ARTIFACT_AUTO_SUGGEST = new GoBooleanSystemProperty("go.fetch-artifact.auto-suggest", true);
public static GoSystemProperty<Boolean> GO_FETCH_ARTIFACT_TEMPLATE_AUTO_SUGGEST = new GoBooleanSystemProperty("go.fetch-artifact.template.auto-suggest", true);
public static GoSystemProperty<String> GO_SSL_TRANSPORT_PROTOCOL_TO_BE_USED_BY_AGENT = new GoStringSystemProperty("go.ssl.agent.protocol", "TLSv1.2");
public static GoSystemProperty<String> GO_SSL_CERTS_ALGORITHM = new GoStringSystemProperty("go.ssl.cert.algorithm", "SHA512WITHRSA");
public static GoSystemProperty<String> GO_SSL_CERTS_PUBLIC_KEY_ALGORITHM = new GoStringSystemProperty("go.ssl.cert.public-key.algorithm", "SHA256WithRSAEncryption");
public static GoSystemProperty<Boolean> GO_SSL_CONFIG_ALLOW = new GoBooleanSystemProperty("go.ssl.config.allow", true);
public static GoSystemProperty<String[]> GO_SSL_INCLUDE_CIPHERS = new GoStringArraySystemProperty("go.ssl.ciphers.include", null);
public static GoSystemProperty<String[]> GO_SSL_EXCLUDE_CIPHERS = new GoStringArraySystemProperty("go.ssl.ciphers.exclude", null);
public static GoSystemProperty<String[]> GO_SSL_INCLUDE_PROTOCOLS = new GoStringArraySystemProperty("go.ssl.protocols.include", null);
public static GoSystemProperty<String[]> GO_SSL_EXCLUDE_PROTOCOLS = new GoStringArraySystemProperty("go.ssl.protocols.exclude", null);
public static GoSystemProperty<Boolean> GO_SSL_RENEGOTIATION_ALLOWED = new GoBooleanSystemProperty("go.ssl.renegotiation.allowed", true);
public static GoSystemProperty<Boolean> GO_CONFIG_REPO_GC_AGGRESSIVE = new GoBooleanSystemProperty("go.config.repo.gc.aggressive", true);
public static GoSystemProperty<Long> GO_CONFIG_REPO_GC_EXPIRE = new GoLongSystemProperty("go.config.repo.gc.expire", 24L);
public static GoSystemProperty<Long> GO_CONFIG_REPO_GC_LOOSE_OBJECT_WARNING_THRESHOLD = new GoLongSystemProperty("go.config.repo.gc.warning.looseobject.threshold", 10000L);
public static GoSystemProperty<Boolean> GO_CONFIG_REPO_PERIODIC_GC = new GoBooleanSystemProperty("go.config.repo.gc.periodic", false);
public static GoSystemProperty<String> GO_UPDATE_SERVER_PUBLIC_KEY_FILE_NAME = new GoStringSystemProperty("go.update.server.public.key.file.name", "go_update_server.pub");
public static GoSystemProperty<String> GO_UPDATE_SERVER_URL = new GoStringSystemProperty("go.update.server.url", "https://update.gocd.io/channels/supported/latest.json");
public static GoSystemProperty<Boolean> GO_CHECK_UPDATES = new GoBooleanSystemProperty("go.check.updates", true);
public static GoSystemProperty<Integer> GO_ELASTIC_PLUGIN_CREATE_AGENT_THREADS = new GoIntSystemProperty("go.elasticplugin.createagent.threads", 5);
public static GoSystemProperty<Integer> GO_ELASTIC_PLUGIN_SERVER_PING_THREADS = new GoIntSystemProperty("go.elasticplugin.serverping.threads", 1);
public static GoSystemProperty<Integer> GO_ENCRYPTION_API_MAX_REQUESTS = new GoIntSystemProperty("go.encryption.api.max.requests", 30);
public static GoSystemProperty<Boolean> WEBSOCKET_ENABLED = new GoBooleanSystemProperty("go.agent.websocket.enabled", false);
public static GoSystemProperty<Boolean> CONSOLE_LOGS_THROUGH_WEBSOCKET_ENABLED = new GoBooleanSystemProperty("go.agent.console.logs.websocket.enabled", true);
public static GoSystemProperty<Boolean> AUTO_REGISTER_LOCAL_AGENT_ENABLED = new GoBooleanSystemProperty("go.auto.register.local.agent.enabled", true);
public static GoSystemProperty<Long> GO_WEBSOCKET_ACK_MESSAGE_TIMEOUT = new GoLongSystemProperty("go.websocket.ack.message.timeout", 300 * 1000L);
public static GoSystemProperty<Integer> GO_WEBSOCKET_SEND_RETRY_COUNT = new GoIntSystemProperty("go.websocket.send.retry.count", 5);
public static GoSystemProperty<Long> GO_WEBSOCKET_MAX_IDLE_TIME = new GoLongSystemProperty("go.websocket.max.idle.time", 60 * 1000L);
public static GoSystemProperty<Boolean> GO_SERVER_SHALLOW_CLONE = new GoBooleanSystemProperty("go.server.shallowClone", false);
public static GoSystemProperty<Boolean> GO_SERVER_SCHEDULED_PIPELINE_LOADER_GLOBAL_MATERIAL_LOOKUP = new GoBooleanSystemProperty("go.server.scheduledPipelineLoader.globalMaterialLookup", false);
public static GoSystemProperty<Boolean> PLUGIN_UPLOAD_ENABLED = new GoBooleanSystemProperty("go.plugin.upload.enabled", false);
public static GoSystemProperty<Boolean> GO_API_WITH_SAFE_MODE = new GoBooleanSystemProperty("go.api.with.safe.mode", true);
public static GoSystemProperty<Integer> MAX_PENDING_AGENTS_ALLOWED = new GoIntSystemProperty("max.pending.agents.allowed", 100);
public static GoSystemProperty<Boolean> CHECK_AND_REMOVE_DUPLICATE_MODIFICATIONS = new GoBooleanSystemProperty("go.modifications.removeDuplicates", true);
public static GoSystemProperty<String> GO_AGENT_KEYSTORE_PASSWORD = new GoStringSystemProperty("go.agent.keystore.password", "agent5s0repa55w0rd");
private static final GoSystemProperty<Boolean> GO_AGENT_USE_SSL_CONTEXT = new GoBooleanSystemProperty("go.agent.reuse.ssl.context", true);
public static final GoSystemProperty<? extends Boolean> ENABLE_BUILD_COMMAND_PROTOCOL = new GoBooleanSystemProperty("go.agent.enableBuildCommandProtocol", false);
public static final GoSystemProperty<? extends Boolean> GO_DIAGNOSTICS_MODE = new GoBooleanSystemProperty("go.diagnostics.mode", false);
public static GoIntSystemProperty DEPENDENCY_MATERIAL_UPDATE_LISTENERS = new GoIntSystemProperty("dependency.material.check.threads", 3);
public static GoSystemProperty<Boolean> OPTIMIZE_FULL_CONFIG_SAVE = new GoBooleanSystemProperty("optimize.full.config.save", true);
public static GoSystemProperty<String> GO_SERVER_MODE = new GoStringSystemProperty("go.server.mode", "production");
public static GoBooleanSystemProperty REAUTHENTICATION_ENABLED = new GoBooleanSystemProperty("go.security.reauthentication.enabled", false);
public static GoSystemProperty<Long> REAUTHENTICATION_TIME_INTERVAL = new GoLongSystemProperty("go.security.reauthentication.interval", 1800 * 1000L);
private final static Map<String, String> GIT_ALLOW_PROTOCOL;
static {
Map<String, String> map = new HashMap<String, String>() {{
put("GIT_ALLOW_PROTOCOL", System.getenv("GIT_ALLOW_PROTOCOL") == null ?
"http:https:ssh:git:file:rsync" : System.getenv("GIT_ALLOW_PROTOCOL"));
}};
GIT_ALLOW_PROTOCOL = Collections.unmodifiableMap(map);
}
private volatile static Integer agentConnectionTimeout;
private volatile static Integer cruiseSSlPort;
private volatile static String cruiseConfigDir;
private volatile static Long databaseFullSizeLimit;
private volatile static Long artifactFullSizeLimit;
private volatile static Long diskSpaceCacheRefresherInterval;
public static final String UNRESPONSIVE_JOB_WARNING_THRESHOLD = "cruise.unresponsive.job.warning";
private File configDir;
private volatile Boolean enforceRevisionCompatibilityWithUpstream;
private volatile Boolean enforceFanInFallbackTriangle;
public SystemEnvironment() {
}
public SystemEnvironment(Properties properties) {
this.properties = properties;
}
public SystemEnvironment(String hsqlPath, String defaultDbPort) {
if (defaultDbPort == null) {
throw ExceptionUtils.bomb("Default db port cannot be null");
}
this.hsqlPath = hsqlPath;
this.defaultDbPort = defaultDbPort;
debug = getPropertyImpl("DB_DEBUG_MODE") != null
&& !(getPropertyImpl("DB_DEBUG_MODE").equals("false"));
}
public <T> T get(GoSystemProperty<T> systemProperty) {
return systemProperty.getValue();
}
public <T> void set(GoSystemProperty<T> systemProperty, T value) {
System.setProperty(systemProperty.propertyName, "" + value);
if (systemProperty instanceof CachedProperty) {
((CachedProperty) systemProperty).clear();
}
}
public void set(GoSystemProperty<Boolean> systemProperty, boolean value) {
System.setProperty(systemProperty.propertyName, value ? "Y" : "N");
if (systemProperty instanceof CachedProperty) {
((CachedProperty) systemProperty).clear();
}
}
public File configDir() {
if (configDir == null) {
configDir = new File(getPropertyImpl(CONFIG_FILE_PROPERTY, "config/cruise-config.xml")).getParentFile();
}
return configDir;
}
public File keystore() {
return new File(configDir(), "keystore");
}
public File truststore() {
return new File(configDir(), "truststore");
}
public File agentkeystore() {
return new File(configDir(), "agentkeystore");
}
public int getServerPort() {
return Integer.parseInt(getPropertyImpl(CRUISE_SERVER_PORT, "8153"));
}
public String getListenHost() {
return getPropertyImpl(CRUISE_LISTEN_HOST);
}
public long getArtifactReposiotryFullLimit() {
if (artifactFullSizeLimit != null) {
return artifactFullSizeLimit;
}
return artifactFullSizeLimit = Long.parseLong(trimMegaFromSize(getPropertyImpl(ARTIFACT_FULL_SIZE_LIMIT, "100M")));
}
public long getDatabaseDiskSpaceFullLimit() {
if (databaseFullSizeLimit != null) {
return databaseFullSizeLimit;
}
return databaseFullSizeLimit = Long.parseLong(trimMegaFromSize(getPropertyImpl(DATABASE_FULL_SIZE_LIMIT, "100M")));
}
public long getDiskSpaceCacheRefresherInterval() {
if (diskSpaceCacheRefresherInterval != null) {
return diskSpaceCacheRefresherInterval;
}
return diskSpaceCacheRefresherInterval = Long.parseLong(getPropertyImpl(DISK_SPACE_CACHE_REFRESHER_INTERVAL, "5000"));
}
//Used in Tests
public void setDiskSpaceCacheRefresherInterval(long interval) {
diskSpaceCacheRefresherInterval = interval;
}
public long getAgentSizeLimit() {
return Long.parseLong(trimMegaFromSize(getPropertyImpl(AGENT_SIZE_LIMIT, "100M"))) * 1024 * 1024;
}
public long getArtifactReposiotryWarningLimit() {
return Long.parseLong(trimMegaFromSize(getPropertyImpl(ARTIFACT_WARNING_SIZE_LIMIT, "1024M")));
}
public long getDatabaseDiskSpaceWarningLimit() {
return Long.parseLong(trimMegaFromSize(getPropertyImpl(DATABASE_WARNING_SIZE_LIMIT, "1024M")));
}
private String trimMegaFromSize(String sizeInMega) {
return StringUtils.removeEndIgnoreCase(sizeInMega, "M");
}
public int getSslServerPort() {
if (cruiseSSlPort != null) {
return cruiseSSlPort;
}
return cruiseSSlPort = Integer.parseInt(getPropertyImpl(CRUISE_SERVER_SSL_PORT, "8154"));
}
public String getConfigDir() {
if (cruiseConfigDir != null) {
return cruiseConfigDir;
}
return cruiseConfigDir = getPropertyImpl(CONFIG_DIR_PROPERTY, "config");
}
public File getJettyConfigFile() {
return new File(getConfigDir(), get(JETTY_XML_FILE_NAME));
}
/**
* @deprecated use <code>new SystemEnvironment().getXXXXX()</code> instead.
*/
public static String getProperty(String property, String defaultValue) {
return new SystemEnvironment().getPropertyImpl(property, defaultValue);
}
/**
* @deprecated use <code>new SystemEnvironment().getXXXXX()</code> instead.
*/
public static String getProperty(String property) {
return new SystemEnvironment().getPropertyImpl(property);
}
private String getPropertyImpl(String property, String defaultValue) {
return System.getProperty(property, defaultValue);
}
public String getPropertyImpl(String property) {
return System.getProperty(property);
}
public String getOperatingSystemFamilyName() {
return OperatingSystem.getFamilyName();
}
public String getOperatingSystemCompleteName() {
return OperatingSystem.getCompleteName();
}
public String getOperatingSystemName() {
return getPropertyImpl("os.name");
}
public int getDatabaseSeverPort() {
String port = getDatabasePort();
try {
return Integer.parseInt(port);
} catch (NumberFormatException e) {
LOG.info("Could not parse port=" + port);
}
return Integer.parseInt(defaultDbPort);
}
private String getDatabasePort() {
String port = getPropertyImpl(CRUISE_DATABASE_PORT);
if (port == null) {
port = defaultDbPort;
}
return port;
}
public boolean getEnableRequestTimeLogging() {
return Boolean.parseBoolean(getPropertyImpl("cruise.request.time.logging", "false"));
}
public int getActivemqQueuePrefetch() {
return Integer.parseInt(getPropertyImpl(ACTIVEMQ_QUEUE_PREFETCH, "0"));
}
public long getCommandRepoWarningTimeout() {
return Long.parseLong(getPropertyImpl(COMMAND_REPOSITORY_WARNING_TIMEOUT, String.valueOf(Timeout.ONE_HOUR.inMillis())));
}
public boolean getActivemqUseJmx() {
return Boolean.parseBoolean(getPropertyImpl(ACTIVEMQ_USE_JMX, "false"));
}
public int getActivemqConnectorPort() {
return Integer.parseInt(getPropertyImpl(ACTIVEMQ_CONNECTOR_PORT, "1099"));
}
public String getScriptPath() {
return new File(getDbPath(), "cruise").getAbsolutePath();
}
public File getDBDeltasPath() {
return new File(getDbFolder(), DB_UPGRADE_H2_DELTAS_FOLDER);
}
public File getDbPath() {
if (hsqlPath == null) {
hsqlPath = get(CRUISE_DATABASE_DIR);
}
return new File(hsqlPath);
}
public File getConfigRepoDir() {
return new File(properties().getProperty(CRUISE_CONFIG_REPO_DIR, CONFIG_REPO_DEFAULT_PATH));
}
public File getCipherFile() {
return new File(getConfigDir(), CONFIG_CIPHER);
}
public File getDbFolder() {
return getDbPath().getParentFile();
}
public int getNumberOfMaterialCheckListener() {
return Integer.parseInt(getPropertyImpl("material.check.threads", "10"));
}
public int getNumberOfConfigMaterialCheckListener() {
return Integer.parseInt(getPropertyImpl("material.config.check.threads", "2"));
}
public int getNumberOfDependencyMaterialUpdateListeners() {
return DEPENDENCY_MATERIAL_UPDATE_LISTENERS.getValue();
}
public int getNumberOfPluginNotificationListener() {
return PLUGIN_NOTIFICATION_LISTENER_COUNT.getValue();
}
public String getAgentMd5() {
return getPropertyImpl(GoConstants.AGENT_JAR_MD5, BLANK_STRING);
}
public String getTfsImplMd5() {
return getPropertyImpl(GoConstants.TFS_IMPL_MD5, BLANK_STRING);
}
public String getGivenAgentLauncherMd5() {
return getPropertyImpl(GoConstants.GIVEN_AGENT_LAUNCHER_JAR_MD5, BLANK_STRING);
}
public String getAgentPluginsMd5() {
return getPropertyImpl(GoConstants.AGENT_PLUGINS_MD5, BLANK_STRING);
}
public boolean inDbDebugMode() {
return debug;
}
public boolean usingRemoteDb() {
return getPropertyImpl("DB_REMOTE") != null
&& !(getPropertyImpl("DB_REMOTE").equals("false"));
}
public void setDebugMode(boolean debug) {
this.debug = debug;
}
public boolean isFeatureEnabled(String value) {
if (Boolean.parseBoolean(properties().getProperty(CRUISE_EXPERIMENTAL_ENABLE_ALL, "false"))) {
return true;
}
return Boolean.parseBoolean(properties().getProperty(value, "false"));
}
private Properties properties() {
if (properties == null) {
properties = new Properties();
try(InputStream is = getClass().getResourceAsStream(CRUISE_PROPERTIES)) {
properties.load(is);
} catch (Exception e) {
LOG.error("Unable to load newProperties file " + CRUISE_PROPERTIES);
}
}
return properties;
}
public boolean useNioSslSocket() {
String socketType = getPropertyImpl(AGENT_SOCKET_TYPE_PROPERTY, AGENT_SOCKET_TYPE_NIO);
return AGENT_SOCKET_TYPE_NIO.equalsIgnoreCase(socketType);
}
public String getCruiseConfigFile() {
return getPropertyImpl(CONFIG_FILE_PROPERTY, getConfigDir() + "/cruise-config.xml");
}
public int getAgentConnectionTimeout() {
if (agentConnectionTimeout != null) {
return agentConnectionTimeout;
}
return agentConnectionTimeout = Integer.parseInt(getPropertyImpl(AGENT_CONNECTION_TIMEOUT_IN_SECONDS, "300"));
}
public Integer getConsolePublishInterval() {
return Integer.valueOf(getPropertyImpl(INTERVAL, "5"));
}
public String getServiceUrl() {
return getPropertyImpl(SERVICE_URL, defaultRemotingUrl());
}
public File getRootCertFile() {
if (getPropertyImpl(AGENT_ROOT_CERT_FILE) == null) {
return null;
}
return new File(getPropertyImpl(AGENT_ROOT_CERT_FILE));
}
public SslVerificationMode getAgentSslVerificationMode() {
if (getPropertyImpl(AGENT_SSL_VERIFICATION_MODE) == null) {
return SslVerificationMode.NONE;
}
return SslVerificationMode.valueOf(getPropertyImpl(AGENT_SSL_VERIFICATION_MODE));
}
private String defaultRemotingUrl() {
return "https://localhost:8443" + getWebappContextPath();
}
public boolean useCompressedJs() {
return Boolean.parseBoolean(getPropertyImpl(GoConstants.USE_COMPRESSED_JAVASCRIPT, "true"));
}
public String getEnvironmentVariable(String key) {
return System.getenv(key);
}
public Map<String, String> getGitAllowedProtocols() {
return GIT_ALLOW_PROTOCOL;
}
public String getBaseUrlForShine() {
return String.format("http://%s:%s%s", HOSTNAME_SHINE_USES, getServerPort(), getWebappContextPath());
}
public Boolean isShineEnabled() {
String shineEnabled = getEnvironmentVariable("SHINE_ENABLED");
return shineEnabled == null ? false : !"false".equalsIgnoreCase(shineEnabled); //should return true for shine_enabled set to anything but false.
}
public String getBaseSslUrlForShineWithoutContextPath() {
return String.format("https://%s:%s", HOSTNAME_SHINE_USES, getSslServerPort());
}
public String getBaseSslUrlForShine() {
return getBaseSslUrlForShineWithoutContextPath() + getWebappContextPath();
}
public File shineDb() {
return new File(properties().getProperty("cruise.shine.store.folder"));
}
public void setProperty(String name, String value) {
clearCachedSystemEnvironment();
System.setProperty(name, value);
}
public void clearProperty(String name) {
clearCachedSystemEnvironment();
System.clearProperty(name);
}
private void clearCachedSystemEnvironment() {
agentConnectionTimeout = null;
cruiseSSlPort = null;
cruiseConfigDir = null;
databaseFullSizeLimit = null;
artifactFullSizeLimit = null;
}
public String getWebappContextPath() {
return getPropertyImpl("cruise.server.context", "/go");
}
public String pathFor(String appPath) {
return (getWebappContextPath() + "/" + appPath).replaceAll("//", "/");
}
public String getCruiseWar() {
return getPropertyImpl(CRUISE_SERVER_WAR_PROPERTY, "cruise.war");
}
public String getCruiseDbCacheSize() {
return getPropertyImpl(CRUISE_DB_CACHE_SIZE, CRUISE_DB_CACHE_SIZE_DEFAULT);
}
public long getUnresponsiveJobWarningThreshold() {
return Long.parseLong(getPropertyImpl(UNRESPONSIVE_JOB_WARNING_THRESHOLD, "5")) * 60 * 1000;//mins to mills
}
public boolean getParentLoaderPriority() {
return Boolean.parseBoolean(getPropertyImpl(PARENT_LOADER_PRIORITY, "false"));
}
public String getUserDirectory() {
return getPropertyImpl("user.dir");
}
public static final ThreadLocal<Boolean> enforceServerIdImmutability = new ThreadLocal<Boolean>() {
@Override
protected Boolean initialValue() {
return false;
}
};
public int getMaxEncryptionAPIRequestsPerMinute() {
return GO_ENCRYPTION_API_MAX_REQUESTS.getValue();
}
public boolean enforceServerIdImmutability() {
return CONFIGURATION_YES.equals(getPropertyImpl(ENFORCE_SERVERID_MUTABILITY, CONFIGURATION_YES)) || enforceServerIdImmutability.get();
}
public boolean enforceRevisionCompatibilityWithUpstream() {
if (enforceRevisionCompatibilityWithUpstream == null) {
enforceRevisionCompatibilityWithUpstream = CONFIGURATION_YES.equals(getPropertyImpl(RESOLVE_FANIN_REVISIONS, CONFIGURATION_YES));
}
return enforceRevisionCompatibilityWithUpstream;
}
public int getTfsSocketTimeout() {
return Integer.parseInt(getPropertyImpl(TFS_SOCKET_TIMEOUT_PROPERTY, String.valueOf(TFS_SOCKET_TIMEOUT_IN_MILLISECONDS)));
}
public boolean enforceFanInFallbackBehaviour() {
if (enforceFanInFallbackTriangle == null) {
enforceFanInFallbackTriangle = CONFIGURATION_YES.equals(getPropertyImpl(RESOLVE_FANIN_FALLBACK_TRIANGLE, CONFIGURATION_NO));
}
return enforceFanInFallbackTriangle;
}
public int getCruiseDbTraceLevel() {
return H2_DB_TRACE_LEVEL.getValue();
}
public int getCruiseDbTraceFileSize() {
return H2_DB_TRACE_FILE_SIZE_MB.getValue();
}
public Level pluginLoggingLevel(String pluginId) {
return Level.toLevel(getPropertyImpl("plugin." + pluginId + ".log.level", "INFO"), Level.INFO);
}
public File getDefaultCommandRepository() {
return new File(get(COMMAND_REPOSITORY_DIRECTORY), "default");
}
public String getCommandRepositoryRootLocation() {
return new File(get(COMMAND_REPOSITORY_DIRECTORY)).getAbsolutePath();
}
public String getExternalPluginAbsolutePath() {
return new File(get(PLUGIN_EXTERNAL_PROVIDED_PATH)).getAbsolutePath();
}
public String getBundledPluginAbsolutePath() {
return new File(get(PLUGIN_GO_PROVIDED_PATH)).getAbsolutePath();
}
public <T> void reset(GoSystemProperty<T> systemProperty) {
System.clearProperty(systemProperty.propertyName());
if (systemProperty instanceof CachedProperty) {
((CachedProperty) systemProperty).clear();
}
}
public long getMaterialUpdateIdleInterval() {
return MATERIAL_UPDATE_IDLE_INTERVAL.getValue();
}
public boolean isDefaultDbProvider() {
return GO_DATABASE_PROVIDER.getValue().equals(H2_DATABASE);
}
public String getDatabaseProvider() {
return GO_DATABASE_PROVIDER.getValue();
}
public String landingPage() {
return GO_LANDING_PAGE.getValue();
}
public boolean usingJetty9() {
return get(APP_SERVER).equals(JETTY9);
}
public boolean isServerActive() {
return GO_SERVER_STATE.getValue().equalsIgnoreCase("active");
}
public void switchToActiveState() {
set(GO_SERVER_STATE, "active");
}
public void switchToPassiveState() {
set(GO_SERVER_STATE, "passive");
}
public String getUpdateServerPublicKeyPath() {
return String.format("%s/%s", getConfigDir(), GO_UPDATE_SERVER_PUBLIC_KEY_FILE_NAME.getValue());
}
public boolean isGOUpdateCheckEnabled() {
return GO_CHECK_UPDATES.getValue();
}
public boolean isFetchArtifactTemplateAutoSuggestEnabled() {
return GO_FETCH_ARTIFACT_TEMPLATE_AUTO_SUGGEST.getValue();
}
public String getUpdateServerUrl() {
return GO_UPDATE_SERVER_URL.getValue();
}
public boolean isWebsocketsForAgentsEnabled() {
return WEBSOCKET_ENABLED.getValue();
}
public boolean isConsoleLogsThroughWebsocketEnabled() {
return CONSOLE_LOGS_THROUGH_WEBSOCKET_ENABLED.getValue();
}
public boolean isAutoRegisterLocalAgentEnabled() {
return AUTO_REGISTER_LOCAL_AGENT_ENABLED.getValue();
}
public boolean isPluginUploadEnabled() {
return PLUGIN_UPLOAD_ENABLED.getValue();
}
public Long getWebsocketMaxIdleTime() {
return GO_WEBSOCKET_MAX_IDLE_TIME.getValue();
}
public Long getWebsocketAckMessageTimeout() {
return GO_WEBSOCKET_ACK_MESSAGE_TIMEOUT.getValue();
}
public Integer getWebsocketSendRetryCount() {
return GO_WEBSOCKET_SEND_RETRY_COUNT.getValue();
}
public Long getConfigGitGCExpireTime() {
Long hour = GO_CONFIG_REPO_GC_EXPIRE.getValue();
return hour * 60 * 60 * 1000;
}
public boolean isApiSafeModeEnabled() {
return GO_API_WITH_SAFE_MODE.getValue();
}
public boolean useSslContext() {
return GO_AGENT_USE_SSL_CONTEXT.getValue();
}
public boolean isBuildCommandProtocolEnabled() {
return Boolean.valueOf(get(SystemEnvironment.ENABLE_BUILD_COMMAND_PROTOCOL));
}
public String getAgentKeyStorePassword() {
return get(SystemEnvironment.GO_AGENT_KEYSTORE_PASSWORD);
}
public boolean optimizeFullConfigSave() {
return OPTIMIZE_FULL_CONFIG_SAVE.getValue();
}
public boolean isProductionMode() {
return GO_SERVER_MODE.getValue().equalsIgnoreCase("production");
}
public boolean isReAuthenticationEnabled() {
return REAUTHENTICATION_ENABLED.getValue();
}
public long getReAuthenticationTimeInterval() {
return REAUTHENTICATION_TIME_INTERVAL.getValue();
}
public static abstract class GoSystemProperty<T> {
private String propertyName;
private T defaultValue;
protected GoSystemProperty(String propertyName, T defaultValue) {
this.propertyName = propertyName;
this.defaultValue = defaultValue;
}
T getValue() {
String propertyValue = System.getProperty(propertyName);
return convertValue(propertyValue, defaultValue);
}
protected abstract T convertValue(String propertyValueFromSystem, T defaultValue);
public String propertyName() {
return propertyName;
}
}
private static class GoIntSystemProperty extends GoSystemProperty<Integer> {
public GoIntSystemProperty(String propertyName, Integer defaultValue) {
super(propertyName, defaultValue);
}
@Override
protected Integer convertValue(String propertyValueFromSystem, Integer defaultValue) {
try {
return Integer.parseInt(propertyValueFromSystem);
} catch (NumberFormatException e) {
return defaultValue;
}
}
}
private static class GoLongSystemProperty extends GoSystemProperty<Long> {
public GoLongSystemProperty(String propertyName, Long defaultValue) {
super(propertyName, defaultValue);
}
@Override
protected Long convertValue(String propertyValueFromSystem, Long defaultValue) {
try {
return Long.parseLong(propertyValueFromSystem);
} catch (NumberFormatException e) {
return defaultValue;
}
}
}
private static class GoStringSystemProperty extends GoSystemProperty<String> {
public GoStringSystemProperty(String propertyName, String defaultValue) {
super(propertyName, defaultValue);
}
@Override
protected String convertValue(String propertyValueFromSystem, String defaultValue) {
return propertyValueFromSystem == null ? defaultValue : propertyValueFromSystem;
}
}
protected static class GoStringArraySystemProperty extends GoSystemProperty<String[]> {
public GoStringArraySystemProperty(String propertyName, String[] defaultValue) {
super(propertyName, defaultValue);
}
@Override
protected String[] convertValue(String propertyValueFromSystem, String[] defaultValue) {
return StringUtil.isBlank(propertyValueFromSystem) ? defaultValue : propertyValueFromSystem.trim().split("(\\s*)?,(\\s*)?");
}
}
private static class CachedProperty<T> extends GoSystemProperty<T> {
private GoSystemProperty<T> wrappedProperty;
private T cachedValue;
public CachedProperty(GoSystemProperty<T> goSystemProperty) {
super(goSystemProperty.propertyName, goSystemProperty.defaultValue);
wrappedProperty = goSystemProperty;
}
@Override
protected T convertValue(String propertyValueFromSystem, T defaultValue) {
if (cachedValue == null) {
cachedValue = wrappedProperty.convertValue(propertyValueFromSystem, defaultValue);
}
return cachedValue;
}
public void clear() {
cachedValue = null;
}
}
private static class GoBooleanSystemProperty extends GoSystemProperty<Boolean> {
public GoBooleanSystemProperty(String propertyName, Boolean defaultValue) {
super(propertyName, defaultValue);
}
@Override
protected Boolean convertValue(String propertyValueFromSystem, Boolean defaultValue) {
if (propertyValueFromSystem == null) {
return defaultValue;
}
return "Y".equalsIgnoreCase(propertyValueFromSystem) || "true".equalsIgnoreCase(propertyValueFromSystem);
}
}
}