Search in sources :

Example 51 with BatchUpdate

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

the class Move method applyImpl.

@Override
protected ChangeInfo applyImpl(BatchUpdate.Factory updateFactory, ChangeResource rsrc, MoveInput input) throws RestApiException, OrmException, UpdateException, PermissionBackendException {
    Change change = rsrc.getChange();
    Project.NameKey project = rsrc.getProject();
    IdentifiedUser caller = rsrc.getUser();
    input.destinationBranch = RefNames.fullName(input.destinationBranch);
    if (change.getStatus().isClosed()) {
        throw new ResourceConflictException("Change is " + ChangeUtil.status(change));
    }
    Branch.NameKey newDest = new Branch.NameKey(project, input.destinationBranch);
    if (change.getDest().equals(newDest)) {
        throw new ResourceConflictException("Change is already destined for the specified branch");
    }
    // Move requires abandoning this change, and creating a new change.
    try {
        rsrc.permissions().database(dbProvider).check(ChangePermission.ABANDON);
        permissionBackend.user(caller).database(dbProvider).ref(newDest).check(RefPermission.CREATE_CHANGE);
    } catch (AuthException denied) {
        throw new AuthException("move not permitted", denied);
    }
    try (BatchUpdate u = updateFactory.create(dbProvider.get(), project, caller, TimeUtil.nowTs())) {
        u.addOp(change.getId(), new Op(input));
        u.execute();
    }
    return json.noOptions().format(project, rsrc.getId());
}
Also used : Project(com.google.gerrit.reviewdb.client.Project) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Branch(com.google.gerrit.reviewdb.client.Branch) AuthException(com.google.gerrit.extensions.restapi.AuthException) Change(com.google.gerrit.reviewdb.client.Change) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) BatchUpdate(com.google.gerrit.server.update.BatchUpdate)

Example 52 with BatchUpdate

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

the class MailProcessor method processImpl.

private void processImpl(BatchUpdate.Factory buf, MailMessage message) throws OrmException, UpdateException, RestApiException {
    for (DynamicMap.Entry<MailFilter> filter : mailFilters) {
        if (!filter.getProvider().get().shouldProcessMessage(message)) {
            log.warn(String.format("Message %s filtered by plugin %s %s. Will delete message.", message.id(), filter.getPluginName(), filter.getExportName()));
            return;
        }
    }
    MailMetadata metadata = MetadataParser.parse(message);
    if (!metadata.hasRequiredFields()) {
        log.error(String.format("Message %s is missing required metadata, have %s. Will delete message.", message.id(), metadata));
        return;
    }
    Set<Account.Id> accounts = accountByEmailCache.get(metadata.author);
    if (accounts.size() != 1) {
        log.error(String.format("Address %s could not be matched to a unique account. It was matched to %s. Will delete message.", metadata.author, accounts));
        return;
    }
    Account.Id account = accounts.iterator().next();
    if (!accountCache.get(account).getAccount().isActive()) {
        log.warn(String.format("Mail: Account %s is inactive. Will delete message.", account));
        return;
    }
    try (ManualRequestContext ctx = oneOffRequestContext.openAs(account)) {
        List<ChangeData> changeDataList = queryProvider.get().byKey(Change.Key.parse(metadata.changeId));
        if (changeDataList.size() != 1) {
            log.error(String.format("Message %s references unique change %s, but there are %d matching changes in the index. Will delete message.", message.id(), metadata.changeId, changeDataList.size()));
            return;
        }
        ChangeData cd = changeDataList.get(0);
        if (existingMessageIds(cd).contains(message.id())) {
            log.info("Message " + message.id() + " was already processed. Will delete message.");
            return;
        }
        // Get all comments; filter and sort them to get the original list of
        // comments from the outbound email.
        // TODO(hiesel) Also filter by original comment author.
        Collection<Comment> comments = cd.publishedComments().stream().filter(c -> (c.writtenOn.getTime() / 1000) == (metadata.timestamp.getTime() / 1000)).sorted(CommentsUtil.COMMENT_ORDER).collect(toList());
        Project.NameKey project = cd.project();
        String changeUrl = canonicalUrl.get() + "#/c/" + cd.getId().get();
        List<MailComment> parsedComments;
        if (useHtmlParser(message)) {
            parsedComments = HtmlParser.parse(message, comments, changeUrl);
        } else {
            parsedComments = TextParser.parse(message, comments, changeUrl);
        }
        if (parsedComments.isEmpty()) {
            log.warn("Could not parse any comments from " + message.id() + ". Will delete message.");
            return;
        }
        Op o = new Op(new PatchSet.Id(cd.getId(), metadata.patchSet), parsedComments, message.id());
        BatchUpdate batchUpdate = buf.create(cd.db(), project, ctx.getUser(), TimeUtil.nowTs());
        batchUpdate.addOp(cd.getId(), o);
        batchUpdate.execute();
    }
}
Also used : MailFilter(com.google.gerrit.server.mail.MailFilter) Account(com.google.gerrit.reviewdb.client.Account) Comment(com.google.gerrit.reviewdb.client.Comment) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) ChangeData(com.google.gerrit.server.query.change.ChangeData) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) Project(com.google.gerrit.reviewdb.client.Project) DynamicMap(com.google.gerrit.extensions.registration.DynamicMap) ManualRequestContext(com.google.gerrit.server.util.ManualRequestContext)

