blob: 72fe43f8ecff0855e7ca4f075f817baff13d933e [file] [log] [blame]
// Copyright (C) 2018 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.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import com.google.inject.Module;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Named;
import com.googlesource.gerrit.plugins.its.base.GlobalRulesFileName;
import com.googlesource.gerrit.plugins.its.base.PluginRulesFileName;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class ItsRulesProjectCacheImpl implements ItsRulesProjectCache {
private static final Logger log = LoggerFactory.getLogger(ItsRulesProjectCacheImpl.class);
private static final String CACHE_NAME = "its_rules_project";
private final LoadingCache<String, List<Rule>> cache;
@Inject
ItsRulesProjectCacheImpl(@Named(CACHE_NAME) LoadingCache<String, List<Rule>> cache) {
this.cache = cache;
}
@Override
public List<Rule> get(String projectName) {
try {
return cache.get(projectName);
} catch (ExecutionException e) {
log.warn("Cannot get project specific rules for project {}", projectName, e);
return ImmutableList.of();
}
}
@Override
public void evict(String projectName) {
cache.invalidate(projectName);
}
public static Module module() {
return new CacheModule() {
@Override
protected void configure() {
cache(CACHE_NAME, String.class, new TypeLiteral<List<Rule>>() {}).loader(Loader.class);
bind(ItsRulesProjectCacheImpl.class);
bind(ItsRulesProjectCache.class).to(ItsRulesProjectCacheImpl.class);
DynamicSet.bind(binder(), GitReferenceUpdatedListener.class)
.to(ItsRulesProjectCacheRefresher.class);
}
};
}
static class Loader extends CacheLoader<String, List<Rule>> {
private final String globalRulesFileName;
private final String pluginRulesFileName;
private final ProjectCache projectCache;
private final RulesConfigReader rulesConfigReader;
@Inject
Loader(
@GlobalRulesFileName String globalRulesFileName,
@PluginRulesFileName String pluginRulesFileName,
ProjectCache projectCache,
RulesConfigReader rulesConfigReader) {
this.globalRulesFileName = globalRulesFileName;
this.pluginRulesFileName = pluginRulesFileName;
this.projectCache = projectCache;
this.rulesConfigReader = rulesConfigReader;
}
@Override
public List<Rule> load(String projectName) throws IOException {
ProjectState project = projectCache.checkedGet(Project.nameKey(projectName));
List<Rule> projectRules = readRulesFrom(project);
if (projectRules.isEmpty()) {
for (ProjectState parent : project.parents()) {
projectRules = readRulesFrom(parent);
if (!projectRules.isEmpty()) {
break;
}
}
}
return projectRules;
}
private List<Rule> readRulesFrom(ProjectState project) {
Config general = project.getConfig(globalRulesFileName).get();
Config pluginSpecific = project.getConfig(pluginRulesFileName).get();
return new ImmutableList.Builder<Rule>()
.addAll(rulesConfigReader.getRulesFromConfig(general))
.addAll(rulesConfigReader.getRulesFromConfig(pluginSpecific))
.build();
}
}
}