Search in sources :

Example 21 with StorageException

use of com.google.gerrit.exceptions.StorageException in project gerrit by GerritCodeReview.

the class ChangeUpdate method applyImpl.

@Override
protected CommitBuilder applyImpl(RevWalk rw, ObjectInserter ins, ObjectId curr) throws IOException {
    checkState(deleteCommentRewriter == null && deleteChangeMessageRewriter == null, "cannot update and rewrite ref in one BatchUpdate");
    PatchSet.Id patchSetId = psId != null ? psId : getChange().currentPatchSetId();
    StringBuilder msg = new StringBuilder();
    if (commitSubject != null) {
        msg.append(commitSubject);
    } else {
        msg.append("Update patch set ").append(patchSetId.get());
    }
    msg.append("\n\n");
    if (changeMessage != null) {
        msg.append(changeMessage);
        msg.append("\n\n");
    }
    addPatchSetFooter(msg, patchSetId);
    if (currentPatchSet) {
        addFooter(msg, FOOTER_CURRENT, Boolean.TRUE);
    }
    if (psDescription != null) {
        addFooter(msg, FOOTER_PATCH_SET_DESCRIPTION, psDescription);
    }
    if (changeId != null) {
        addFooter(msg, FOOTER_CHANGE_ID, changeId);
    }
    if (subject != null) {
        addFooter(msg, FOOTER_SUBJECT, subject);
    }
    if (branch != null) {
        addFooter(msg, FOOTER_BRANCH, branch);
    }
    if (status != null) {
        addFooter(msg, FOOTER_STATUS, status.name().toLowerCase());
        if (status.equals(Change.Status.ABANDONED)) {
            clearAttentionSet("Change was abandoned");
        }
        if (status.equals(Change.Status.MERGED)) {
            clearAttentionSet("Change was submitted");
        }
    }
    if (topic != null) {
        addFooter(msg, FOOTER_TOPIC, topic);
    }
    if (commit != null) {
        addFooter(msg, FOOTER_COMMIT, commit);
    }
    if (assignee != null) {
        if (assignee.isPresent()) {
            addFooter(msg, FOOTER_ASSIGNEE);
            noteUtil.appendAccountIdIdentString(msg, assignee.get()).append('\n');
        } else {
            addFooter(msg, FOOTER_ASSIGNEE).append('\n');
        }
    }
    Joiner comma = Joiner.on(',');
    if (hashtags != null) {
        addFooter(msg, FOOTER_HASHTAGS, comma.join(hashtags));
    }
    if (tag != null) {
        addFooter(msg, FOOTER_TAG, tag);
    }
    if (groups != null) {
        addFooter(msg, FOOTER_GROUPS, comma.join(groups));
    }
    for (Map.Entry<Account.Id, ReviewerStateInternal> e : reviewers.entrySet()) {
        addFooter(msg, e.getValue().getFooterKey());
        noteUtil.appendAccountIdIdentString(msg, e.getKey()).append('\n');
    }
    applyReviewerUpdatesToAttentionSet();
    for (Map.Entry<Address, ReviewerStateInternal> e : reviewersByEmail.entrySet()) {
        addFooter(msg, e.getValue().getByEmailFooterKey(), e.getKey().toString());
    }
    for (Table.Cell<String, Account.Id, Optional<Short>> c : approvals.cellSet()) {
        addLabelFooter(msg, c, patchSetId);
    }
    for (PatchSetApproval patchSetApproval : copiedApprovals) {
        addCopiedLabelFooter(msg, patchSetApproval);
    }
    if (submissionId != null) {
        addFooter(msg, FOOTER_SUBMISSION_ID, submissionId);
    }
    if (submitRecords != null) {
        for (SubmitRecord rec : submitRecords) {
            addFooter(msg, FOOTER_SUBMITTED_WITH).append(rec.status);
            if (rec.errorMessage != null) {
                msg.append(' ').append(sanitizeFooter(rec.errorMessage));
            }
            msg.append('\n');
            if (rec.ruleName != null) {
                addFooter(msg, FOOTER_SUBMITTED_WITH).append("Rule-Name: ").append(rec.ruleName);
                msg.append('\n');
            }
            if (rec.labels != null) {
                for (SubmitRecord.Label label : rec.labels) {
                    // Label names/values are safe to append without sanitizing.
                    addFooter(msg, FOOTER_SUBMITTED_WITH).append(label.status).append(": ").append(label.label);
                    if (label.appliedBy != null) {
                        msg.append(": ");
                        noteUtil.appendAccountIdIdentString(msg, label.appliedBy);
                    }
                    msg.append('\n');
                }
            }
        }
    }
    if (!Objects.equals(accountId, realAccountId)) {
        addFooter(msg, FOOTER_REAL_USER);
        noteUtil.appendAccountIdIdentString(msg, realAccountId).append('\n');
    }
    if (isPrivate != null) {
        addFooter(msg, FOOTER_PRIVATE, isPrivate);
    }
    if (workInProgress != null) {
        addFooter(msg, FOOTER_WORK_IN_PROGRESS, workInProgress);
        if (workInProgress) {
            clearAttentionSet("Change was marked work in progress");
        } else {
            addAllReviewersToAttentionSet();
        }
    }
    if (revertOf != null) {
        addFooter(msg, FOOTER_REVERT_OF, revertOf);
    }
    if (cherryPickOf != null) {
        if (cherryPickOf.isPresent()) {
            addFooter(msg, FOOTER_CHERRY_PICK_OF, cherryPickOf.get());
        } else {
            // Update cherryPickOf with an empty value.
            addFooter(msg, FOOTER_CHERRY_PICK_OF).append('\n');
        }
    }
    updateAttentionSet(msg);
    CommitBuilder cb = new CommitBuilder();
    cb.setMessage(msg.toString());
    try {
        ObjectId treeId = storeRevisionNotes(rw, ins, curr);
        if (treeId != null) {
            cb.setTreeId(treeId);
        }
    } catch (ConfigInvalidException e) {
        throw new StorageException(e);
    }
    return cb;
}
Also used : Joiner(com.google.common.base.Joiner) TreeBasedTable(com.google.common.collect.TreeBasedTable) Table(com.google.common.collect.Table) Address(com.google.gerrit.entities.Address) Optional(java.util.Optional) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) ObjectId(org.eclipse.jgit.lib.ObjectId) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) PatchSet(com.google.gerrit.entities.PatchSet) PatchSetApproval(com.google.gerrit.entities.PatchSetApproval) SubmitRecord(com.google.gerrit.entities.SubmitRecord) SubmissionId(com.google.gerrit.entities.SubmissionId) LabelId(com.google.gerrit.entities.LabelId) ObjectId(org.eclipse.jgit.lib.ObjectId) Map(java.util.Map) NoteMap(org.eclipse.jgit.notes.NoteMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) StorageException(com.google.gerrit.exceptions.StorageException)