Example 53 with BatchUpdate

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

the class ReceiveCommits method insertChangesAndPatchSets.

private void insertChangesAndPatchSets() {
    ReceiveCommand magicBranchCmd = magicBranch != null ? magicBranch.cmd : null;
    if (magicBranchCmd != null && magicBranchCmd.getResult() != NOT_ATTEMPTED) {
        logWarn(String.format("Skipping change updates on %s because ref update failed: %s %s", project.getName(), magicBranchCmd.getResult(), Strings.nullToEmpty(magicBranchCmd.getMessage())));
        return;
    }
    try (BatchUpdate bu = batchUpdateFactory.create(db, project.getNameKey(), user.materializedCopy(), TimeUtil.nowTs());
        ObjectInserter ins = repo.newObjectInserter();
        ObjectReader reader = ins.newReader();
        RevWalk rw = new RevWalk(reader)) {
        bu.setRepository(repo, rw, ins).updateChangesInParallel();
        bu.setRequestId(receiveId);
        bu.setRefLogMessage("push");
        logDebug("Adding {} replace requests", newChanges.size());
        for (ReplaceRequest replace : replaceByChange.values()) {
            replace.addOps(bu, replaceProgress);
        }
        logDebug("Adding {} create requests", newChanges.size());
        for (CreateRequest create : newChanges) {
            create.addOps(bu);
        }
        logDebug("Adding {} group update requests", newChanges.size());
        updateGroups.forEach(r -> r.addOps(bu));
        logDebug("Adding {} additional ref updates", actualCommands.size());
        actualCommands.forEach(c -> bu.addRepoOnlyOp(new UpdateOneRefOp(c)));
        logDebug("Executing batch");
        try {
            bu.execute();
        } catch (UpdateException e) {
            throw INSERT_EXCEPTION.apply(e);
        }
        if (magicBranchCmd != null) {
            magicBranchCmd.setResult(OK);
        }
        for (ReplaceRequest replace : replaceByChange.values()) {
            String rejectMessage = replace.getRejectMessage();
            if (rejectMessage == null) {
                if (replace.inputCommand.getResult() == NOT_ATTEMPTED) {
                    // Not necessarily the magic branch, so need to set OK on the original value.
                    replace.inputCommand.setResult(OK);
                }
            } else {
                logDebug("Rejecting due to message from ReplaceOp");
                reject(replace.inputCommand, rejectMessage);
            }
        }
    } catch (ResourceConflictException e) {
        addMessage(e.getMessage());
        reject(magicBranchCmd, "conflict");
    } catch (RestApiException | IOException err) {
        logError("Can't insert change/patch set for " + project.getName(), err);
        reject(magicBranchCmd, "internal server error: " + err.getMessage());
    }
    if (magicBranch != null && magicBranch.submit) {
        try {
            submit(newChanges, replaceByChange.values());
        } catch (ResourceConflictException e) {
            addMessage(e.getMessage());
            reject(magicBranchCmd, "conflict");
        } catch (RestApiException | OrmException e) {
            logError("Error submitting changes to " + project.getName(), e);
            reject(magicBranchCmd, "error during submit");
        }
    }
}
Also used : ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) OrmException(com.google.gwtorm.server.OrmException) ObjectReader(org.eclipse.jgit.lib.ObjectReader) UpdateException(com.google.gerrit.server.update.UpdateException) RestApiException(com.google.gerrit.extensions.restapi.RestApiException)

Example 54 with BatchUpdate

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

the class ReceiveCommits method autoCloseChanges.

