Search in sources :

Example 1 with SubmissionExecutor

use of com.google.gerrit.server.update.SubmissionExecutor in project gerrit by GerritCodeReview.

the class MergeOp method merge.

/**
 * Merges the given change.
 *
 * <p>Depending on the server configuration, more changes may be affected, e.g. by submission of a
 * topic or via superproject subscriptions. All affected changes are integrated using the projects
 * integration strategy.
 *
 * @param change the change to be merged.
 * @param caller the identity of the caller
 * @param checkSubmitRules whether the prolog submit rules should be evaluated
 * @param submitInput parameters regarding the merge
 * @throws RestApiException if an error occurred.
 * @throws PermissionBackendException if permissions can't be checked
 * @throws IOException an error occurred reading from NoteDb.
 * @return the merged change
 */
public Change merge(Change change, IdentifiedUser caller, boolean checkSubmitRules, SubmitInput submitInput, boolean dryrun) throws RestApiException, UpdateException, IOException, ConfigInvalidException, PermissionBackendException {
    this.submitInput = submitInput;
    this.notify = notifyResolver.resolve(firstNonNull(submitInput.notify, NotifyHandling.ALL), submitInput.notifyDetails);
    this.dryrun = dryrun;
    this.caller = caller;
    this.ts = TimeUtil.now();
    this.submissionId = new SubmissionId(change);
    try (TraceContext traceContext = TraceContext.open().addTag(RequestId.Type.SUBMISSION_ID, new RequestId(submissionId.toString()))) {
        openRepoManager();
        logger.atFine().log("Beginning integration of %s", change);
        try {
            ChangeSet indexBackedChangeSet = mergeSuperSet.setMergeOpRepoManager(orm).completeChangeSet(change, caller, /* includingTopicClosure= */
            false);
            if (!indexBackedChangeSet.ids().contains(change.getId())) {
                // indexBackedChangeSet contains only open changes, if the change is missing in this set
                // it might be that the change was concurrently submitted in the meantime.
                change = changeDataFactory.create(change).reloadChange();
                if (!change.isNew()) {
                    throw new ResourceConflictException("change is " + ChangeUtil.status(change));
                }
                throw new IllegalStateException(String.format("change %s missing from %s", change.getId(), indexBackedChangeSet));
            }
            if (indexBackedChangeSet.furtherHiddenChanges()) {
                throw new AuthException("A change to be submitted with " + change.getId() + " is not visible");
            }
            logger.atFine().log("Calculated to merge %s", indexBackedChangeSet);
            // Reload ChangeSet so that we don't rely on (potentially) stale index data for merging
            ChangeSet noteDbChangeSet = reloadChanges(indexBackedChangeSet);
            // At this point, any change that isn't new can be filtered out since they were only here
            // in the first place due to stale index.
            List<ChangeData> filteredChanges = new ArrayList<>();
            for (ChangeData changeData : noteDbChangeSet.changes()) {
                if (!changeData.change().getStatus().equals(Status.NEW)) {
                    logger.atFine().log("Change %s has status %s due to stale index, so it is skipped during submit", changeData.getId(), changeData.change().getStatus().name());
                    continue;
                }
                filteredChanges.add(changeData);
            }
            // There are no hidden changes (or else we would have thrown AuthException above).
            ChangeSet filteredNoteDbChangeSet = new ChangeSet(filteredChanges, /* hiddenChanges= */
            ImmutableList.of());
            // Count cross-project submissions outside of the retry loop. The chance of a single project
            // failing increases with the number of projects, so the failure count would be inflated if
            // this metric were incremented inside of integrateIntoHistory.
            int projects = filteredNoteDbChangeSet.projects().size();
            if (projects > 1) {
                topicMetrics.topicSubmissions.increment();
            }
            SubmissionExecutor submissionExecutor = new SubmissionExecutor(dryrun, superprojectUpdateSubmissionListeners);
            RetryTracker retryTracker = new RetryTracker();
            retryHelper.changeUpdate("integrateIntoHistory", updateFactory -> {
                long attempt = retryTracker.lastAttemptNumber + 1;
                boolean isRetry = attempt > 1;
                if (isRetry) {
                    logger.atFine().log("Retrying, attempt #%d; skipping merged changes", attempt);
                    this.ts = TimeUtil.now();
                    openRepoManager();
                }
                this.commitStatus = new CommitStatus(filteredNoteDbChangeSet, isRetry);
                if (checkSubmitRules) {
                    logger.atFine().log("Checking submit rules and state");
                    checkSubmitRulesAndState(filteredNoteDbChangeSet, isRetry);
                } else {
                    logger.atFine().log("Bypassing submit rules");
                    bypassSubmitRulesAndRequirements(filteredNoteDbChangeSet);
                }
                integrateIntoHistory(filteredNoteDbChangeSet, submissionExecutor);
                return null;
            }).listener(retryTracker).defaultTimeoutMultiplier(filteredNoteDbChangeSet.projects().size() * 2).retryOn(t -> t instanceof RuntimeException).call();
            submissionExecutor.afterExecutions(orm);
            if (projects > 1) {
                topicMetrics.topicSubmissionsCompleted.increment();
            }
            // (e.g. caller provided a change that was already merged).
            return updatedChanges.containsKey(change.getId()) ? updatedChanges.get(change.getId()) : change;
        } catch (IOException e) {
            // Anything before the merge attempt is an error
            throw new StorageException(e);
        }
    }
}
Also used : ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) SuperprojectUpdateOnSubmission(com.google.gerrit.server.update.SuperprojectUpdateOnSubmission) ListMultimap(com.google.common.collect.ListMultimap) MultimapBuilder(com.google.common.collect.MultimapBuilder) InternalUser(com.google.gerrit.server.InternalUser) Inject(com.google.inject.Inject) SubmissionId(com.google.gerrit.entities.SubmissionId) UpdateException(com.google.gerrit.server.update.UpdateException) SubmitRequirementResult(com.google.gerrit.entities.SubmitRequirementResult) MergeUpdateException(com.google.gerrit.exceptions.MergeUpdateException) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) SubmitInput(com.google.gerrit.extensions.api.changes.SubmitInput) Map(java.util.Map) AuthException(com.google.gerrit.extensions.restapi.AuthException) StoreSubmitRequirementsOp(com.google.gerrit.server.notedb.StoreSubmitRequirementsOp) RetryHelper(com.google.gerrit.server.update.RetryHelper) MergeTip(com.google.gerrit.server.git.MergeTip) Collectors.toSet(java.util.stream.Collectors.toSet) ImmutableSetMultimap(com.google.common.collect.ImmutableSetMultimap) ImmutableSet(com.google.common.collect.ImmutableSet) Status(com.google.gerrit.entities.Change.Status) ImmutableMap(com.google.common.collect.ImmutableMap) TraceContext(com.google.gerrit.server.logging.TraceContext) SubmitType(com.google.gerrit.extensions.client.SubmitType) Collection(java.util.Collection) Set(java.util.Set) Constants(org.eclipse.jgit.lib.Constants) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit) Instant(java.time.Instant) RetryListener(com.github.rholder.retry.RetryListener) SubmitRecord(com.google.gerrit.entities.SubmitRecord) Collectors(java.util.stream.Collectors) BranchNameKey(com.google.gerrit.entities.BranchNameKey) NotifyHandling(com.google.gerrit.extensions.api.changes.NotifyHandling) SubmitTypeRecord(com.google.gerrit.entities.SubmitTypeRecord) ChangeData(com.google.gerrit.server.query.change.ChangeData) List(java.util.List) Nullable(com.google.gerrit.common.Nullable) Ref(org.eclipse.jgit.lib.Ref) AutoValue(com.google.auto.value.AutoValue) InternalChangeQuery(com.google.gerrit.server.query.change.InternalChangeQuery) Optional(java.util.Optional) MoreObjects.firstNonNull(com.google.common.base.MoreObjects.firstNonNull) Counter0(com.google.gerrit.metrics.Counter0) MetricMaker(com.google.gerrit.metrics.MetricMaker) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) FluentLogger(com.google.common.flogger.FluentLogger) Joiner(com.google.common.base.Joiner) ChangeMessagesUtil(com.google.gerrit.server.ChangeMessagesUtil) Singleton(com.google.inject.Singleton) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) RevCommit(org.eclipse.jgit.revwalk.RevCommit) OpenRepo(com.google.gerrit.server.submit.MergeOpRepoManager.OpenRepo) IncorrectObjectTypeException(org.eclipse.jgit.errors.IncorrectObjectTypeException) HashMap(java.util.HashMap) Function(java.util.function.Function) SubmissionListener(com.google.gerrit.server.update.SubmissionListener) MergeValidators(com.google.gerrit.server.git.validators.MergeValidators) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ImmutableList(com.google.common.collect.ImmutableList) SubmissionExecutor(com.google.gerrit.server.update.SubmissionExecutor) Description(com.google.gerrit.metrics.Description) Objects.requireNonNull(java.util.Objects.requireNonNull) Change(com.google.gerrit.entities.Change) PatchSet(com.google.gerrit.entities.PatchSet) Comparator.comparing(java.util.Comparator.comparing) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) ChangeUtil(com.google.gerrit.server.ChangeUtil) LockFailureException(com.google.gerrit.git.LockFailureException) ChangeContext(com.google.gerrit.server.update.ChangeContext) MergeValidationException(com.google.gerrit.server.git.validators.MergeValidationException) LinkedHashSet(java.util.LinkedHashSet) SubmitRequirement(com.google.gerrit.entities.SubmitRequirement) NotifyResolver(com.google.gerrit.server.change.NotifyResolver) OpenBranch(com.google.gerrit.server.submit.MergeOpRepoManager.OpenBranch) StorageException(com.google.gerrit.exceptions.StorageException) Attempt(com.github.rholder.retry.Attempt) NoSuchProjectException(com.google.gerrit.server.project.NoSuchProjectException) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) SubmitRuleOptions(com.google.gerrit.server.project.SubmitRuleOptions) SetMultimap(com.google.common.collect.SetMultimap) ObjectId(org.eclipse.jgit.lib.ObjectId) Provider(com.google.inject.Provider) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) Project(com.google.gerrit.entities.Project) TimeUtil(com.google.gerrit.server.util.time.TimeUtil) RequestId(com.google.gerrit.server.logging.RequestId) RequestId(com.google.gerrit.server.logging.RequestId) ArrayList(java.util.ArrayList) AuthException(com.google.gerrit.extensions.restapi.AuthException) IOException(java.io.IOException) ChangeData(com.google.gerrit.server.query.change.ChangeData) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) SubmissionId(com.google.gerrit.entities.SubmissionId) TraceContext(com.google.gerrit.server.logging.TraceContext) StorageException(com.google.gerrit.exceptions.StorageException) SubmissionExecutor(com.google.gerrit.server.update.SubmissionExecutor)

