
This is the second part of the migration to Flogger. This change migrates all classes of the 'server' module to Flogger. Classes of the 'httpd' module have been migrated by the predecessor change. Other modules continue to use slf4j. They should be migrated by follow-up changes. During this migration we try to make the log statements more consistent: - avoid string concatenation - avoid usage of String.format(...) Change-Id: I233afc8360af7fef8640394204d0d676cc0d0001 Signed-off-by: Edwin Kempin <ekempin@google.com>
378 lines
17 KiB
Java
378 lines
17 KiB
Java
// Copyright (C) 2013 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.google.gerrit.server.config;
|
|
|
|
import com.google.common.flogger.FluentLogger;
|
|
import com.google.gerrit.reviewdb.client.Project;
|
|
import com.google.gerrit.server.plugins.Plugin;
|
|
import com.google.gerrit.server.plugins.ReloadPluginListener;
|
|
import com.google.gerrit.server.project.NoSuchProjectException;
|
|
import com.google.gerrit.server.project.ProjectCache;
|
|
import com.google.gerrit.server.project.ProjectLevelConfig;
|
|
import com.google.gerrit.server.project.ProjectState;
|
|
import com.google.gerrit.server.securestore.SecureStore;
|
|
import com.google.inject.Inject;
|
|
import com.google.inject.Provider;
|
|
import com.google.inject.Singleton;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.nio.file.Path;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import org.eclipse.jgit.errors.ConfigInvalidException;
|
|
import org.eclipse.jgit.internal.storage.file.FileSnapshot;
|
|
import org.eclipse.jgit.lib.Config;
|
|
import org.eclipse.jgit.storage.file.FileBasedConfig;
|
|
import org.eclipse.jgit.util.FS;
|
|
|
|
@Singleton
|
|
public class PluginConfigFactory implements ReloadPluginListener {
|
|
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
|
|
|
private static final String EXTENSION = ".config";
|
|
|
|
private final SitePaths site;
|
|
private final Provider<Config> cfgProvider;
|
|
private final ProjectCache projectCache;
|
|
private final ProjectState.Factory projectStateFactory;
|
|
private final SecureStore secureStore;
|
|
private final Map<String, Config> pluginConfigs;
|
|
|
|
private volatile FileSnapshot cfgSnapshot;
|
|
private volatile Config cfg;
|
|
|
|
@Inject
|
|
PluginConfigFactory(
|
|
SitePaths site,
|
|
@GerritServerConfig Provider<Config> cfgProvider,
|
|
ProjectCache projectCache,
|
|
ProjectState.Factory projectStateFactory,
|
|
SecureStore secureStore) {
|
|
this.site = site;
|
|
this.cfgProvider = cfgProvider;
|
|
this.projectCache = projectCache;
|
|
this.projectStateFactory = projectStateFactory;
|
|
this.secureStore = secureStore;
|
|
|
|
this.pluginConfigs = new HashMap<>();
|
|
this.cfgSnapshot = FileSnapshot.save(site.gerrit_config.toFile());
|
|
this.cfg = cfgProvider.get();
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the 'gerrit.config' file.
|
|
*
|
|
* <p>The returned plugin configuration provides access to all parameters of the 'gerrit.config'
|
|
* file that are set in the 'plugin' subsection of the specified plugin.
|
|
*
|
|
* <p>E.g.: [plugin "my-plugin"] myKey = myValue
|
|
*
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @return the plugin configuration from the 'gerrit.config' file
|
|
*/
|
|
public PluginConfig getFromGerritConfig(String pluginName) {
|
|
return getFromGerritConfig(pluginName, false);
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the 'gerrit.config' file.
|
|
*
|
|
* <p>The returned plugin configuration provides access to all parameters of the 'gerrit.config'
|
|
* file that are set in the 'plugin' subsection of the specified plugin.
|
|
*
|
|
* <p>E.g.: [plugin "my-plugin"] myKey = myValue
|
|
*
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @param refresh if <code>true</code> it is checked if the 'gerrit.config' file was modified and
|
|
* if yes the Gerrit configuration is reloaded, if <code>false</code> the cached Gerrit
|
|
* configuration is used
|
|
* @return the plugin configuration from the 'gerrit.config' file
|
|
*/
|
|
public PluginConfig getFromGerritConfig(String pluginName, boolean refresh) {
|
|
if (refresh && secureStore.isOutdated()) {
|
|
secureStore.reload();
|
|
}
|
|
File configFile = site.gerrit_config.toFile();
|
|
if (refresh && cfgSnapshot.isModified(configFile)) {
|
|
cfgSnapshot = FileSnapshot.save(configFile);
|
|
cfg = cfgProvider.get();
|
|
}
|
|
return new PluginConfig(pluginName, cfg);
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the 'project.config' file
|
|
* of the specified project.
|
|
*
|
|
* <p>The returned plugin configuration provides access to all parameters of the 'project.config'
|
|
* file that are set in the 'plugin' subsection of the specified plugin.
|
|
*
|
|
* <p>E.g.: [plugin "my-plugin"] myKey = myValue
|
|
*
|
|
* @param projectName the name of the project for which the plugin configuration should be
|
|
* returned
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @return the plugin configuration from the 'project.config' file of the specified project
|
|
* @throws NoSuchProjectException thrown if the specified project does not exist
|
|
*/
|
|
public PluginConfig getFromProjectConfig(Project.NameKey projectName, String pluginName)
|
|
throws NoSuchProjectException {
|
|
ProjectState projectState = projectCache.get(projectName);
|
|
if (projectState == null) {
|
|
throw new NoSuchProjectException(projectName);
|
|
}
|
|
return getFromProjectConfig(projectState, pluginName);
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the 'project.config' file
|
|
* of the specified project.
|
|
*
|
|
* <p>The returned plugin configuration provides access to all parameters of the 'project.config'
|
|
* file that are set in the 'plugin' subsection of the specified plugin.
|
|
*
|
|
* <p>E.g.: [plugin "my-plugin"] myKey = myValue
|
|
*
|
|
* @param projectState the project for which the plugin configuration should be returned
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @return the plugin configuration from the 'project.config' file of the specified project
|
|
*/
|
|
public PluginConfig getFromProjectConfig(ProjectState projectState, String pluginName) {
|
|
return projectState.getConfig().getPluginConfig(pluginName);
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the 'project.config' file
|
|
* of the specified project. Parameters which are not set in the 'project.config' of this project
|
|
* are inherited from the parent project's 'project.config' files.
|
|
*
|
|
* <p>The returned plugin configuration provides access to all parameters of the 'project.config'
|
|
* file that are set in the 'plugin' subsection of the specified plugin.
|
|
*
|
|
* <p>E.g.: child project: [plugin "my-plugin"] myKey = childValue
|
|
*
|
|
* <p>parent project: [plugin "my-plugin"] myKey = parentValue anotherKey = someValue
|
|
*
|
|
* <p>return: [plugin "my-plugin"] myKey = childValue anotherKey = someValue
|
|
*
|
|
* @param projectName the name of the project for which the plugin configuration should be
|
|
* returned
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @return the plugin configuration from the 'project.config' file of the specified project with
|
|
* inherited non-set parameters from the parent projects
|
|
* @throws NoSuchProjectException thrown if the specified project does not exist
|
|
*/
|
|
public PluginConfig getFromProjectConfigWithInheritance(
|
|
Project.NameKey projectName, String pluginName) throws NoSuchProjectException {
|
|
return getFromProjectConfig(projectName, pluginName).withInheritance(projectStateFactory);
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the 'project.config' file
|
|
* of the specified project. Parameters which are not set in the 'project.config' of this project
|
|
* are inherited from the parent project's 'project.config' files.
|
|
*
|
|
* <p>The returned plugin configuration provides access to all parameters of the 'project.config'
|
|
* file that are set in the 'plugin' subsection of the specified plugin.
|
|
*
|
|
* <p>E.g.: child project: [plugin "my-plugin"] myKey = childValue
|
|
*
|
|
* <p>parent project: [plugin "my-plugin"] myKey = parentValue anotherKey = someValue
|
|
*
|
|
* <p>return: [plugin "my-plugin"] myKey = childValue anotherKey = someValue
|
|
*
|
|
* @param projectState the project for which the plugin configuration should be returned
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @return the plugin configuration from the 'project.config' file of the specified project with
|
|
* inherited non-set parameters from the parent projects
|
|
*/
|
|
public PluginConfig getFromProjectConfigWithInheritance(
|
|
ProjectState projectState, String pluginName) {
|
|
return getFromProjectConfig(projectState, pluginName).withInheritance(projectStateFactory);
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the plugin configuration
|
|
* file '{@code etc/<plugin-name>.config}'.
|
|
*
|
|
* <p>The plugin configuration is only loaded once and is then cached.
|
|
*
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @return the plugin configuration from the '{@code etc/<plugin-name>.config}' file
|
|
*/
|
|
public synchronized Config getGlobalPluginConfig(String pluginName) {
|
|
if (pluginConfigs.containsKey(pluginName)) {
|
|
return pluginConfigs.get(pluginName);
|
|
}
|
|
|
|
Path pluginConfigFile = site.etc_dir.resolve(pluginName + ".config");
|
|
FileBasedConfig cfg = new FileBasedConfig(pluginConfigFile.toFile(), FS.DETECTED);
|
|
GlobalPluginConfig pluginConfig = new GlobalPluginConfig(pluginName, cfg, secureStore);
|
|
pluginConfigs.put(pluginName, pluginConfig);
|
|
if (!cfg.getFile().exists()) {
|
|
logger.atInfo().log("No %s; assuming defaults", pluginConfigFile.toAbsolutePath());
|
|
return pluginConfig;
|
|
}
|
|
|
|
try {
|
|
cfg.load();
|
|
} catch (ConfigInvalidException e) {
|
|
// This is an error in user input, don't spam logs with a stack trace.
|
|
logger.atWarning().log("Failed to load %s: %s", pluginConfigFile.toAbsolutePath(), e);
|
|
} catch (IOException e) {
|
|
logger.atWarning().withCause(e).log("Failed to load %s", pluginConfigFile.toAbsolutePath());
|
|
}
|
|
|
|
return pluginConfig;
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the '{@code
|
|
* <plugin-name>.config}' file in the 'refs/meta/config' branch of the specified project.
|
|
*
|
|
* @param projectName the name of the project for which the plugin configuration should be
|
|
* returned
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @return the plugin configuration from the '{@code <plugin-name>.config}' file of the specified
|
|
* project
|
|
* @throws NoSuchProjectException thrown if the specified project does not exist
|
|
*/
|
|
public Config getProjectPluginConfig(Project.NameKey projectName, String pluginName)
|
|
throws NoSuchProjectException {
|
|
return getPluginConfig(projectName, pluginName).get();
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the '{@code
|
|
* <plugin-name>.config}' file in the 'refs/meta/config' branch of the specified project.
|
|
*
|
|
* @param projectState the project for which the plugin configuration should be returned
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @return the plugin configuration from the '{@code <plugin-name>.config}' file of the specified
|
|
* project
|
|
*/
|
|
public Config getProjectPluginConfig(ProjectState projectState, String pluginName) {
|
|
return projectState.getConfig(pluginName + EXTENSION).get();
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the '{@code
|
|
* <plugin-name>.config}' file in the 'refs/meta/config' branch of the specified project.
|
|
* Parameters which are not set in the '{@code <plugin-name>.config}' of this project are
|
|
* inherited from the parent project's '{@code <plugin-name>.config}' files.
|
|
*
|
|
* <p>E.g.: child project: [mySection "mySubsection"] myKey = childValue
|
|
*
|
|
* <p>parent project: [mySection "mySubsection"] myKey = parentValue anotherKey = someValue
|
|
*
|
|
* <p>return: [mySection "mySubsection"] myKey = childValue anotherKey = someValue
|
|
*
|
|
* @param projectName the name of the project for which the plugin configuration should be
|
|
* returned
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @return the plugin configuration from the '{@code <plugin-name>.config}' file of the specified
|
|
* project with inheriting non-set parameters from the parent projects
|
|
* @throws NoSuchProjectException thrown if the specified project does not exist
|
|
*/
|
|
public Config getProjectPluginConfigWithInheritance(
|
|
Project.NameKey projectName, String pluginName) throws NoSuchProjectException {
|
|
return getPluginConfig(projectName, pluginName).getWithInheritance(false);
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the '{@code
|
|
* <plugin-name>.config}' file in the 'refs/meta/config' branch of the specified project.
|
|
* Parameters which are not set in the '{@code <plugin-name>.config}' of this project are
|
|
* inherited from the parent project's '{@code <plugin-name>.config}' files.
|
|
*
|
|
* <p>E.g.: child project: [mySection "mySubsection"] myKey = childValue
|
|
*
|
|
* <p>parent project: [mySection "mySubsection"] myKey = parentValue anotherKey = someValue
|
|
*
|
|
* <p>return: [mySection "mySubsection"] myKey = childValue anotherKey = someValue
|
|
*
|
|
* @param projectState the project for which the plugin configuration should be returned
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @return the plugin configuration from the '{@code <plugin-name>.config}' file of the specified
|
|
* project with inheriting non-set parameters from the parent projects
|
|
*/
|
|
public Config getProjectPluginConfigWithInheritance(
|
|
ProjectState projectState, String pluginName) {
|
|
return projectState.getConfig(pluginName + EXTENSION).getWithInheritance(false);
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the '{@code
|
|
* <plugin-name>.config}' file in the 'refs/meta/config' branch of the specified project.
|
|
* Parameters from the '{@code <plugin-name>.config}' of the parent project are appended to this
|
|
* project's '{@code <plugin-name>.config}' files.
|
|
*
|
|
* <p>E.g.: child project: [mySection "mySubsection"] myKey = childValue
|
|
*
|
|
* <p>parent project: [mySection "mySubsection"] myKey = parentValue anotherKey = someValue
|
|
*
|
|
* <p>return: [mySection "mySubsection"] myKey = childValue myKey = parentValue anotherKey =
|
|
* someValue
|
|
*
|
|
* @param projectName the name of the project for which the plugin configuration should be
|
|
* returned
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @return the plugin configuration from the '{@code <plugin-name>.config}' file of the specified
|
|
* project with parameters from the parent projects appended to the project values
|
|
* @throws NoSuchProjectException thrown if the specified project does not exist
|
|
*/
|
|
public Config getProjectPluginConfigWithMergedInheritance(
|
|
Project.NameKey projectName, String pluginName) throws NoSuchProjectException {
|
|
return getPluginConfig(projectName, pluginName).getWithInheritance(true);
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration for the specified plugin that is stored in the '{@code
|
|
* <plugin-name>.config}' file in the 'refs/meta/config' branch of the specified project.
|
|
* Parameters from the '{@code <plugin-name>.config}' of the parent project are appended to this
|
|
* project's '{@code <plugin-name>.config}' files.
|
|
*
|
|
* <p>E.g.: child project: [mySection "mySubsection"] myKey = childValue
|
|
*
|
|
* <p>parent project: [mySection "mySubsection"] myKey = parentValue anotherKey = someValue
|
|
*
|
|
* <p>return: [mySection "mySubsection"] myKey = childValue myKey = parentValue anotherKey =
|
|
* someValue
|
|
*
|
|
* @param projectState the project for which the plugin configuration should be returned
|
|
* @param pluginName the name of the plugin for which the configuration should be returned
|
|
* @return the plugin configuration from the '{@code <plugin-name>.config}' file of the specified
|
|
* project with inheriting non-set parameters from the parent projects
|
|
*/
|
|
public Config getProjectPluginConfigWithMergedInheritance(
|
|
ProjectState projectState, String pluginName) {
|
|
return projectState.getConfig(pluginName + EXTENSION).getWithInheritance(true);
|
|
}
|
|
|
|
private ProjectLevelConfig getPluginConfig(Project.NameKey projectName, String pluginName)
|
|
throws NoSuchProjectException {
|
|
ProjectState projectState = projectCache.get(projectName);
|
|
if (projectState == null) {
|
|
throw new NoSuchProjectException(projectName);
|
|
}
|
|
return projectState.getConfig(pluginName + EXTENSION);
|
|
}
|
|
|
|
@Override
|
|
public synchronized void onReloadPlugin(Plugin oldPlugin, Plugin newPlugin) {
|
|
pluginConfigs.remove(oldPlugin.getName());
|
|
}
|
|
}
|