Example 22 with StorageException

use of com.google.gerrit.exceptions.StorageException in project gerrit by GerritCodeReview.

the class RepoSequence method next.

/**
 * Retrieves the next N available sequence number.
 *
 * <p>This method is thread-safe.
 *
 * @param count the number of sequence numbers which should be returned
 * @return the next N available sequence numbers
 */
public ImmutableList<Integer> next(int count) {
    if (count == 0) {
        return ImmutableList.of();
    }
    checkArgument(count > 0, "count is negative: %s", count);
    try {
        return retryer.call(() -> {
            counterLock.lock();
            try {
                if (count == 1) {
                    if (counter >= limit) {
                        acquire(batchSize);
                    }
                    return ImmutableList.of(counter++);
                }
                List<Integer> ids = new ArrayList<>(count);
                while (counter < limit) {
                    ids.add(counter++);
                    if (ids.size() == count) {
                        return ImmutableList.copyOf(ids);
                    }
                }
                acquire(Math.max(count - ids.size(), batchSize));
                while (ids.size() < count) {
                    ids.add(counter++);
                }
                return ImmutableList.copyOf(ids);
            } finally {
                counterLock.unlock();
            }
        });
    } catch (ExecutionException | RetryException e) {
        if (e.getCause() != null) {
            Throwables.throwIfInstanceOf(e.getCause(), StorageException.class);
        }
        throw new StorageException(e);
    }
}
Also used : ArrayList(java.util.ArrayList) ExecutionException(java.util.concurrent.ExecutionException) RetryException(com.github.rholder.retry.RetryException) StorageException(com.google.gerrit.exceptions.StorageException)

Example 23 with StorageException

use of com.google.gerrit.exceptions.StorageException in project gerrit by GerritCodeReview.

the class RepoSequence method storeNew.

public void storeNew(int value) {
    counterLock.lock();
    try (Repository repo = repoManager.openRepository(projectName);
        RevWalk rw = new RevWalk(repo)) {
        Optional<IntBlob> blob = IntBlob.parse(repo, refName, rw);
        afterReadRef.run();
        ObjectId oldId;
        if (!blob.isPresent()) {
            oldId = ObjectId.zeroId();
        } else {
            oldId = blob.get().id();
        }
        RefUpdate refUpdate = IntBlob.tryStore(repo, rw, projectName, refName, oldId, value, gitRefUpdated);
        RefUpdateUtil.checkResult(refUpdate);
        counter = value;
        limit = counter + batchSize;
        acquireCount++;
    } catch (IOException e) {
        throw new StorageException(e);
    } finally {
        counterLock.unlock();
    }
}
Also used : Repository(org.eclipse.jgit.lib.Repository) ObjectId(org.eclipse.jgit.lib.ObjectId) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) StorageException(com.google.gerrit.exceptions.StorageException) RefUpdate(org.eclipse.jgit.lib.RefUpdate)