Example 2 with SubmissionExecutor

use of com.google.gerrit.server.update.SubmissionExecutor in project gerrit by GerritCodeReview.

the class ReceiveCommits method handleRegularCommands.

private void handleRegularCommands(List<ReceiveCommand> cmds, MultiProgressMonitor progress) throws PermissionBackendException, IOException, NoSuchProjectException {
    try (TraceTimer traceTimer = newTimer("handleRegularCommands", Metadata.builder().resourceCount(cmds.size()))) {
        result.magicPush(false);
        for (ReceiveCommand cmd : cmds) {
            parseRegularCommand(cmd);
        }
        Map<BranchNameKey, ReceiveCommand> branches;
        try (BatchUpdate bu = batchUpdateFactory.create(project.getNameKey(), user.materializedCopy(), TimeUtil.now());
            ObjectInserter ins = repo.newObjectInserter();
            ObjectReader reader = ins.newReader();
            RevWalk rw = new RevWalk(reader);
            MergeOpRepoManager orm = ormProvider.get()) {
            bu.setRepository(repo, rw, ins);
            bu.setRefLogMessage("push");
            int added = 0;
            for (ReceiveCommand cmd : cmds) {
                if (cmd.getResult() == NOT_ATTEMPTED) {
                    bu.addRepoOnlyOp(new UpdateOneRefOp(cmd));
                    added++;
                }
            }
            logger.atFine().log("Added %d additional ref updates", added);
            SubmissionExecutor submissionExecutor = new SubmissionExecutor(false, superprojectUpdateSubmissionListeners);
            submissionExecutor.execute(ImmutableList.of(bu));
            orm.setContext(TimeUtil.now(), user, NotifyResolver.Result.none());
            submissionExecutor.afterExecutions(orm);
            branches = bu.getSuccessfullyUpdatedBranches(false);
        } catch (UpdateException | RestApiException e) {
            throw new StorageException(e);
        }
        // This could be moved into a SubmissionListener
        branches.values().stream().filter(c -> isHead(c) || isConfig(c)).forEach(c -> {
            // BatchUpdate because they involve kicking off an additional BatchUpdate.
            switch(c.getType()) {
                case CREATE:
                case UPDATE:
                case UPDATE_NONFASTFORWARD:
                    Task closeProgress = progress.beginSubTask("closed", UNKNOWN);
                    autoCloseChanges(c, closeProgress);
                    closeProgress.end();
                    break;
                case DELETE:
                    break;
            }
        });
    }
}
Also used : NotifyInfo(com.google.gerrit.extensions.api.changes.NotifyInfo) DynamicItem(com.google.gerrit.extensions.registration.DynamicItem) MultimapBuilder(com.google.common.collect.MultimapBuilder) ChangeReportFormatter(com.google.gerrit.server.git.ChangeReportFormatter) DeadlineChecker(com.google.gerrit.server.DeadlineChecker) ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) RevObject(org.eclipse.jgit.revwalk.RevObject) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) HashtagsInput(com.google.gerrit.extensions.api.changes.HashtagsInput) RevWalk(org.eclipse.jgit.revwalk.RevWalk) Config(org.eclipse.jgit.lib.Config) Future(java.util.concurrent.Future) FooterLine(org.eclipse.jgit.revwalk.FooterLine) Map(java.util.Map) UrlFormatter(com.google.gerrit.server.config.UrlFormatter) Metadata(com.google.gerrit.server.logging.Metadata) MailRecipients(com.google.gerrit.server.mail.MailUtil.MailRecipients) RevSort(org.eclipse.jgit.revwalk.RevSort) Constants(org.eclipse.jgit.lib.Constants) PublishCommentsOp(com.google.gerrit.server.PublishCommentsOp) Collectors.joining(java.util.stream.Collectors.joining) RequestListener(com.google.gerrit.server.RequestListener) PersonIdent(org.eclipse.jgit.lib.PersonIdent) TagCache(com.google.gerrit.server.git.TagCache) Stream(java.util.stream.Stream) HashtagsUtil.cleanupHashtag(com.google.gerrit.server.change.HashtagsUtil.cleanupHashtag) BooleanProjectConfig(com.google.gerrit.entities.BooleanProjectConfig) Counter3(com.google.gerrit.metrics.Counter3) PluginSetContext(com.google.gerrit.server.plugincontext.PluginSetContext) ProjectConfigEntryType(com.google.gerrit.extensions.api.projects.ProjectConfigEntryType) Counter0(com.google.gerrit.metrics.Counter0) MetricMaker(com.google.gerrit.metrics.MetricMaker) PatchSetInfo(com.google.gerrit.entities.PatchSetInfo) FluentLogger(com.google.common.flogger.FluentLogger) Joiner(com.google.common.base.Joiner) ValidationError(com.google.gerrit.server.git.ValidationError) SAME_CHANGE_ID_IN_MULTIPLE_CHANGES(com.google.gerrit.server.git.receive.ReceiveConstants.SAME_CHANGE_ID_IN_MULTIPLE_CHANGES) RevCommit(org.eclipse.jgit.revwalk.RevCommit) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) CommentsUtil(com.google.gerrit.server.CommentsUtil) RequestScopePropagator(com.google.gerrit.server.util.RequestScopePropagator) PerformanceLogger(com.google.gerrit.server.logging.PerformanceLogger) LinkedHashMap(java.util.LinkedHashMap) Strings(com.google.common.base.Strings) Lists(com.google.common.collect.Lists) SubmissionExecutor(com.google.gerrit.server.update.SubmissionExecutor) Description(com.google.gerrit.metrics.Description) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) StreamSupport(java.util.stream.StreamSupport) MagicBranch(com.google.gerrit.server.util.MagicBranch) ProjectCache.illegalState(com.google.gerrit.server.project.ProjectCache.illegalState) NotifyResolver(com.google.gerrit.server.change.NotifyResolver) ObjectIds.abbreviateName(com.google.gerrit.git.ObjectIds.abbreviateName) Throwables(com.google.common.base.Throwables) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) ChangeEdit(com.google.gerrit.server.edit.ChangeEdit) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) Project(com.google.gerrit.entities.Project) DynamicSet(com.google.gerrit.extensions.registration.DynamicSet) NOT_ATTEMPTED(org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED) LabelVote(com.google.gerrit.server.util.LabelVote) TimeUtil(com.google.gerrit.server.util.time.TimeUtil) CommentValidator(com.google.gerrit.extensions.validators.CommentValidator) ONLY_USERS_WITH_TOGGLE_WIP_STATE_PERM_CAN_MODIFY_WIP(com.google.gerrit.server.git.receive.ReceiveConstants.ONLY_USERS_WITH_TOGGLE_WIP_STATE_PERM_CAN_MODIFY_WIP) RequestCancelledException(com.google.gerrit.server.cancellation.RequestCancelledException) RequestId(com.google.gerrit.server.logging.RequestId) REJECTED_MISSING_OBJECT(org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_MISSING_OBJECT) CommentSizeValidator(com.google.gerrit.server.git.validators.CommentSizeValidator) RefPermission(com.google.gerrit.server.permissions.RefPermission) PUSH_OPTION_SKIP_VALIDATION(com.google.gerrit.server.git.receive.ReceiveConstants.PUSH_OPTION_SKIP_VALIDATION) URLDecoder(java.net.URLDecoder) ValidationMessage(com.google.gerrit.server.git.validators.ValidationMessage) Inject(com.google.inject.Inject) MissingObjectException(org.eclipse.jgit.errors.MissingObjectException) RepoOnlyOp(com.google.gerrit.server.update.RepoOnlyOp) PatchSetInfoFactory(com.google.gerrit.server.patch.PatchSetInfoFactory) UpdateException(com.google.gerrit.server.update.UpdateException) Assisted(com.google.inject.assistedinject.Assisted) ImmutableListMultimap.toImmutableListMultimap(com.google.common.collect.ImmutableListMultimap.toImmutableListMultimap) LabelType(com.google.gerrit.entities.LabelType) AuthException(com.google.gerrit.extensions.restapi.AuthException) AutoMerger(com.google.gerrit.server.patch.AutoMerger) PerformanceLogContext(com.google.gerrit.server.logging.PerformanceLogContext) PluginConfig(com.google.gerrit.server.config.PluginConfig) NoteMap(org.eclipse.jgit.notes.NoteMap) ImmutableSetMultimap(com.google.common.collect.ImmutableSetMultimap) CommentCountValidator(com.google.gerrit.server.git.validators.CommentCountValidator) BiMap(com.google.common.collect.BiMap) ImmutableSet(com.google.common.collect.ImmutableSet) SortedSetMultimap(com.google.common.collect.SortedSetMultimap) Collection(java.util.Collection) OK(org.eclipse.jgit.transport.ReceiveCommand.Result.OK) PermissionDeniedException(com.google.gerrit.server.permissions.PermissionDeniedException) Collectors(java.util.stream.Collectors) ApprovalsUtil(com.google.gerrit.server.approval.ApprovalsUtil) Objects(java.util.Objects) CmdLineException(org.kohsuke.args4j.CmdLineException) SetPrivateOp(com.google.gerrit.server.change.SetPrivateOp) ChangeData(com.google.gerrit.server.query.change.ChangeData) Nullable(com.google.gerrit.common.Nullable) AllProjectsName(com.google.gerrit.server.config.AllProjectsName) Ref(org.eclipse.jgit.lib.Ref) InternalChangeQuery(com.google.gerrit.server.query.change.InternalChangeQuery) Providers(com.google.inject.util.Providers) Queue(java.util.Queue) RefNames.isConfigRef(com.google.gerrit.entities.RefNames.isConfigRef) RequestStateContext(com.google.gerrit.server.cancellation.RequestStateContext) CommentValidationContext(com.google.gerrit.extensions.validators.CommentValidationContext) IncorrectObjectTypeException(org.eclipse.jgit.errors.IncorrectObjectTypeException) GeneralPreferencesInfo(com.google.gerrit.extensions.client.GeneralPreferencesInfo) RepoContext(com.google.gerrit.server.update.RepoContext) MergedByPushOp(com.google.gerrit.server.git.MergedByPushOp) HashSet(java.util.HashSet) ImmutableList(com.google.common.collect.ImmutableList) REFS_CHANGES(com.google.gerrit.entities.RefNames.REFS_CHANGES) Field(com.google.gerrit.metrics.Field) UsedAt(com.google.gerrit.common.UsedAt) Change(com.google.gerrit.entities.Change) ChangeUtil(com.google.gerrit.server.ChangeUtil) ChangeContext(com.google.gerrit.server.update.ChangeContext) SetTopicOp(com.google.gerrit.server.change.SetTopicOp) SetHashtagsOp(com.google.gerrit.server.change.SetHashtagsOp) UTF_8(java.nio.charset.StandardCharsets.UTF_8) ProjectState(com.google.gerrit.server.project.ProjectState) Collectors.toList(java.util.stream.Collectors.toList) HashBiMap(com.google.common.collect.HashBiMap) Provider(com.google.inject.Provider) ReceivePack(org.eclipse.jgit.transport.ReceivePack) SuperprojectUpdateOnSubmission(com.google.gerrit.server.update.SuperprojectUpdateOnSubmission) Arrays(java.util.Arrays) ProjectConfig(com.google.gerrit.server.project.ProjectConfig) ListMultimap(com.google.common.collect.ListMultimap) GroupCollector(com.google.gerrit.server.git.GroupCollector) ProjectCache(com.google.gerrit.server.project.ProjectCache) PermissionBackend(com.google.gerrit.server.permissions.PermissionBackend) InvalidDeadlineException(com.google.gerrit.server.InvalidDeadlineException) NoSuchChangeException(com.google.gerrit.server.project.NoSuchChangeException) RetryHelper(com.google.gerrit.server.update.RetryHelper) GerritServerConfig(com.google.gerrit.server.config.GerritServerConfig) TraceContext(com.google.gerrit.server.logging.TraceContext) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Set(java.util.Set) BranchNameKey(com.google.gerrit.entities.BranchNameKey) NotifyHandling(com.google.gerrit.extensions.api.changes.NotifyHandling) ProjectPermission(com.google.gerrit.server.permissions.ProjectPermission) NEW_PATCHSET_PATTERN(com.google.gerrit.server.git.validators.CommitValidators.NEW_PATCHSET_PATTERN) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) LazyArgs.lazy(com.google.common.flogger.LazyArgs.lazy) Singleton(com.google.inject.Singleton) Iterables(com.google.common.collect.Iterables) CommentType(com.google.gerrit.extensions.validators.CommentForValidation.CommentType) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) RefOperationValidationException(com.google.gerrit.server.git.validators.RefOperationValidationException) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) CommentForValidation(com.google.gerrit.extensions.validators.CommentForValidation) TraceTimer(com.google.gerrit.server.logging.TraceContext.TraceTimer) CancellationMetrics(com.google.gerrit.server.CancellationMetrics) SubmissionListener(com.google.gerrit.server.update.SubmissionListener) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) ChangeEditUtil(com.google.gerrit.server.edit.ChangeEditUtil) PatchSet(com.google.gerrit.entities.PatchSet) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) Extension(com.google.gerrit.extensions.registration.Extension) LinkedHashSet(java.util.LinkedHashSet) UNKNOWN(com.google.gerrit.server.git.MultiProgressMonitor.UNKNOWN) CommitValidationMessage(com.google.gerrit.server.git.validators.CommitValidationMessage) Sequences(com.google.gerrit.server.notedb.Sequences) CreateRefControl(com.google.gerrit.server.project.CreateRefControl) RevFilter(org.eclipse.jgit.revwalk.filter.RevFilter) AttentionSetUnchangedOp(com.google.gerrit.server.change.AttentionSetUnchangedOp) StorageException(com.google.gerrit.exceptions.StorageException) StringWriter(java.io.StringWriter) CommentValidationFailure(com.google.gerrit.extensions.validators.CommentValidationFailure) CmdLineParser(com.google.gerrit.util.cli.CmdLineParser) NoSuchProjectException(com.google.gerrit.server.project.NoSuchProjectException) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) R_HEADS(org.eclipse.jgit.lib.Constants.R_HEADS) RefOperationValidators(com.google.gerrit.server.git.validators.RefOperationValidators) DynamicMap(com.google.gerrit.extensions.registration.DynamicMap) ObjectReader(org.eclipse.jgit.lib.ObjectReader) Repository(org.eclipse.jgit.lib.Repository) REJECTED_OTHER_REASON(org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON) MailUtil.getRecipientsFromFooters(com.google.gerrit.server.mail.MailUtil.getRecipientsFromFooters) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) HumanComment(com.google.gerrit.entities.HumanComment) SubmissionId(com.google.gerrit.entities.SubmissionId) RefNames.isRefsUsersSelf(com.google.gerrit.entities.RefNames.isRefsUsersSelf) LabelTypes(com.google.gerrit.entities.LabelTypes) ChangeIndexer(com.google.gerrit.server.index.change.ChangeIndexer) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) SubmitInput(com.google.gerrit.extensions.api.changes.SubmitInput) RefNames(com.google.gerrit.entities.RefNames) COMMAND_REJECTION_MESSAGE_FOOTER(com.google.gerrit.server.git.receive.ReceiveConstants.COMMAND_REJECTION_MESSAGE_FOOTER) Splitter(com.google.common.base.Splitter) ReceivePackInitializer(com.google.gerrit.server.git.ReceivePackInitializer) LinkedListMultimap(com.google.common.collect.LinkedListMultimap) GlobalPermission(com.google.gerrit.server.permissions.GlobalPermission) Task(com.google.gerrit.server.git.MultiProgressMonitor.Task) ImmutableMap(com.google.common.collect.ImmutableMap) Account(com.google.gerrit.entities.Account) RequestInfo(com.google.gerrit.server.RequestInfo) ProjectConfigEntry(com.google.gerrit.server.config.ProjectConfigEntry) Option(org.kohsuke.args4j.Option) Streams(com.google.common.collect.Streams) Sets(com.google.common.collect.Sets) Preconditions.checkState(com.google.common.base.Preconditions.checkState) List(java.util.List) Optional(java.util.Optional) MoreObjects.firstNonNull(com.google.common.base.MoreObjects.firstNonNull) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) BanCommit(com.google.gerrit.server.git.BanCommit) CommentSource(com.google.gerrit.extensions.validators.CommentForValidation.CommentSource) PublishCommentUtil(com.google.gerrit.server.PublishCommentUtil) MultiProgressMonitor(com.google.gerrit.server.git.MultiProgressMonitor) MergeOpRepoManager(com.google.gerrit.server.submit.MergeOpRepoManager) ChangePermission(com.google.gerrit.server.permissions.ChangePermission) CreateGroupPermissionSyncer(com.google.gerrit.server.CreateGroupPermissionSyncer) HashMap(java.util.HashMap) ReplyAttentionSetUpdates(com.google.gerrit.server.restapi.change.ReplyAttentionSetUpdates) MergeOp(com.google.gerrit.server.submit.MergeOp) PostUpdateContext(com.google.gerrit.server.update.PostUpdateContext) Objects.requireNonNull(java.util.Objects.requireNonNull) ChangeInserter(com.google.gerrit.server.change.ChangeInserter) AccountResolver(com.google.gerrit.server.account.AccountResolver) Iterator(java.util.Iterator) Maps(com.google.common.collect.Maps) ObjectId(org.eclipse.jgit.lib.ObjectId) RecipientType(com.google.gerrit.extensions.api.changes.RecipientType) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) PatchSetUtil(com.google.gerrit.server.PatchSetUtil) Collections(java.util.Collections) ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) Task(com.google.gerrit.server.git.MultiProgressMonitor.Task) RevWalk(org.eclipse.jgit.revwalk.RevWalk) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) BranchNameKey(com.google.gerrit.entities.BranchNameKey) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) TraceTimer(com.google.gerrit.server.logging.TraceContext.TraceTimer) ObjectReader(org.eclipse.jgit.lib.ObjectReader) MergeOpRepoManager(com.google.gerrit.server.submit.MergeOpRepoManager) UpdateException(com.google.gerrit.server.update.UpdateException) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) StorageException(com.google.gerrit.exceptions.StorageException) SubmissionExecutor(com.google.gerrit.server.update.SubmissionExecutor)