private void autoCloseChanges(final ReceiveCommand cmd) {
    logDebug("Starting auto-closing of changes");
    String refName = cmd.getRefName();
    checkState(!MagicBranch.isMagicBranch(refName), "shouldn't be auto-closing changes on magic branch %s", refName);
    // insertChangesAndPatchSets.
    try (BatchUpdate bu = batchUpdateFactory.create(db, projectControl.getProject().getNameKey(), user, TimeUtil.nowTs());
        ObjectInserter ins = repo.newObjectInserter();
        ObjectReader reader = ins.newReader();
        RevWalk rw = new RevWalk(reader)) {
        bu.setRepository(repo, rw, ins).updateChangesInParallel();
        bu.setRequestId(receiveId);
        // TODO(dborowitz): Teach BatchUpdate to ignore missing changes.
        RevCommit newTip = rw.parseCommit(cmd.getNewId());
        Branch.NameKey branch = new Branch.NameKey(project.getNameKey(), refName);
        rw.reset();
        rw.markStart(newTip);
        if (!ObjectId.zeroId().equals(cmd.getOldId())) {
            rw.markUninteresting(rw.parseCommit(cmd.getOldId()));
        }
        ListMultimap<ObjectId, Ref> byCommit = changeRefsById();
        Map<Change.Key, ChangeNotes> byKey = null;
        List<ReplaceRequest> replaceAndClose = new ArrayList<>();
        int existingPatchSets = 0;
        int newPatchSets = 0;
        COMMIT: for (RevCommit c; (c = rw.next()) != null; ) {
            rw.parseBody(c);
            for (Ref ref : byCommit.get(c.copy())) {
                existingPatchSets++;
                PatchSet.Id psId = PatchSet.Id.fromRef(ref.getName());
                bu.addOp(psId.getParentKey(), mergedByPushOpFactory.create(requestScopePropagator, psId, refName));
                continue COMMIT;
            }
            for (String changeId : c.getFooterLines(CHANGE_ID)) {
                if (byKey == null) {
                    byKey = openChangesByBranch(branch);
                }
                ChangeNotes onto = byKey.get(new Change.Key(changeId.trim()));
                if (onto != null) {
                    newPatchSets++;
                    // Hold onto this until we're done with the walk, as the call to
                    // req.validate below calls isMergedInto which resets the walk.
                    ReplaceRequest req = new ReplaceRequest(onto.getChangeId(), c, cmd, false);
                    req.notes = onto;
                    replaceAndClose.add(req);
                    continue COMMIT;
                }
            }
        }
        for (final ReplaceRequest req : replaceAndClose) {
            Change.Id id = req.notes.getChangeId();
            if (!req.validate(true)) {
                logDebug("Not closing {} because validation failed", id);
                continue;
            }
            req.addOps(bu, null);
            bu.addOp(id, mergedByPushOpFactory.create(requestScopePropagator, req.psId, refName).setPatchSetProvider(new Provider<PatchSet>() {

                @Override
                public PatchSet get() {
                    return req.replaceOp.getPatchSet();
                }
            }));
            bu.addOp(id, new ChangeProgressOp(closeProgress));
        }
        logDebug("Auto-closing {} changes with existing patch sets and {} with new patch sets", existingPatchSets, newPatchSets);
        bu.execute();
    } catch (RestApiException e) {
        logError("Can't insert patchset", e);
    } catch (IOException | OrmException | UpdateException | PermissionBackendException e) {
        logError("Can't scan for changes to close", e);
    }
}
Also used : ArrayList(java.util.ArrayList) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) OrmException(com.google.gwtorm.server.OrmException) MagicBranch(com.google.gerrit.server.util.MagicBranch) Branch(com.google.gerrit.reviewdb.client.Branch) ObjectReader(org.eclipse.jgit.lib.ObjectReader) UpdateException(com.google.gerrit.server.update.UpdateException) RevCommit(org.eclipse.jgit.revwalk.RevCommit) ObjectId(org.eclipse.jgit.lib.ObjectId) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) Change(com.google.gerrit.reviewdb.client.Change) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) Provider(com.google.inject.Provider) Ref(org.eclipse.jgit.lib.Ref) RequestId(com.google.gerrit.server.util.RequestId) ObjectId(org.eclipse.jgit.lib.ObjectId) RevId(com.google.gerrit.reviewdb.client.RevId) RestApiException(com.google.gerrit.extensions.restapi.RestApiException)

Aggregations

BatchUpdate (com.google.gerrit.server.update.BatchUpdate)54 BatchUpdateOp (com.google.gerrit.server.update.BatchUpdateOp)26 Change (com.google.gerrit.reviewdb.client.Change)22 ObjectId (org.eclipse.jgit.lib.ObjectId)14 OrmException (com.google.gwtorm.server.OrmException)13 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)12 RestApiException (com.google.gerrit.extensions.restapi.RestApiException)12 UpdateException (com.google.gerrit.server.update.UpdateException)12 PatchSet (com.google.gerrit.reviewdb.client.PatchSet)11 ChangeControl (com.google.gerrit.server.project.ChangeControl)11 ChangeContext (com.google.gerrit.server.update.ChangeContext)11 AuthException (com.google.gerrit.extensions.restapi.AuthException)10 ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)10 ObjectReader (org.eclipse.jgit.lib.ObjectReader)10 Repository (org.eclipse.jgit.lib.Repository)9 RevWalk (org.eclipse.jgit.revwalk.RevWalk)9 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)8 IOException (java.io.IOException)8 RevCommit (org.eclipse.jgit.revwalk.RevCommit)8 IdentifiedUser (com.google.gerrit.server.IdentifiedUser)7