Line data Source code
1 : // Copyright (C) 2015 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.git.receive; 16 : 17 : import static com.google.gerrit.server.quota.QuotaGroupDefinitions.REPOSITORY_SIZE_GROUP; 18 : 19 : import com.google.common.flogger.FluentLogger; 20 : import com.google.gerrit.entities.Project; 21 : import com.google.gerrit.server.CurrentUser; 22 : import com.google.gerrit.server.plugincontext.PluginSetContext; 23 : import com.google.gerrit.server.quota.QuotaBackend; 24 : import com.google.gerrit.server.quota.QuotaResponse; 25 : import com.google.inject.Inject; 26 : import com.google.inject.assistedinject.Assisted; 27 : import java.util.Collection; 28 : import org.eclipse.jgit.transport.PostReceiveHook; 29 : import org.eclipse.jgit.transport.ReceiveCommand; 30 : import org.eclipse.jgit.transport.ReceivePack; 31 : 32 : /** 33 : * Class is responsible for calling all registered post-receive hooks. In addition, in case when 34 : * repository size quota is defined, it requests tokens (pack size) that were received. This is the 35 : * final step of enforcing repository size quota that deducts token from available tokens. 36 : */ 37 : public class LazyPostReceiveHookChain implements PostReceiveHook { 38 : interface Factory { 39 : LazyPostReceiveHookChain create(CurrentUser user, Project.NameKey project); 40 : } 41 : 42 97 : private static final FluentLogger logger = FluentLogger.forEnclosingClass(); 43 : 44 : private final PluginSetContext<PostReceiveHook> hooks; 45 : private final QuotaBackend quotaBackend; 46 : private final CurrentUser user; 47 : private final Project.NameKey project; 48 : 49 : @Inject 50 : LazyPostReceiveHookChain( 51 : PluginSetContext<PostReceiveHook> hooks, 52 : QuotaBackend quotaBackend, 53 : @Assisted CurrentUser user, 54 97 : @Assisted Project.NameKey project) { 55 97 : this.hooks = hooks; 56 97 : this.quotaBackend = quotaBackend; 57 97 : this.user = user; 58 97 : this.project = project; 59 97 : } 60 : 61 : @Override 62 : public void onPostReceive(ReceivePack rp, Collection<ReceiveCommand> commands) { 63 9 : hooks.runEach(h -> h.onPostReceive(rp, commands)); 64 9 : if (affectsSize(rp)) { 65 2 : QuotaResponse.Aggregated a = 66 : quotaBackend 67 2 : .user(user) 68 2 : .project(project) 69 2 : .requestTokens(REPOSITORY_SIZE_GROUP, rp.getPackSize()); 70 2 : if (a.hasError()) { 71 0 : String msg = 72 0 : String.format( 73 : "%s request failed for project %s with [%s]", 74 0 : REPOSITORY_SIZE_GROUP, project, a.errorMessage()); 75 0 : logger.atWarning().log("%s", msg); 76 0 : throw new RuntimeException(msg); 77 : } 78 : } 79 9 : } 80 : 81 : public static boolean affectsSize(ReceivePack rp) { 82 97 : return rp.hasReceivedPack() && rp.getPackSize() > 0L; 83 : } 84 : }