| // 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.googlesource.gerrit.plugins.its.base.workflow; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.inject.Inject; |
| import com.googlesource.gerrit.plugins.its.base.GlobalRulesFileName; |
| import com.googlesource.gerrit.plugins.its.base.ItsPath; |
| import com.googlesource.gerrit.plugins.its.base.PluginRulesFileName; |
| import java.io.File; |
| import java.io.IOException; |
| import java.nio.file.Path; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Map; |
| import org.eclipse.jgit.errors.ConfigInvalidException; |
| import org.eclipse.jgit.storage.file.FileBasedConfig; |
| import org.eclipse.jgit.util.FS; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** Collection and matcher against {@link Rule}s. */ |
| public class RuleBase { |
| private static final Logger log = LoggerFactory.getLogger(RuleBase.class); |
| |
| private final File globalRuleFile; |
| private final File itsSpecificRuleFile; |
| private final ItsRulesProjectCache rulesProjectCache; |
| |
| private Collection<Rule> rules; |
| |
| public interface Factory { |
| RuleBase create(); |
| } |
| |
| @Inject |
| public RuleBase( |
| @ItsPath Path itsPath, |
| @GlobalRulesFileName String globalRulesFileName, |
| @PluginRulesFileName String pluginRulesFileName, |
| ItsRulesProjectCache rulesProjectCache, |
| RulesConfigReader rulesConfigReader) { |
| this.globalRuleFile = itsPath.resolve(globalRulesFileName).toFile(); |
| this.itsSpecificRuleFile = itsPath.resolve(pluginRulesFileName).toFile(); |
| this.rulesProjectCache = rulesProjectCache; |
| this.rules = |
| new ImmutableList.Builder<Rule>() |
| .addAll(getRulesFromFile(rulesConfigReader, globalRuleFile)) |
| .addAll(getRulesFromFile(rulesConfigReader, itsSpecificRuleFile)) |
| .build(); |
| } |
| |
| /** |
| * Gets rules from a file. |
| * |
| * <p>If the given file does not exist, it is silently ignored |
| * |
| * @param rulesConfigReader The rules reader |
| * @param ruleFile File from which to read the rules |
| * @return A collection of rules or an empty collection if the file does not exist or contains an |
| * invalid configuration |
| */ |
| private static Collection<Rule> getRulesFromFile( |
| RulesConfigReader rulesConfigReader, File ruleFile) { |
| if (ruleFile.exists()) { |
| FileBasedConfig cfg = new FileBasedConfig(ruleFile, FS.DETECTED); |
| try { |
| cfg.load(); |
| return rulesConfigReader.getRulesFromConfig(cfg); |
| } catch (IOException | ConfigInvalidException e) { |
| log.error("Invalid ITS action configuration", e); |
| } |
| } |
| return Collections.emptyList(); |
| } |
| |
| /** |
| * Gets the action requests for a set of properties. |
| * |
| * @param properties The properties to search actions for. |
| * @return Requests for the actions that should be fired. |
| */ |
| public Collection<ActionRequest> actionRequestsFor(Map<String, String> properties) { |
| String projectName = properties.get("project"); |
| Collection<Rule> fromProjectConfig = rulesProjectCache.get(projectName); |
| Collection<Rule> rulesToAdd = !fromProjectConfig.isEmpty() ? fromProjectConfig : rules; |
| if (rulesToAdd.isEmpty() && !globalRuleFile.exists() && !itsSpecificRuleFile.exists()) { |
| log.warn( |
| "Neither global rule file {} nor Its specific rule file {} exist and no rules are " |
| + "configured for project {}. Please configure rules.", |
| globalRuleFile, |
| itsSpecificRuleFile, |
| projectName); |
| return Collections.emptyList(); |
| } |
| Collection<ActionRequest> actions = new ArrayList<>(); |
| for (Rule rule : rulesToAdd) { |
| actions.addAll(rule.actionRequestsFor(properties)); |
| } |
| return actions; |
| } |
| } |