Example 24 with StorageException

use of com.google.gerrit.exceptions.StorageException in project gerrit by GerritCodeReview.

the class OpenRepo method addUpdates.

<U extends AbstractChangeUpdate> void addUpdates(ListMultimap<String, U> all, Optional<Integer> maxUpdates, Optional<Integer> maxPatchSets) throws IOException {
    for (Map.Entry<String, Collection<U>> e : all.asMap().entrySet()) {
        String refName = e.getKey();
        Collection<U> updates = e.getValue();
        ObjectId old = cmds.get(refName).orElse(ObjectId.zeroId());
        // writing partial change meta if the change hasn't been backfilled yet.
        if (!allowWrite(updates, old)) {
            continue;
        }
        int updateCount = 0;
        U first = updates.iterator().next();
        if (maxUpdates.isPresent()) {
            checkState(first.getNotes() != null, "expected ChangeNotes on %s", first);
            updateCount = first.getNotes().getUpdateCount();
        }
        ObjectId curr = old;
        for (U update : updates) {
            if (maxPatchSets.isPresent() && update.psId != null) {
                // is still a good estimate and an upper bound.
                if (update.psId.get() > maxPatchSets.get()) {
                    throw new LimitExceededException(String.format("Change %d may not exceed %d patch sets. To continue working on this change, " + "recreate it with a new Change-Id, then abandon this one.", update.getId().get(), maxPatchSets.get()));
                }
            }
            if (update.isRootOnly() && !old.equals(ObjectId.zeroId())) {
                throw new StorageException("Given ChangeUpdate is only allowed on initial commit");
            }
            ObjectId next = update.apply(rw, tempIns, curr);
            if (next == null) {
                continue;
            }
            if (maxUpdates.isPresent() && !Objects.equals(next, curr) && ++updateCount > maxUpdates.get() && !update.bypassMaxUpdates()) {
                throw new LimitExceededException(String.format("Change %s may not exceed %d updates. It may still be abandoned, submitted and you can add/remove" + " reviewers to/from the attention-set. To continue working on this change, recreate it with a new" + " Change-Id, then abandon this one.", update.getId(), maxUpdates.get()));
            }
            curr = next;
        }
        if (!old.equals(curr)) {
            cmds.add(new ReceiveCommand(old, curr, refName));
        }
    }
}
Also used : ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) ObjectId(org.eclipse.jgit.lib.ObjectId) Collection(java.util.Collection) Map(java.util.Map) StorageException(com.google.gerrit.exceptions.StorageException)

Example 25 with StorageException

use of com.google.gerrit.exceptions.StorageException in project gerrit by GerritCodeReview.

the class ChangeJson method format.

public ChangeInfo format(Project.NameKey project, Change.Id id, @Nullable ObjectId metaRevId) {
    ChangeNotes notes;
    try {
        notes = notesFactory.createChecked(project, id, metaRevId);
    } catch (StorageException e) {
        if (!has(CHECK)) {
            throw e;
        }
        return checkOnly(changeDataFactory.create(project, id));
    }
    ChangeData cd = changeDataFactory.create(notes);
    return format(cd, Optional.empty(), true, getPluginInfos(cd));
}
Also used : ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) StorageException(com.google.gerrit.exceptions.StorageException) ChangeData(com.google.gerrit.server.query.change.ChangeData)

Aggregations

StorageException (com.google.gerrit.exceptions.StorageException)153 IOException (java.io.IOException)68 Change (com.google.gerrit.entities.Change)47 ObjectId (org.eclipse.jgit.lib.ObjectId)37 Repository (org.eclipse.jgit.lib.Repository)33 ChangeNotes (com.google.gerrit.server.notedb.ChangeNotes)30 PatchSet (com.google.gerrit.entities.PatchSet)29 RevCommit (org.eclipse.jgit.revwalk.RevCommit)28 ArrayList (java.util.ArrayList)25 ConfigInvalidException (org.eclipse.jgit.errors.ConfigInvalidException)24 Project (com.google.gerrit.entities.Project)22 Ref (org.eclipse.jgit.lib.Ref)22 ChangeData (com.google.gerrit.server.query.change.ChangeData)21 RevWalk (org.eclipse.jgit.revwalk.RevWalk)21 Account (com.google.gerrit.entities.Account)20 Inject (com.google.inject.Inject)19 Map (java.util.Map)19 Test (org.junit.Test)19 List (java.util.List)18 BranchNameKey (com.google.gerrit.entities.BranchNameKey)17