| // Copyright (C) 2020 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.gerritforge.gerrit.globalrefdb.validation.dfsrefdb; |
| |
| import static com.google.common.base.Suppliers.memoize; |
| |
| import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbConfiguration; |
| import com.google.common.base.MoreObjects; |
| import com.google.common.base.Splitter; |
| import com.google.common.base.Supplier; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.inject.Inject; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| /** |
| * Implementation of the {@link SharedRefEnforcement} interface which derives project and |
| * project/ref enforcement policy from the configuration of the libModule consuming this library |
| */ |
| public class CustomSharedRefEnforcementByProject implements SharedRefEnforcement { |
| private static final String ALL = ".*"; |
| |
| private final Supplier<Map<String, Map<String, EnforcePolicy>>> predefEnforcements; |
| |
| /** |
| * Constructs a {@code CustomSharedRefEnforcementByProject} with the values specified in the |
| * configuration of the libModule consuming this library |
| * |
| * @param config the libModule configuration |
| */ |
| @Inject |
| public CustomSharedRefEnforcementByProject(SharedRefDbConfiguration config) { |
| this.predefEnforcements = memoize(() -> parseDryRunEnforcementsToMap(config)); |
| } |
| |
| private static Map<String, Map<String, EnforcePolicy>> parseDryRunEnforcementsToMap( |
| SharedRefDbConfiguration config) { |
| Map<String, Map<String, EnforcePolicy>> enforcementMap = new HashMap<>(); |
| |
| for (Map.Entry<EnforcePolicy, String> enforcementEntry : |
| config.getSharedRefDb().getEnforcementRules().entries()) { |
| parseEnforcementEntry(enforcementMap, enforcementEntry); |
| } |
| |
| return enforcementMap; |
| } |
| |
| private static void parseEnforcementEntry( |
| Map<String, Map<String, EnforcePolicy>> enforcementMap, |
| Map.Entry<EnforcePolicy, String> enforcementEntry) { |
| Iterator<String> projectAndRef = Splitter.on(':').split(enforcementEntry.getValue()).iterator(); |
| EnforcePolicy enforcementPolicy = enforcementEntry.getKey(); |
| |
| if (projectAndRef.hasNext()) { |
| String projectName = emptyToAll(projectAndRef.next()); |
| String refName = emptyToAll(projectAndRef.hasNext() ? projectAndRef.next() : ALL); |
| |
| Map<String, EnforcePolicy> existingOrDefaultRef = |
| enforcementMap.getOrDefault(projectName, new HashMap<>()); |
| |
| existingOrDefaultRef.put(refName, enforcementPolicy); |
| |
| enforcementMap.put(projectName, existingOrDefaultRef); |
| } |
| } |
| |
| private static String emptyToAll(String value) { |
| return value.trim().isEmpty() ? ALL : value; |
| } |
| |
| /** |
| * The enforcement policy for 'refName' in 'projectName' as computed from the libModule's |
| * configuration file. |
| * |
| * <p>By default all projects are REQUIRED to be consistent on all refs. |
| * |
| * @param projectName project to be enforced |
| * @param refName ref name to be enforced |
| * @return the enforcement policy for this project/ref |
| */ |
| @Override |
| public EnforcePolicy getPolicy(String projectName, String refName) { |
| if (isRefToBeIgnoredBySharedRefDb(refName)) { |
| return EnforcePolicy.IGNORED; |
| } |
| |
| return getRefEnforcePolicy(projectName, refName); |
| } |
| |
| private EnforcePolicy getRefEnforcePolicy(String projectName, String refName) { |
| Map<String, EnforcePolicy> orDefault = |
| predefEnforcements |
| .get() |
| .getOrDefault( |
| projectName, predefEnforcements.get().getOrDefault(ALL, ImmutableMap.of())); |
| |
| return MoreObjects.firstNonNull( |
| orDefault.getOrDefault(refName, orDefault.get(ALL)), EnforcePolicy.REQUIRED); |
| } |
| |
| /** |
| * The enforcement policy for 'projectName' as computed from the libModule's configuration file. |
| * |
| * <p>By default all projects are REQUIRED to be consistent on all refs. |
| * |
| * @param projectName the name of the project to get the policy for |
| * @return the enforcement policy for the project |
| */ |
| @Override |
| public EnforcePolicy getPolicy(String projectName) { |
| Map<String, EnforcePolicy> policiesForProject = |
| predefEnforcements |
| .get() |
| .getOrDefault( |
| projectName, predefEnforcements.get().getOrDefault(ALL, ImmutableMap.of())); |
| return policiesForProject.getOrDefault(ALL, EnforcePolicy.REQUIRED); |
| } |
| } |