use of com.google.gerrit.index.RefState in project gerrit by GerritCodeReview.
the class ProjectResetter method restoreRefs.
private void restoreRefs() throws IOException {
for (Map.Entry<Project.NameKey, Collection<RefState>> e : savedRefStatesByProject.asMap().entrySet()) {
try (Repository repo = repoManager.openRepository(e.getKey())) {
for (RefState refState : e.getValue()) {
if (refState.match(repo)) {
keptRefsByProject.put(e.getKey(), refState.ref());
continue;
}
Ref ref = repo.exactRef(refState.ref());
RefUpdate updateRef = repo.updateRef(refState.ref());
updateRef.setExpectedOldObjectId(ref != null ? ref.getObjectId() : ObjectId.zeroId());
updateRef.setNewObjectId(refState.id());
updateRef.setForceUpdate(true);
RefUpdate.Result result = updateRef.update();
checkState(result == RefUpdate.Result.FORCED || result == RefUpdate.Result.NEW, "resetting branch %s in %s failed", refState.ref(), e.getKey());
restoredRefsByProject.put(e.getKey(), refState.ref());
}
}
}
}
use of com.google.gerrit.index.RefState in project gerrit by GerritCodeReview.
the class ChangeData method getRefStates.
public SetMultimap<NameKey, RefState> getRefStates() {
if (refStates == null) {
if (!lazyload()) {
return ImmutableSetMultimap.of();
}
ImmutableSetMultimap.Builder<NameKey, RefState> result = ImmutableSetMultimap.builder();
for (Table.Cell<Account.Id, PatchSet.Id, ObjectId> edit : editRefs().cellSet()) {
result.put(project, RefState.create(RefNames.refsEdit(edit.getRowKey(), edit.getColumnKey().changeId(), edit.getColumnKey()), edit.getValue()));
}
starRefs().values().forEach(r -> result.put(allUsersName, RefState.of(r.ref())));
// TODO: instantiating the notes is too much. We don't want to parse NoteDb, we just want the
// refs.
result.put(project, RefState.create(notes().getRefName(), notes().getMetaId()));
// Force loading robot comments.
notes().getRobotComments();
RobotCommentNotes robotNotes = notes().getRobotCommentNotes();
result.put(project, RefState.create(robotNotes.getRefName(), robotNotes.getMetaId()));
draftRefs().entrySet().forEach(r -> result.put(allUsersName, RefState.create(RefNames.refsDraftComments(getId(), r.getKey()), r.getValue())));
refStates = result.build();
}
return refStates;
}
use of com.google.gerrit.index.RefState in project gerrit by GerritCodeReview.
the class StalenessChecker method check.
public StalenessCheckResult check(Account.Id id) throws IOException {
AccountIndex i = indexes.getSearchIndex();
if (i == null) {
// No index; caller couldn't do anything if it is stale.
return StalenessCheckResult.notStale();
}
if (!i.getSchema().hasField(AccountField.REF_STATE) || !i.getSchema().hasField(AccountField.EXTERNAL_ID_STATE)) {
// Index version not new enough for this check.
return StalenessCheckResult.notStale();
}
boolean useLegacyNumericFields = i.getSchema().useLegacyNumericFields();
ImmutableSet<String> fields = useLegacyNumericFields ? FIELDS : FIELDS2;
Optional<FieldBundle> result = i.getRaw(id, QueryOptions.create(indexConfig, 0, 1, IndexUtils.accountFields(fields, useLegacyNumericFields)));
if (!result.isPresent()) {
// The document is missing in the index.
try (Repository repo = repoManager.openRepository(allUsersName)) {
Ref ref = repo.exactRef(RefNames.refsUsers(id));
// Stale if the account actually exists.
if (ref == null) {
return StalenessCheckResult.notStale();
}
return StalenessCheckResult.stale("Document missing in index, but found %s in the repo", ref);
}
}
for (Map.Entry<Project.NameKey, RefState> e : RefState.parseStates(result.get().getValue(AccountField.REF_STATE)).entries()) {
// Custom All-Users repository names are not indexed. Instead, the default name is used.
// Therefore, defer to the currently configured All-Users name.
Project.NameKey repoName = e.getKey().get().equals(AllUsersNameProvider.DEFAULT) ? allUsersName : e.getKey();
try (Repository repo = repoManager.openRepository(repoName)) {
if (!e.getValue().match(repo)) {
return StalenessCheckResult.stale("Ref was modified since the account was indexed (%s != %s)", e.getValue(), repo.exactRef(e.getValue().ref()));
}
}
}
Set<ExternalId> extIds = externalIds.byAccount(id);
ListMultimap<ObjectId, ObjectId> extIdStates = parseExternalIdStates(result.get().getValue(AccountField.EXTERNAL_ID_STATE));
if (extIdStates.size() != extIds.size()) {
return StalenessCheckResult.stale("External IDs of the account were modified since the account was indexed. (%s != %s)", extIdStates.size(), extIds.size());
}
for (ExternalId extId : extIds) {
if (!extIdStates.containsKey(extId.key().sha1())) {
return StalenessCheckResult.stale("External ID missing: %s", extId.key().sha1());
}
if (!extIdStates.containsEntry(extId.key().sha1(), extId.blobId())) {
return StalenessCheckResult.stale("External ID has unexpected value. (%s != %s)", extIdStates.get(extId.key().sha1()), extId.blobId());
}
}
return StalenessCheckResult.notStale();
}
use of com.google.gerrit.index.RefState in project gerrit by GerritCodeReview.
the class ChangeJson method toChangeInfoImpl.
private ChangeInfo toChangeInfoImpl(ChangeData cd, Optional<PatchSet.Id> limitToPsId, List<PluginDefinedInfo> pluginInfos) throws PatchListNotAvailableException, GpgException, PermissionBackendException, IOException {
ChangeInfo out = new ChangeInfo();
CurrentUser user = userProvider.get();
if (has(CHECK)) {
out.problems = checkerProvider.get().check(cd.notes(), fix).problems();
// If any problems were fixed, the ChangeData needs to be reloaded.
for (ProblemInfo p : out.problems) {
if (p.status == ProblemInfo.Status.FIXED) {
cd = changeDataFactory.create(cd.project(), cd.getId());
break;
}
}
}
Change in = cd.change();
out.project = in.getProject().get();
out.branch = in.getDest().shortName();
out.topic = in.getTopic();
if (!cd.attentionSet().isEmpty()) {
out.removedFromAttentionSet = removalsOnly(cd.attentionSet()).stream().collect(toImmutableMap(a -> a.account().get(), a -> AttentionSetUtil.createAttentionSetInfo(a, accountLoader)));
out.attentionSet = // This filtering should match GetAttentionSet.
additionsOnly(cd.attentionSet()).stream().collect(toImmutableMap(a -> a.account().get(), a -> AttentionSetUtil.createAttentionSetInfo(a, accountLoader)));
}
out.assignee = in.getAssignee() != null ? accountLoader.get(in.getAssignee()) : null;
out.hashtags = cd.hashtags();
out.changeId = in.getKey().get();
if (in.isNew()) {
SubmitTypeRecord str = cd.submitTypeRecord();
if (str.isOk()) {
out.submitType = str.type;
}
if (includeMergeable) {
out.mergeable = cd.isMergeable();
}
if (has(SUBMITTABLE)) {
out.submittable = submittable(cd);
}
}
if (!has(SKIP_DIFFSTAT)) {
Optional<ChangedLines> changedLines = cd.changedLines();
if (changedLines.isPresent()) {
out.insertions = changedLines.get().insertions;
out.deletions = changedLines.get().deletions;
}
}
out.isPrivate = in.isPrivate() ? true : null;
out.workInProgress = in.isWorkInProgress() ? true : null;
out.hasReviewStarted = in.hasReviewStarted();
out.subject = in.getSubject();
out.status = in.getStatus().asChangeStatus();
out.owner = accountLoader.get(in.getOwner());
out.setCreated(in.getCreatedOn());
out.setUpdated(in.getLastUpdatedOn());
out._number = in.getId().get();
out.totalCommentCount = cd.totalCommentCount();
out.unresolvedCommentCount = cd.unresolvedCommentCount();
if (cd.getRefStates() != null) {
String metaName = RefNames.changeMetaRef(cd.getId());
Optional<RefState> metaState = cd.getRefStates().values().stream().filter(r -> r.ref().equals(metaName)).findAny();
// metaState should always be there, but it doesn't hurt to be extra careful.
metaState.ifPresent(rs -> out.metaRevId = rs.id().getName());
}
if (user.isIdentifiedUser()) {
Collection<String> stars = cd.stars(user.getAccountId());
out.starred = stars.contains(StarredChangesUtil.DEFAULT_LABEL) ? true : null;
if (!stars.isEmpty()) {
out.stars = stars;
}
}
if (in.isNew() && has(REVIEWED) && user.isIdentifiedUser()) {
out.reviewed = cd.isReviewedBy(user.getAccountId()) ? true : null;
}
out.labels = labelsJson.labelsFor(accountLoader, cd, has(LABELS), has(DETAILED_LABELS));
out.requirements = requirementsFor(cd);
out.submitRecords = submitRecordsFor(cd);
if (has(SUBMIT_REQUIREMENTS)) {
out.submitRequirements = submitRequirementsFor(cd);
}
if (out.labels != null && has(DETAILED_LABELS)) {
// list permitted labels, since users can't vote on those patch sets.
if (user.isIdentifiedUser() && (!limitToPsId.isPresent() || limitToPsId.get().equals(in.currentPatchSetId()))) {
out.permittedLabels = !cd.change().isAbandoned() ? labelsJson.permittedLabels(user.getAccountId(), cd) : ImmutableMap.of();
}
}
if (has(LABELS) || has(DETAILED_LABELS)) {
out.reviewers = reviewerMap(cd.reviewers(), cd.reviewersByEmail(), false);
out.pendingReviewers = reviewerMap(cd.pendingReviewers(), cd.pendingReviewersByEmail(), true);
out.removableReviewers = removableReviewers(cd, out);
}
setSubmitter(cd, out);
if (!pluginInfos.isEmpty()) {
out.plugins = pluginInfos;
}
out.revertOf = cd.change().getRevertOf() != null ? cd.change().getRevertOf().get() : null;
out.submissionId = cd.change().getSubmissionId();
out.cherryPickOfChange = cd.change().getCherryPickOf() != null ? cd.change().getCherryPickOf().changeId().get() : null;
out.cherryPickOfPatchSet = cd.change().getCherryPickOf() != null ? cd.change().getCherryPickOf().get() : null;
if (has(REVIEWER_UPDATES)) {
out.reviewerUpdates = reviewerUpdates(cd);
}
boolean needMessages = has(MESSAGES);
boolean needRevisions = has(ALL_REVISIONS) || has(CURRENT_REVISION) || limitToPsId.isPresent();
Map<PatchSet.Id, PatchSet> src;
if (needMessages || needRevisions) {
src = loadPatchSets(cd, limitToPsId);
} else {
src = null;
}
if (needMessages) {
out.messages = messages(cd);
}
finish(out);
// it will be passed to ActionVisitors as-is.
if (needRevisions) {
out.revisions = revisionJson.getRevisions(accountLoader, cd, src, limitToPsId, out);
if (out.revisions != null) {
for (Map.Entry<String, RevisionInfo> entry : out.revisions.entrySet()) {
if (entry.getValue().isCurrent) {
out.currentRevision = entry.getKey();
break;
}
}
}
}
if (has(CURRENT_ACTIONS) || has(CHANGE_ACTIONS)) {
actionJson.addChangeActions(out, cd);
}
if (has(TRACKING_IDS)) {
ListMultimap<String, String> set = trackingFooters.extract(cd.commitFooters());
out.trackingIds = set.entries().stream().map(e -> new TrackingIdInfo(e.getKey(), e.getValue())).collect(toList());
}
return out;
}
use of com.google.gerrit.index.RefState in project gerrit by GerritCodeReview.
the class StalenessChecker method check.
/**
* Returns a {@link StalenessCheckResult} with structured information about staleness of the
* provided {@link com.google.gerrit.entities.Project.NameKey}.
*/
public StalenessCheckResult check(Project.NameKey project) {
ProjectData projectData = projectCache.get(project).orElseThrow(illegalState(project)).toProjectData();
ProjectIndex i = indexes.getSearchIndex();
if (i == null) {
return StalenessCheckResult.notStale();
}
Optional<FieldBundle> result = i.getRaw(project, QueryOptions.create(indexConfig, 0, 1, FIELDS));
if (!result.isPresent()) {
return StalenessCheckResult.stale("Document %s missing from index", project);
}
SetMultimap<Project.NameKey, RefState> indexedRefStates = RefState.parseStates(result.get().getValue(ProjectField.REF_STATE));
SetMultimap<Project.NameKey, RefState> currentRefStates = MultimapBuilder.hashKeys().hashSetValues().build();
projectData.tree().stream().filter(p -> p.getProject().getConfigRefState() != null).forEach(p -> currentRefStates.put(p.getProject().getNameKey(), RefState.create(RefNames.REFS_CONFIG, p.getProject().getConfigRefState())));
if (currentRefStates.equals(indexedRefStates)) {
return StalenessCheckResult.notStale();
}
return StalenessCheckResult.stale("Document has unexpected ref states (%s != %s)", currentRefStates, indexedRefStates);
}
Aggregations