Example 3 with SubmissionExecutor

use of com.google.gerrit.server.update.SubmissionExecutor in project gerrit by GerritCodeReview.

the class MergeOp method integrateIntoHistory.

private void integrateIntoHistory(ChangeSet cs, SubmissionExecutor submissionExecutor) throws RestApiException, UpdateException {
    checkArgument(!cs.furtherHiddenChanges(), "cannot integrate hidden changes into history");
    logger.atFine().log("Beginning merge attempt on %s", cs);
    Map<BranchNameKey, BranchBatch> toSubmit = new HashMap<>();
    ListMultimap<BranchNameKey, ChangeData> cbb;
    try {
        cbb = cs.changesByBranch();
    } catch (StorageException e) {
        throw new StorageException("Error reading changes to submit", e);
    }
    Set<BranchNameKey> branches = cbb.keySet();
    for (BranchNameKey branch : branches) {
        OpenRepo or = openRepo(branch.project());
        if (or != null) {
            toSubmit.put(branch, validateChangeList(or, cbb.get(branch)));
        }
    }
    // Done checks that don't involve running submit strategies.
    commitStatus.maybeFailVerbose();
    try {
        SubscriptionGraph subscriptionGraph = subscriptionGraphFactory.compute(branches, orm);
        SubmoduleCommits submoduleCommits = submoduleCommitsFactory.create(orm);
        UpdateOrderCalculator updateOrderCalculator = new UpdateOrderCalculator(subscriptionGraph);
        List<SubmitStrategy> strategies = getSubmitStrategies(toSubmit, updateOrderCalculator, submoduleCommits, subscriptionGraph, dryrun);
        this.allProjects = updateOrderCalculator.getProjectsInOrder();
        List<BatchUpdate> batchUpdates = orm.batchUpdates(allProjects);
        // Group batch updates by project
        Map<Project.NameKey, BatchUpdate> batchUpdatesByProject = batchUpdates.stream().collect(Collectors.toMap(b -> b.getProject(), Function.identity()));
        for (Map.Entry<Change.Id, ChangeData> entry : cs.changesById().entrySet()) {
            Project.NameKey project = entry.getValue().project();
            Change.Id changeId = entry.getKey();
            ChangeData cd = entry.getValue();
            batchUpdatesByProject.get(project).addOp(changeId, storeSubmitRequirementsOpFactory.create(cd.submitRequirementsIncludingLegacy().values(), cd));
        }
        try {
            submissionExecutor.setAdditionalBatchUpdateListeners(ImmutableList.of(new SubmitStrategyListener(submitInput, strategies, commitStatus)));
            submissionExecutor.execute(batchUpdates);
        } finally {
            // If the BatchUpdate fails it can be that merging some of the changes was actually
            // successful. This is why we must to collect the updated changes also when an
            // exception was thrown.
            strategies.forEach(s -> updatedChanges.putAll(s.getUpdatedChanges()));
            // Do not leave executed BatchUpdates in the OpenRepos
            if (!dryrun) {
                orm.resetUpdates(ImmutableSet.copyOf(this.allProjects));
            }
        }
    } catch (NoSuchProjectException e) {
        throw new ResourceNotFoundException(e.getMessage());
    } catch (IOException e) {
        throw new StorageException(e);
    } catch (SubmoduleConflictException e) {
        throw new IntegrationConflictException(e.getMessage(), e);
    } catch (UpdateException e) {
        if (e.getCause() instanceof LockFailureException) {
            // as to be unnoticeable, assuming RetryHelper is retrying sufficiently.
            throw e;
        }
        // inner IntegrationConflictException to a ResourceConflictException.
        if (e.getCause() instanceof IntegrationConflictException) {
            throw (IntegrationConflictException) e.getCause();
        }
        throw new MergeUpdateException(genericMergeError(cs), e);
    }
}
Also used : ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) SuperprojectUpdateOnSubmission(com.google.gerrit.server.update.SuperprojectUpdateOnSubmission) ListMultimap(com.google.common.collect.ListMultimap) MultimapBuilder(com.google.common.collect.MultimapBuilder) InternalUser(com.google.gerrit.server.InternalUser) Inject(com.google.inject.Inject) SubmissionId(com.google.gerrit.entities.SubmissionId) UpdateException(com.google.gerrit.server.update.UpdateException) SubmitRequirementResult(com.google.gerrit.entities.SubmitRequirementResult) MergeUpdateException(com.google.gerrit.exceptions.MergeUpdateException) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) SubmitInput(com.google.gerrit.extensions.api.changes.SubmitInput) Map(java.util.Map) AuthException(com.google.gerrit.extensions.restapi.AuthException) StoreSubmitRequirementsOp(com.google.gerrit.server.notedb.StoreSubmitRequirementsOp) RetryHelper(com.google.gerrit.server.update.RetryHelper) MergeTip(com.google.gerrit.server.git.MergeTip) Collectors.toSet(java.util.stream.Collectors.toSet) ImmutableSetMultimap(com.google.common.collect.ImmutableSetMultimap) ImmutableSet(com.google.common.collect.ImmutableSet) Status(com.google.gerrit.entities.Change.Status) ImmutableMap(com.google.common.collect.ImmutableMap) TraceContext(com.google.gerrit.server.logging.TraceContext) SubmitType(com.google.gerrit.extensions.client.SubmitType) Collection(java.util.Collection) Set(java.util.Set) Constants(org.eclipse.jgit.lib.Constants) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit) Instant(java.time.Instant) RetryListener(com.github.rholder.retry.RetryListener) SubmitRecord(com.google.gerrit.entities.SubmitRecord) Collectors(java.util.stream.Collectors) BranchNameKey(com.google.gerrit.entities.BranchNameKey) NotifyHandling(com.google.gerrit.extensions.api.changes.NotifyHandling) SubmitTypeRecord(com.google.gerrit.entities.SubmitTypeRecord) ChangeData(com.google.gerrit.server.query.change.ChangeData) List(java.util.List) Nullable(com.google.gerrit.common.Nullable) Ref(org.eclipse.jgit.lib.Ref) AutoValue(com.google.auto.value.AutoValue) InternalChangeQuery(com.google.gerrit.server.query.change.InternalChangeQuery) Optional(java.util.Optional) MoreObjects.firstNonNull(com.google.common.base.MoreObjects.firstNonNull) Counter0(com.google.gerrit.metrics.Counter0) MetricMaker(com.google.gerrit.metrics.MetricMaker) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) FluentLogger(com.google.common.flogger.FluentLogger) Joiner(com.google.common.base.Joiner) ChangeMessagesUtil(com.google.gerrit.server.ChangeMessagesUtil) Singleton(com.google.inject.Singleton) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) RevCommit(org.eclipse.jgit.revwalk.RevCommit) OpenRepo(com.google.gerrit.server.submit.MergeOpRepoManager.OpenRepo) IncorrectObjectTypeException(org.eclipse.jgit.errors.IncorrectObjectTypeException) HashMap(java.util.HashMap) Function(java.util.function.Function) SubmissionListener(com.google.gerrit.server.update.SubmissionListener) MergeValidators(com.google.gerrit.server.git.validators.MergeValidators) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ImmutableList(com.google.common.collect.ImmutableList) SubmissionExecutor(com.google.gerrit.server.update.SubmissionExecutor) Description(com.google.gerrit.metrics.Description) Objects.requireNonNull(java.util.Objects.requireNonNull) Change(com.google.gerrit.entities.Change) PatchSet(com.google.gerrit.entities.PatchSet) Comparator.comparing(java.util.Comparator.comparing) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) ChangeUtil(com.google.gerrit.server.ChangeUtil) LockFailureException(com.google.gerrit.git.LockFailureException) ChangeContext(com.google.gerrit.server.update.ChangeContext) MergeValidationException(com.google.gerrit.server.git.validators.MergeValidationException) LinkedHashSet(java.util.LinkedHashSet) SubmitRequirement(com.google.gerrit.entities.SubmitRequirement) NotifyResolver(com.google.gerrit.server.change.NotifyResolver) OpenBranch(com.google.gerrit.server.submit.MergeOpRepoManager.OpenBranch) StorageException(com.google.gerrit.exceptions.StorageException) Attempt(com.github.rholder.retry.Attempt) NoSuchProjectException(com.google.gerrit.server.project.NoSuchProjectException) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) SubmitRuleOptions(com.google.gerrit.server.project.SubmitRuleOptions) SetMultimap(com.google.common.collect.SetMultimap) ObjectId(org.eclipse.jgit.lib.ObjectId) Provider(com.google.inject.Provider) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) Project(com.google.gerrit.entities.Project) TimeUtil(com.google.gerrit.server.util.time.TimeUtil) RequestId(com.google.gerrit.server.logging.RequestId) HashMap(java.util.HashMap) NoSuchProjectException(com.google.gerrit.server.project.NoSuchProjectException) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) LockFailureException(com.google.gerrit.git.LockFailureException) BranchNameKey(com.google.gerrit.entities.BranchNameKey) UpdateException(com.google.gerrit.server.update.UpdateException) MergeUpdateException(com.google.gerrit.exceptions.MergeUpdateException) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) Change(com.google.gerrit.entities.Change) IOException(java.io.IOException) ChangeData(com.google.gerrit.server.query.change.ChangeData) BranchNameKey(com.google.gerrit.entities.BranchNameKey) MergeUpdateException(com.google.gerrit.exceptions.MergeUpdateException) Project(com.google.gerrit.entities.Project) OpenRepo(com.google.gerrit.server.submit.MergeOpRepoManager.OpenRepo) SubmissionId(com.google.gerrit.entities.SubmissionId) ObjectId(org.eclipse.jgit.lib.ObjectId) RequestId(com.google.gerrit.server.logging.RequestId) StorageException(com.google.gerrit.exceptions.StorageException) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap)

