| // Copyright (C) 2019 The Android Open Source Project |
| // |
| // 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.googlesource.gerrit.plugins.healthcheck; |
| |
| import static com.google.common.base.Preconditions.checkNotNull; |
| import static com.googlesource.gerrit.plugins.healthcheck.check.HealthCheckNames.QUERYCHANGES; |
| |
| import com.google.common.annotations.VisibleForTesting; |
| import com.google.common.base.MoreObjects; |
| import com.google.common.base.Strings; |
| import com.google.gerrit.entities.Project; |
| import com.google.gerrit.extensions.annotations.PluginName; |
| import com.google.gerrit.server.config.AllProjectsName; |
| import com.google.gerrit.server.config.AllUsersName; |
| import com.google.gerrit.server.config.GerritIsReplica; |
| import com.google.gerrit.server.config.PluginConfigFactory; |
| import com.google.inject.Inject; |
| import com.google.inject.Singleton; |
| import java.util.Collections; |
| import java.util.Set; |
| import java.util.concurrent.TimeUnit; |
| import java.util.stream.Collectors; |
| import java.util.stream.Stream; |
| import org.eclipse.jgit.errors.ConfigInvalidException; |
| import org.eclipse.jgit.lib.Config; |
| |
| @Singleton |
| public class HealthCheckConfig { |
| public static final String HEALTHCHECK = "healthcheck"; |
| public static final HealthCheckConfig DEFAULT_CONFIG = new HealthCheckConfig(null); |
| private static final long HEALTHCHECK_TIMEOUT_DEFAULT = 500L; |
| private static final String QUERY_DEFAULT = "status:open"; |
| private static final int LIMIT_DEFAULT = 10; |
| private static final int ACTIVE_WORKERS_THRESHOLD_DEFAULT = 80; |
| private static final String USERNAME_DEFAULT = "healthcheck"; |
| private static final String PASSWORD_DEFAULT = ""; |
| private static final boolean HEALTH_CHECK_ENABLED_DEFAULT = true; |
| private final AllProjectsName allProjectsName; |
| private final AllUsersName allUsersName; |
| |
| private final Config config; |
| private final boolean isReplica; |
| |
| private static final Set<String> HEALTH_CHECK_DISABLED_FOR_REPLICAS = |
| Collections.singleton(QUERYCHANGES); |
| |
| @Inject |
| public HealthCheckConfig( |
| PluginConfigFactory configFactory, |
| @PluginName String pluginName, |
| AllProjectsName allProjectsName, |
| AllUsersName allUsersName, |
| @GerritIsReplica boolean isReplica) { |
| config = configFactory.getGlobalPluginConfig(pluginName); |
| this.allProjectsName = allProjectsName; |
| this.allUsersName = allUsersName; |
| this.isReplica = isReplica; |
| } |
| |
| @VisibleForTesting |
| HealthCheckConfig(String configText) { |
| config = new Config(); |
| if (!Strings.isNullOrEmpty(configText)) { |
| try { |
| config.fromText(configText); |
| } catch (ConfigInvalidException e) { |
| throw new IllegalArgumentException("Invalid configuration " + configText, e); |
| } |
| } |
| allProjectsName = new AllProjectsName("All-Projects"); |
| allUsersName = new AllUsersName("All-Users"); |
| isReplica = false; |
| } |
| |
| @VisibleForTesting |
| void fromText(String configText) throws ConfigInvalidException { |
| config.fromText(configText); |
| } |
| |
| public long getTimeout() { |
| return getTimeout(null); |
| } |
| |
| public long getTimeout(String healthCheckName) { |
| long defaultTimeout = healthCheckName == null ? HEALTHCHECK_TIMEOUT_DEFAULT : getTimeout(null); |
| return config.getTimeUnit( |
| HEALTHCHECK, healthCheckName, "timeout", defaultTimeout, TimeUnit.MILLISECONDS); |
| } |
| |
| public String getQuery(String healthCheckName) { |
| return getStringWithFallback("query", healthCheckName, QUERY_DEFAULT); |
| } |
| |
| public int getLimit(String healthCheckName) { |
| int defaultLimit = healthCheckName == null ? LIMIT_DEFAULT : getLimit(null); |
| return config.getInt(HEALTHCHECK, healthCheckName, "limit", defaultLimit); |
| } |
| |
| public int getActiveWorkersThreshold(String healthCheckName) { |
| int defaultThreshold = |
| healthCheckName == null |
| ? ACTIVE_WORKERS_THRESHOLD_DEFAULT |
| : getActiveWorkersThreshold(null); |
| return config.getInt(HEALTHCHECK, healthCheckName, "threshold", defaultThreshold); |
| } |
| |
| public Set<Project.NameKey> getJGITRepositories(String healthCheckName) { |
| Set<Project.NameKey> repos = |
| Stream.of(config.getStringList(HEALTHCHECK, healthCheckName, "project")) |
| .map(Project::nameKey) |
| .collect(Collectors.toSet()); |
| repos.add(allProjectsName); |
| repos.add(allUsersName); |
| return repos; |
| } |
| |
| public String getUsername(String healthCheckName) { |
| return getStringWithFallback("username", healthCheckName, USERNAME_DEFAULT); |
| } |
| |
| public String getPassword(String healthCheckName) { |
| return getStringWithFallback("password", healthCheckName, PASSWORD_DEFAULT); |
| } |
| |
| public boolean healthCheckEnabled(String healthCheckName) { |
| if (isReplica && HEALTH_CHECK_DISABLED_FOR_REPLICAS.contains(healthCheckName)) { |
| return false; |
| } |
| return config.getBoolean( |
| HEALTHCHECK, checkNotNull(healthCheckName), "enabled", HEALTH_CHECK_ENABLED_DEFAULT); |
| } |
| |
| private String getStringWithFallback( |
| String parameter, String healthCheckName, String defaultValue) { |
| String fallbackDefault = |
| healthCheckName == null |
| ? defaultValue |
| : getStringWithFallback(parameter, null, defaultValue); |
| return MoreObjects.firstNonNull( |
| config.getString(HEALTHCHECK, healthCheckName, parameter), fallbackDefault); |
| } |
| } |