use of com.google.gerrit.exceptions.StorageException in project gerrit by GerritCodeReview.
the class ChangeKindCacheImpl method getChangeKindInternal.
private static ChangeKind getChangeKindInternal(ChangeKindCache cache, @Nullable RevWalk rw, @Nullable Config repoConfig, ChangeData change, PatchSet patch) {
ChangeKind kind = ChangeKind.REWORK;
// the repository.
if (patch.id().get() > 1) {
try {
Collection<PatchSet> patchSetCollection = change.patchSets();
PatchSet priorPs = patch;
for (PatchSet ps : patchSetCollection) {
if (ps.id().get() < patch.id().get() && (ps.id().get() > priorPs.id().get() || priorPs == patch)) {
// We only want the previous patch set, so walk until the last one
priorPs = ps;
}
}
// and deletes the draft.
if (priorPs != patch) {
kind = cache.getChangeKind(change.project(), rw, repoConfig, priorPs.commitId(), patch.commitId());
}
} catch (StorageException e) {
// Do nothing; assume we have a complex change
logger.atWarning().withCause(e).log("Unable to get change kind for patchSet %s of change %s", patch.number(), change.getId());
}
}
logger.atFine().log("Change kind for patchSet %s of change %s: %s", patch.number(), change.getId(), kind);
return kind;
}
use of com.google.gerrit.exceptions.StorageException in project gerrit by GerritCodeReview.
the class ChangeResource method prepareETag.
// This includes all information relevant for ETag computation
// unrelated to the UI.
public void prepareETag(Hasher h, CurrentUser user) {
h.putInt(JSON_FORMAT_VERSION).putLong(getChange().getLastUpdatedOn().toEpochMilli()).putInt(user.isIdentifiedUser() ? user.getAccountId().get() : 0);
if (user.isIdentifiedUser()) {
for (AccountGroup.UUID uuid : user.getEffectiveGroups().getKnownGroups()) {
h.putBytes(uuid.get().getBytes(UTF_8));
}
}
byte[] buf = new byte[20];
Set<Account.Id> accounts = new HashSet<>();
accounts.add(getChange().getOwner());
if (getChange().getAssignee() != null) {
accounts.add(getChange().getAssignee());
}
try {
patchSetUtil.byChange(getNotes()).stream().map(PatchSet::uploader).forEach(accounts::add);
// It's intentional to include the states for *all* reviewers into the ETag computation.
// We need the states of all current reviewers and CCs because they are part of ChangeInfo.
// Including removed reviewers is a cheap way of making sure that the states of accounts that
// posted a message on the change are included. Loading all change messages to find the exact
// set of accounts that posted a message is too expensive. However everyone who posts a
// message is automatically added as reviewer. Hence if we include removed reviewers we can
// be sure that we have all accounts that posted messages on the change.
accounts.addAll(approvalUtil.getReviewers(getNotes()).all());
} catch (StorageException e) {
// This ETag will be invalidated if it loads next time.
}
for (Account.Id accountId : accounts) {
Optional<AccountState> accountState = accountCache.get(accountId);
if (accountState.isPresent()) {
hashAccount(h, accountState.get(), buf);
} else {
h.putInt(accountId.get());
}
}
ObjectId noteId;
try {
noteId = getNotes().loadRevision();
} catch (StorageException e) {
// This ETag will be invalidated if it loads next time.
noteId = null;
}
hashObjectId(h, noteId, buf);
// TODO(dborowitz): Include more NoteDb and other related refs, e.g. drafts
// and edits.
Iterable<ProjectState> projectStateTree = projectCache.get(getProject()).orElseThrow(illegalState(getProject())).tree();
for (ProjectState p : projectStateTree) {
hashObjectId(h, p.getConfig().getRevision().orElse(null), buf);
}
changeETagComputation.runEach(c -> {
String pluginETag = c.getETag(changeData.project(), changeData.getId());
if (pluginETag != null) {
h.putString(pluginETag, UTF_8);
}
});
}
use of com.google.gerrit.exceptions.StorageException in project gerrit by GerritCodeReview.
the class ConsistencyChecker method checkPatchSets.
private boolean checkPatchSets() {
List<PatchSet> all;
try {
// Iterate in descending order.
all = PS_ID_ORDER.sortedCopy(psUtil.byChange(notes));
} catch (StorageException e) {
ProblemInfo problem = problem("Failed to look up patch sets");
logger.atWarning().withCause(e).log("Error in consistency check of change %s: %s", notes.getChangeId(), problem);
return false;
}
patchSetsBySha = MultimapBuilder.hashKeys(all.size()).treeSetValues(PS_ID_ORDER).build();
Map<String, Ref> refs;
try {
refs = repo.getRefDatabase().exactRef(all.stream().map(ps -> ps.id().toRefName()).toArray(String[]::new));
} catch (IOException e) {
ProblemInfo problem = problem("Error reading refs");
logger.atWarning().withCause(e).log("Error in consistency check of change %s: %s", notes.getChangeId(), problem);
refs = Collections.emptyMap();
}
List<DeletePatchSetFromDbOp> deletePatchSetOps = new ArrayList<>();
for (PatchSet ps : all) {
// Check revision format.
int psNum = ps.id().get();
String refName = ps.id().toRefName();
ObjectId objId = ps.commitId();
patchSetsBySha.put(objId, ps);
// Check ref existence.
ProblemInfo refProblem = null;
Ref ref = refs.get(refName);
if (ref == null) {
refProblem = problem("Ref missing: " + refName);
} else if (!objId.equals(ref.getObjectId())) {
String actual = ref.getObjectId() != null ? ref.getObjectId().name() : "null";
refProblem = problem(String.format("Expected %s to point to %s, found %s", ref.getName(), objId.name(), actual));
}
// Check object existence.
RevCommit psCommit = parseCommit(objId, String.format("patch set %d", psNum));
if (psCommit == null) {
if (fix != null && fix.deletePatchSetIfCommitMissing) {
deletePatchSetOps.add(new DeletePatchSetFromDbOp(lastProblem(), ps.id()));
}
continue;
} else if (refProblem != null && fix != null) {
fixPatchSetRef(refProblem, ps);
}
if (ps.id().equals(change().currentPatchSetId())) {
currPsCommit = psCommit;
}
}
// Delete any bad patch sets found above, in a single update.
deletePatchSets(deletePatchSetOps);
// Check for duplicates.
for (Map.Entry<ObjectId, Collection<PatchSet>> e : patchSetsBySha.asMap().entrySet()) {
if (e.getValue().size() > 1) {
problem(String.format("Multiple patch sets pointing to %s: %s", e.getKey().name(), Collections2.transform(e.getValue(), PatchSet::number)));
}
}
return currPs != null && currPsCommit != null;
}
use of com.google.gerrit.exceptions.StorageException in project gerrit by GerritCodeReview.
the class ChangeIndexer method indexImpl.
private void indexImpl(ChangeData cd) {
logger.atFine().log("Reindex change %d in index.", cd.getId().get());
for (Index<?, ChangeData> i : getWriteIndexes()) {
try (TraceTimer traceTimer = TraceContext.newTimer("Reindexing change in index", Metadata.builder().changeId(cd.getId().get()).patchSetId(cd.currentPatchSet().number()).indexVersion(i.getSchema().getVersion()).build())) {
if (isFirstInsertForEntry.equals(IsFirstInsertForEntry.YES)) {
i.insert(cd);
} else {
i.replace(cd);
}
} catch (RuntimeException e) {
throw new StorageException(String.format("Failed to reindex change %d in index version %d (current patch set = %d)", cd.getId().get(), i.getSchema().getVersion(), cd.currentPatchSet().number()), e);
}
}
fireChangeIndexedEvent(cd.project().get(), cd.getId().get());
}
use of com.google.gerrit.exceptions.StorageException in project gerrit by GerritCodeReview.
the class AccountIndexerImpl method reindexIfStale.
@Override
public boolean reindexIfStale(Account.Id id) {
try {
StalenessCheckResult stalenessCheckResult = stalenessChecker.check(id);
if (stalenessCheckResult.isStale()) {
logger.atInfo().log("Reindexing stale document %s", stalenessCheckResult);
index(id);
return true;
}
} catch (IOException e) {
throw new StorageException(e);
}
return false;
}
Aggregations