Aggregations

Joiner (com.google.common.base.Joiner)3 MoreObjects.firstNonNull (com.google.common.base.MoreObjects.firstNonNull)3 ImmutableList (com.google.common.collect.ImmutableList)3 ImmutableMap (com.google.common.collect.ImmutableMap)3 ImmutableSet (com.google.common.collect.ImmutableSet)3 ImmutableSetMultimap (com.google.common.collect.ImmutableSetMultimap)3 ListMultimap (com.google.common.collect.ListMultimap)3 MultimapBuilder (com.google.common.collect.MultimapBuilder)3 FluentLogger (com.google.common.flogger.FluentLogger)3 Nullable (com.google.gerrit.common.Nullable)3 BranchNameKey (com.google.gerrit.entities.BranchNameKey)3 Change (com.google.gerrit.entities.Change)3 PatchSet (com.google.gerrit.entities.PatchSet)3 Project (com.google.gerrit.entities.Project)3 SubmissionId (com.google.gerrit.entities.SubmissionId)3 StorageException (com.google.gerrit.exceptions.StorageException)3 NotifyHandling (com.google.gerrit.extensions.api.changes.NotifyHandling)3 SubmitInput (com.google.gerrit.extensions.api.changes.SubmitInput)3 AuthException (com.google.gerrit.extensions.restapi.AuthException)3 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)3