Remove ProjectCache#checkedGet and move callers to #get

In an effort to make it impossible to use the ProjectCache interface the
wrong way, we are simplifying the interface to just a single option for
getting a project. The #get method throws a StorageException in case loading
failed and returns Optional#empty in case the project does not exist.

Change-Id: I7e3ecf2de3bc975d1c35ee8a848ac61def7af252
This commit is contained in:
Patrick Hiesel
2020-03-06 15:11:28 +01:00
parent 3a0ad58890
commit a6a44c5ab5
69 changed files with 344 additions and 256 deletions

View File

@@ -23,6 +23,7 @@ import static com.google.common.truth.TruthJUnit.assume;
import static com.google.gerrit.entities.Patch.COMMIT_MSG; import static com.google.gerrit.entities.Patch.COMMIT_MSG;
import static com.google.gerrit.entities.Patch.MERGE_LIST; import static com.google.gerrit.entities.Patch.MERGE_LIST;
import static com.google.gerrit.extensions.api.changes.SubmittedTogetherOption.NON_VISIBLE_CHANGES; import static com.google.gerrit.extensions.api.changes.SubmittedTogetherOption.NON_VISIBLE_CHANGES;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static com.google.gerrit.server.project.testing.TestLabels.label; import static com.google.gerrit.server.project.testing.TestLabels.label;
import static com.google.gerrit.server.project.testing.TestLabels.value; import static com.google.gerrit.server.project.testing.TestLabels.value;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
@@ -1185,9 +1186,8 @@ public abstract class AbstractDaemonTest {
GroupReference groupReference, GroupReference groupReference,
String ref, String ref,
boolean exclusive, boolean exclusive,
String... permissionNames) String... permissionNames) {
throws IOException { ProjectConfig cfg = projectCache.get(project).orElseThrow(illegalState(project)).getConfig();
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
AccessSection accessSection = cfg.getAccessSection(ref); AccessSection accessSection = cfg.getAccessSection(ref);
assertThat(accessSection).isNotNull(); assertThat(accessSection).isNotNull();
for (String permissionName : permissionNames) { for (String permissionName : permissionNames) {

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance; package com.google.gerrit.acceptance;
import static com.google.gerrit.server.git.receive.LazyPostReceiveHookChain.affectsSize; import static com.google.gerrit.server.git.receive.LazyPostReceiveHookChain.affectsSize;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static com.google.gerrit.server.quota.QuotaGroupDefinitions.REPOSITORY_SIZE_GROUP; import static com.google.gerrit.server.quota.QuotaGroupDefinitions.REPOSITORY_SIZE_GROUP;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -241,15 +242,8 @@ class InProcessProtocol extends TestProtocol<Context> {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
ProjectState projectState; ProjectState projectState =
try { projectCache.get(req.project).orElseThrow(illegalState(req.project));
projectState = projectCache.checkedGet(req.project);
} catch (IOException e) {
throw new RuntimeException(e);
}
if (projectState == null) {
throw new RuntimeException("can't load project state for " + req.project.get());
}
Repository permissionAwareRepository = PermissionAwareRepositoryManager.wrap(repo, perm); Repository permissionAwareRepository = PermissionAwareRepositoryManager.wrap(repo, perm);
UploadPack up = new UploadPack(permissionAwareRepository); UploadPack up = new UploadPack(permissionAwareRepository);
up.setPackConfig(transferConfig.getPackConfig()); up.setPackConfig(transferConfig.getPackConfig());
@@ -320,10 +314,11 @@ class InProcessProtocol extends TestProtocol<Context> {
} }
try { try {
IdentifiedUser identifiedUser = userProvider.get().asIdentifiedUser(); IdentifiedUser identifiedUser = userProvider.get().asIdentifiedUser();
ProjectState projectState = projectCache.checkedGet(req.project); ProjectState projectState =
if (projectState == null) { projectCache
throw new RuntimeException(String.format("project %s not found", req.project)); .get(req.project)
} .orElseThrow(
() -> new RuntimeException(String.format("project %s not found", req.project)));
AsyncReceiveCommits arc = factory.create(projectState, identifiedUser, db, null); AsyncReceiveCommits arc = factory.create(projectState, identifiedUser, db, null);
if (arc.canUpload() != Capable.OK) { if (arc.canUpload() != Capable.OK) {

View File

@@ -285,8 +285,11 @@ public class GitOverHttpServlet extends GitServlet {
try { try {
Project.NameKey nameKey = Project.nameKey(projectName); Project.NameKey nameKey = Project.nameKey(projectName);
ProjectState state = projectCache.checkedGet(nameKey); ProjectState state =
if (state == null || !state.statePermitsRead()) { projectCache
.get(nameKey)
.orElseThrow(() -> new RepositoryNotFoundException(nameKey.get()));
if (!state.statePermitsRead()) {
throw new RepositoryNotFoundException(nameKey.get()); throw new RepositoryNotFoundException(nameKey.get());
} }
req.setAttribute(ATT_STATE, state); req.setAttribute(ATT_STATE, state);

View File

@@ -413,15 +413,15 @@ class GitwebServlet extends HttpServlet {
} }
Project.NameKey nameKey = Project.nameKey(name); Project.NameKey nameKey = Project.nameKey(name);
ProjectState projectState; Optional<ProjectState> projectState;
try { try {
projectState = projectCache.checkedGet(nameKey); projectState = projectCache.get(nameKey);
if (projectState == null) { if (!projectState.isPresent()) {
sendErrorOrRedirect(req, rsp, HttpServletResponse.SC_NOT_FOUND); sendErrorOrRedirect(req, rsp, HttpServletResponse.SC_NOT_FOUND);
return; return;
} }
projectState.checkStatePermitsRead(); projectState.get().checkStatePermitsRead();
permissionBackend.user(userProvider.get()).project(nameKey).check(ProjectPermission.READ); permissionBackend.user(userProvider.get()).project(nameKey).check(ProjectPermission.READ);
} catch (AuthException e) { } catch (AuthException e) {
sendErrorOrRedirect(req, rsp, HttpServletResponse.SC_NOT_FOUND); sendErrorOrRedirect(req, rsp, HttpServletResponse.SC_NOT_FOUND);
@@ -437,7 +437,7 @@ class GitwebServlet extends HttpServlet {
try (Repository repo = repoManager.openRepository(nameKey)) { try (Repository repo = repoManager.openRepository(nameKey)) {
CacheHeaders.setNotCacheable(rsp); CacheHeaders.setNotCacheable(rsp);
exec(req, rsp, projectState); exec(req, rsp, projectState.get());
} catch (RepositoryNotFoundException e) { } catch (RepositoryNotFoundException e) {
getServletContext().log("Cannot open repository", e); getServletContext().log("Cannot open repository", e);
rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.httpd.raw; package com.google.gerrit.httpd.raw;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.gerrit.entities.Change; import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Patch; import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.PatchSet; import com.google.gerrit.entities.PatchSet;
@@ -123,7 +125,10 @@ public class CatServlet extends HttpServlet {
try { try {
ChangeNotes notes = changeNotesFactory.createChecked(changeId); ChangeNotes notes = changeNotesFactory.createChecked(changeId);
permissionBackend.currentUser().change(notes).check(ChangePermission.READ); permissionBackend.currentUser().change(notes).check(ChangePermission.READ);
projectCache.checkedGet(notes.getProjectName()).checkStatePermitsRead(); projectCache
.get(notes.getProjectName())
.orElseThrow(illegalState(notes.getProjectName()))
.checkStatePermitsRead();
if (patchKey.patchSetId().get() == 0) { if (patchKey.patchSetId().get() == 0) {
// change edit // change edit
Optional<ChangeEdit> edit = changeEditUtil.byChange(notes); Optional<ChangeEdit> edit = changeEditUtil.byChange(notes);

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.server;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.common.collect.HashBasedTable; import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -83,7 +84,10 @@ public class ApprovalInference {
.changeId(notes.load().getChangeId().get()) .changeId(notes.load().getChangeId().get())
.patchSetId(psId.get()) .patchSetId(psId.get())
.build())) { .build())) {
project = projectCache.checkedGet(notes.getProjectName()); project =
projectCache
.get(notes.getProjectName())
.orElseThrow(illegalState(notes.getProjectName()));
Collection<PatchSetApproval> approvals = Collection<PatchSetApproval> approvals =
getForPatchSetWithoutNormalization(notes, project, psId, rw, repoConfig); getForPatchSetWithoutNormalization(notes, project, psId, rw, repoConfig);
return labelNormalizer.normalize(notes, approvals).getNormalized(); return labelNormalizer.normalize(notes, approvals).getNormalized();

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.gerrit.server.notedb.ReviewerStateInternal.CC; import static com.google.gerrit.server.notedb.ReviewerStateInternal.CC;
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER; import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -49,7 +50,6 @@ import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.util.LabelVote; import com.google.gerrit.server.util.LabelVote;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -220,14 +220,17 @@ public class ApprovalsUtil {
private boolean canSee(ChangeNotes notes, Account.Id accountId) { private boolean canSee(ChangeNotes notes, Account.Id accountId) {
try { try {
if (!projectCache.checkedGet(notes.getProjectName()).statePermitsRead()) { if (!projectCache
.get(notes.getProjectName())
.orElseThrow(illegalState(notes.getProjectName()))
.statePermitsRead()) {
return false; return false;
} }
permissionBackend.absentUser(accountId).change(notes).check(ChangePermission.READ); permissionBackend.absentUser(accountId).change(notes).check(ChangePermission.READ);
return true; return true;
} catch (AuthException e) { } catch (AuthException e) {
return false; return false;
} catch (IOException | PermissionBackendException e) { } catch (PermissionBackendException e) {
logger.atWarning().withCause(e).log( logger.atWarning().withCause(e).log(
"Failed to check if account %d can see change %d", "Failed to check if account %d can see change %d",
accountId.get(), notes.getChangeId().get()); accountId.get(), notes.getChangeId().get());

View File

@@ -14,7 +14,6 @@
package com.google.gerrit.server; package com.google.gerrit.server;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
@@ -79,12 +78,8 @@ public class CreateGroupPermissionSyncer implements ChangeMergedListener {
* refs/groups/*}. * refs/groups/*}.
*/ */
public void syncIfNeeded() throws IOException, ConfigInvalidException { public void syncIfNeeded() throws IOException, ConfigInvalidException {
ProjectState allProjectsState = projectCache.checkedGet(allProjects); ProjectState allProjectsState = projectCache.getAllProjects();
requireNonNull( ProjectState allUsersState = projectCache.getAllUsers();
allProjectsState, () -> String.format("Can't obtain project state for %s", allProjects));
ProjectState allUsersState = projectCache.checkedGet(allUsers);
requireNonNull(
allUsersState, () -> String.format("Can't obtain project state for %s", allUsers));
Set<PermissionRule> createGroupsGlobal = Set<PermissionRule> createGroupsGlobal =
new HashSet<>(allProjectsState.getCapabilityCollection().createGroup); new HashSet<>(allProjectsState.getCapabilityCollection().createGroup);

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server; package com.google.gerrit.server;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableCollection;
@@ -145,9 +146,8 @@ public class PatchSetUtil {
return false; return false;
} }
ProjectState projectState = projectCache.checkedGet(notes.getProjectName()); ProjectState projectState =
requireNonNull( projectCache.get(notes.getProjectName()).orElseThrow(illegalState(notes.getProjectName()));
projectState, () -> String.format("Failed to load project %s", notes.getProjectName()));
ApprovalsUtil approvalsUtil = approvalsUtilProvider.get(); ApprovalsUtil approvalsUtil = approvalsUtilProvider.get();
for (PatchSetApproval ap : for (PatchSetApproval ap :

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.account; package com.google.gerrit.server.account;
import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.gerrit.server.project.ProjectCache.noSuchProject;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.common.collect.Streams; import com.google.common.collect.Streams;
@@ -106,11 +107,7 @@ public class GroupMembers {
return Collections.emptySet(); return Collections.emptySet();
} }
ProjectState projectState = projectCache.checkedGet(project); ProjectState projectState = projectCache.get(project).orElseThrow(noSuchProject(project));
if (projectState == null) {
throw new NoSuchProjectException(project);
}
final HashSet<Account> projectOwners = new HashSet<>(); final HashSet<Account> projectOwners = new HashSet<>();
for (AccountGroup.UUID ownerGroup : projectState.getAllOwners()) { for (AccountGroup.UUID ownerGroup : projectState.getAllOwners()) {
if (!seen.contains(ownerGroup)) { if (!seen.contains(ownerGroup)) {

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.api.projects; package com.google.gerrit.server.api.projects;
import static com.google.gerrit.server.api.ApiUtil.asRestApiException; import static com.google.gerrit.server.api.ApiUtil.asRestApiException;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.gerrit.common.Nullable; import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.api.projects.LabelApi; import com.google.gerrit.extensions.api.projects.LabelApi;
@@ -78,7 +79,11 @@ public class LabelApiImpl implements LabelApi {
// recreate project resource because project state was updated by creating the new label and // recreate project resource because project state was updated by creating the new label and
// needs to be reloaded // needs to be reloaded
project = project =
new ProjectResource(projectCache.checkedGet(project.getNameKey()), project.getUser()); new ProjectResource(
projectCache
.get(project.getNameKey())
.orElseThrow(illegalState(project.getNameKey())),
project.getUser());
return this; return this;
} catch (Exception e) { } catch (Exception e) {
throw asRestApiException("Cannot create branch", e); throw asRestApiException("Cannot create branch", e);

View File

@@ -28,7 +28,7 @@ import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState; import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import java.io.IOException; import java.util.Optional;
import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.OptionDef; import org.kohsuke.args4j.OptionDef;
@@ -74,10 +74,10 @@ public class ProjectHandler extends OptionHandler<ProjectState> {
String nameWithoutSuffix = ProjectUtil.stripGitSuffix(projectName); String nameWithoutSuffix = ProjectUtil.stripGitSuffix(projectName);
Project.NameKey nameKey = Project.nameKey(nameWithoutSuffix); Project.NameKey nameKey = Project.nameKey(nameWithoutSuffix);
ProjectState state; Optional<ProjectState> state;
try { try {
state = projectCache.checkedGet(nameKey); state = projectCache.get(nameKey);
if (state == null) { if (!state.isPresent()) {
throw new CmdLineException(owner, localizable("project %s not found"), nameWithoutSuffix); throw new CmdLineException(owner, localizable("project %s not found"), nameWithoutSuffix);
} }
// Hidden projects(permitsRead = false) should only be accessible by the project owners. // Hidden projects(permitsRead = false) should only be accessible by the project owners.
@@ -85,18 +85,18 @@ public class ProjectHandler extends OptionHandler<ProjectState> {
// be allowed for other users). Allowing project owners to access here will help them to view // be allowed for other users). Allowing project owners to access here will help them to view
// and update the config of hidden projects easily. // and update the config of hidden projects easily.
ProjectPermission permissionToCheck = ProjectPermission permissionToCheck =
state.statePermitsRead() ? ProjectPermission.ACCESS : ProjectPermission.READ_CONFIG; state.get().statePermitsRead() ? ProjectPermission.ACCESS : ProjectPermission.READ_CONFIG;
permissionBackend.currentUser().project(nameKey).check(permissionToCheck); permissionBackend.currentUser().project(nameKey).check(permissionToCheck);
} catch (AuthException e) { } catch (AuthException e) {
throw new CmdLineException( throw new CmdLineException(
owner, localizable(new NoSuchProjectException(nameKey, e).getMessage())); owner, localizable(new NoSuchProjectException(nameKey, e).getMessage()));
} catch (PermissionBackendException | IOException e) { } catch (PermissionBackendException e) {
logger.atWarning().withCause(e).log("Cannot load project %s", nameWithoutSuffix); logger.atWarning().withCause(e).log("Cannot load project %s", nameWithoutSuffix);
throw new CmdLineException( throw new CmdLineException(
owner, localizable(new NoSuchProjectException(nameKey).getMessage())); owner, localizable(new NoSuchProjectException(nameKey).getMessage()));
} }
setter.addValue(state); setter.addValue(state.get());
return 1; return 1;
} }

View File

@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.gerrit.extensions.client.ReviewerState.CC; import static com.google.gerrit.extensions.client.ReviewerState.CC;
import static com.google.gerrit.extensions.client.ReviewerState.REVIEWER; import static com.google.gerrit.extensions.client.ReviewerState.REVIEWER;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
@@ -175,7 +176,10 @@ public class AddReviewersOp implements BatchUpdateOp {
approvalsUtil.addReviewers( approvalsUtil.addReviewers(
ctx.getNotes(), ctx.getNotes(),
ctx.getUpdate(change.currentPatchSetId()), ctx.getUpdate(change.currentPatchSetId()),
projectCache.checkedGet(change.getProject()).getLabelTypes(change.getDest()), projectCache
.get(change.getProject())
.orElseThrow(illegalState(change.getProject()))
.getLabelTypes(change.getDest()),
change, change,
accountIds); accountIds);
} }

View File

@@ -20,6 +20,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.gerrit.entities.Change.INITIAL_PATCH_SET_ID; import static com.google.gerrit.entities.Change.INITIAL_PATCH_SET_ID;
import static com.google.gerrit.server.change.ReviewerAdder.newAddReviewerInputFromCommitIdentity; import static com.google.gerrit.server.change.ReviewerAdder.newAddReviewerInputFromCommitIdentity;
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER; import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
@@ -359,7 +360,7 @@ public class ChangeInserter implements InsertChangeOp {
@Override @Override
public void updateRepo(RepoContext ctx) throws ResourceConflictException, IOException { public void updateRepo(RepoContext ctx) throws ResourceConflictException, IOException {
cmd = new ReceiveCommand(ObjectId.zeroId(), commitId, psId.toRefName()); cmd = new ReceiveCommand(ObjectId.zeroId(), commitId, psId.toRefName());
projectState = projectCache.checkedGet(ctx.getProject()); projectState = projectCache.get(ctx.getProject()).orElseThrow(illegalState(ctx.getProject()));
validate(ctx); validate(ctx);
if (!updateRef) { if (!updateRef) {
return; return;

View File

@@ -14,10 +14,10 @@
package com.google.gerrit.server.change; package com.google.gerrit.server.change;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.google.common.hash.Hasher; import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing; import com.google.common.hash.Hashing;
@@ -47,7 +47,6 @@ import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@@ -189,14 +188,8 @@ public class ChangeResource implements RestResource, HasETag {
// TODO(dborowitz): Include more NoteDb and other related refs, e.g. drafts // TODO(dborowitz): Include more NoteDb and other related refs, e.g. drafts
// and edits. // and edits.
Iterable<ProjectState> projectStateTree; Iterable<ProjectState> projectStateTree =
try { projectCache.get(getProject()).orElseThrow(illegalState(getProject())).tree();
projectStateTree = projectCache.checkedGet(getProject()).tree();
} catch (IOException e) {
logger.atSevere().log("could not load project %s while computing etag", getProject());
projectStateTree = ImmutableList.of();
}
for (ProjectState p : projectStateTree) { for (ProjectState p : projectStateTree) {
hashObjectId(h, p.getConfig().getRevision(), buf); hashObjectId(h, p.getConfig().getRevision(), buf);
} }

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.change; package com.google.gerrit.server.change;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.data.LabelType; import com.google.gerrit.common.data.LabelType;
@@ -118,7 +120,11 @@ public class DeleteReviewerOp implements BatchUpdateOp {
currChange = ctx.getChange(); currChange = ctx.getChange();
currPs = psUtil.current(ctx.getNotes()); currPs = psUtil.current(ctx.getNotes());
LabelTypes labelTypes = projectCache.checkedGet(ctx.getProject()).getLabelTypes(ctx.getNotes()); LabelTypes labelTypes =
projectCache
.get(ctx.getProject())
.orElseThrow(illegalState(ctx.getProject()))
.getLabelTypes(ctx.getNotes());
// removing a reviewer will remove all her votes // removing a reviewer will remove all her votes
for (LabelType lt : labelTypes.getLabelTypes()) { for (LabelType lt : labelTypes.getLabelTypes()) {
newApprovals.put(lt.getName(), (short) 0); newApprovals.put(lt.getName(), (short) 0);

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.change; package com.google.gerrit.server.change;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.auto.value.AutoValue; import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
@@ -86,7 +87,11 @@ public class LabelNormalizer {
List<PatchSetApproval> unchanged = Lists.newArrayListWithCapacity(approvals.size()); List<PatchSetApproval> unchanged = Lists.newArrayListWithCapacity(approvals.size());
List<PatchSetApproval> updated = Lists.newArrayListWithCapacity(approvals.size()); List<PatchSetApproval> updated = Lists.newArrayListWithCapacity(approvals.size());
List<PatchSetApproval> deleted = Lists.newArrayListWithCapacity(approvals.size()); List<PatchSetApproval> deleted = Lists.newArrayListWithCapacity(approvals.size());
LabelTypes labelTypes = projectCache.checkedGet(notes.getProjectName()).getLabelTypes(notes); LabelTypes labelTypes =
projectCache
.get(notes.getProjectName())
.orElseThrow(illegalState(notes.getProjectName()))
.getLabelTypes(notes);
for (PatchSetApproval psa : approvals) { for (PatchSetApproval psa : approvals) {
Change.Id changeId = psa.key().patchSetId().changeId(); Change.Id changeId = psa.key().patchSetId().changeId();
checkArgument( checkArgument(

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.change;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.server.notedb.ReviewerStateInternal.CC; import static com.google.gerrit.server.notedb.ReviewerStateInternal.CC;
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER; import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
@@ -297,7 +298,10 @@ public class PatchSetInserter implements BatchUpdateOp {
if (checkAddPatchSetPermission) { if (checkAddPatchSetPermission) {
permissionBackend.user(ctx.getUser()).change(origNotes).check(ChangePermission.ADD_PATCH_SET); permissionBackend.user(ctx.getUser()).change(origNotes).check(ChangePermission.ADD_PATCH_SET);
} }
projectCache.checkedGet(ctx.getProject()).checkStatePermitsWrite(); projectCache
.get(ctx.getProject())
.orElseThrow(illegalState(ctx.getProject()))
.checkStatePermitsWrite();
if (!validate) { if (!validate) {
return; return;
} }
@@ -309,7 +313,10 @@ public class PatchSetInserter implements BatchUpdateOp {
ObjectId.zeroId(), ObjectId.zeroId(),
commitId, commitId,
refName.substring(0, refName.lastIndexOf('/') + 1) + "new"), refName.substring(0, refName.lastIndexOf('/') + 1) + "new"),
projectCache.checkedGet(origNotes.getProjectName()).getProject(), projectCache
.get(origNotes.getProjectName())
.orElseThrow(illegalState(origNotes.getProjectName()))
.getProject(),
origNotes.getChange().getDest().branch(), origNotes.getChange().getDest().branch(),
ctx.getRevWalk().getObjectReader(), ctx.getRevWalk().getObjectReader(),
commitId, commitId,

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.change; package com.google.gerrit.server.change;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.gerrit.entities.PatchSet; import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.extensions.restapi.MergeConflictException; import com.google.gerrit.extensions.restapi.MergeConflictException;
@@ -233,8 +234,9 @@ public class RebaseChangeOp implements BatchUpdateOp {
return rebasedPatchSet; return rebasedPatchSet;
} }
private MergeUtil newMergeUtil() throws IOException { private MergeUtil newMergeUtil() {
ProjectState project = projectCache.checkedGet(notes.getProjectName()); ProjectState project =
projectCache.get(notes.getProjectName()).orElseThrow(illegalState(notes.getProjectName()));
return forceContentMerge return forceContentMerge
? mergeUtilFactory.create(project, true) ? mergeUtilFactory.create(project, true)
: mergeUtilFactory.create(project); : mergeUtilFactory.create(project);

View File

@@ -20,6 +20,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.gerrit.extensions.client.ReviewerState.CC; import static com.google.gerrit.extensions.client.ReviewerState.CC;
import static com.google.gerrit.extensions.client.ReviewerState.REVIEWER; import static com.google.gerrit.extensions.client.ReviewerState.REVIEWER;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.Comparator.comparing; import static java.util.Comparator.comparing;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
@@ -203,7 +204,8 @@ public class ReviewerAdder {
boolean confirmed = input.confirmed(); boolean confirmed = input.confirmed();
boolean allowByEmail = boolean allowByEmail =
projectCache projectCache
.checkedGet(notes.getProjectName()) .get(notes.getProjectName())
.orElseThrow(illegalState(notes.getProjectName()))
.is(BooleanProjectConfig.ENABLE_REVIEWER_BY_EMAIL); .is(BooleanProjectConfig.ENABLE_REVIEWER_BY_EMAIL);
ReviewerAddition byAccountId = addByAccountId(input, notes, user); ReviewerAddition byAccountId = addByAccountId(input, notes, user);

View File

@@ -365,11 +365,8 @@ public class RevisionJson {
} catch (AuthException ae) { } catch (AuthException ae) {
return false; return false;
} }
ProjectState projectState = projectCache.checkedGet(cd.project()); ProjectState projectState =
if (projectState == null) { projectCache.get(cd.project()).orElseThrow(illegalState(cd.project()));
logger.atSevere().log("project state for project %s is null", cd.project());
return false;
}
return projectState.statePermitsRead(); return projectState.statePermitsRead();
} }

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.edit; package com.google.gerrit.server.edit;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.gerrit.entities.Change; import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.PatchSet; import com.google.gerrit.entities.PatchSet;
@@ -426,7 +428,10 @@ public class ChangeEditModifier {
patchSetUtil.checkPatchSetNotLocked(notes); patchSetUtil.checkPatchSetNotLocked(notes);
try { try {
permissionBackend.currentUser().change(notes).check(ChangePermission.ADD_PATCH_SET); permissionBackend.currentUser().change(notes).check(ChangePermission.ADD_PATCH_SET);
projectCache.checkedGet(notes.getProjectName()).checkStatePermitsWrite(); projectCache
.get(notes.getProjectName())
.orElseThrow(illegalState(notes.getProjectName()))
.checkStatePermitsWrite();
} catch (AuthException denied) { } catch (AuthException denied) {
throw new AuthException("edit not permitted", denied); throw new AuthException("edit not permitted", denied);
} }

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.git; package com.google.gerrit.server.git;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
@@ -178,7 +180,7 @@ public class PureRevertCache {
// Rebase claimed revert onto claimed original // Rebase claimed revert onto claimed original
ThreeWayMerger merger = ThreeWayMerger merger =
mergeUtilFactory mergeUtilFactory
.create(projectCache.checkedGet(project)) .create(projectCache.get(project).orElseThrow(illegalState(project)))
.newThreeWayMerger(oi, repo.getConfig()); .newThreeWayMerger(oi, repo.getConfig());
merger.setBase(claimedRevertCommit.getParent(0)); merger.setBase(claimedRevertCommit.getParent(0));
boolean success = merger.merge(claimedRevertCommit, claimedOriginalCommit); boolean success = merger.merge(claimedRevertCommit, claimedOriginalCommit);

View File

@@ -21,6 +21,7 @@ import static com.google.gerrit.server.change.ReviewerAdder.newAddReviewerInputF
import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromFooters; import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromFooters;
import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromReviewers; import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromReviewers;
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER; import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static org.eclipse.jgit.lib.Constants.R_HEADS; import static org.eclipse.jgit.lib.Constants.R_HEADS;
import com.google.common.base.Strings; import com.google.common.base.Strings;
@@ -549,7 +550,11 @@ public class ReplaceOp implements BatchUpdateOp {
* show a transition from an oldValue of 0 to the new value. * show a transition from an oldValue of 0 to the new value.
*/ */
List<LabelType> labels = List<LabelType> labels =
projectCache.checkedGet(ctx.getProject()).getLabelTypes(notes).getLabelTypes(); projectCache
.get(ctx.getProject())
.orElseThrow(illegalState(ctx.getProject()))
.getLabelTypes(notes)
.getLabelTypes();
Map<String, Short> allApprovals = new HashMap<>(); Map<String, Short> allApprovals = new HashMap<>();
Map<String, Short> oldApprovals = new HashMap<>(); Map<String, Short> oldApprovals = new HashMap<>();
for (LabelType lt : labels) { for (LabelType lt : labels) {

View File

@@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.entities.Change.CHANGE_ID_PATTERN; import static com.google.gerrit.entities.Change.CHANGE_ID_PATTERN;
import static com.google.gerrit.entities.RefNames.REFS_CHANGES; import static com.google.gerrit.entities.RefNames.REFS_CHANGES;
import static com.google.gerrit.entities.RefNames.REFS_CONFIG; import static com.google.gerrit.entities.RefNames.REFS_CONFIG;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
@@ -144,7 +145,8 @@ public class CommitValidators {
boolean skipValidation) boolean skipValidation)
throws IOException { throws IOException {
PermissionBackend.ForRef perm = forProject.ref(branch.branch()); PermissionBackend.ForRef perm = forProject.ref(branch.branch());
ProjectState projectState = projectCache.checkedGet(branch.project()); ProjectState projectState =
projectCache.get(branch.project()).orElseThrow(illegalState(branch.project()));
return new CommitValidators( return new CommitValidators(
ImmutableList.of( ImmutableList.of(
new UploadMergesPermissionValidator(perm), new UploadMergesPermissionValidator(perm),
@@ -173,7 +175,8 @@ public class CommitValidators {
@Nullable Change change) @Nullable Change change)
throws IOException { throws IOException {
PermissionBackend.ForRef perm = forProject.ref(branch.branch()); PermissionBackend.ForRef perm = forProject.ref(branch.branch());
ProjectState projectState = projectCache.checkedGet(branch.project()); ProjectState projectState =
projectCache.get(branch.project()).orElseThrow(illegalState(branch.project()));
return new CommitValidators( return new CommitValidators(
ImmutableList.of( ImmutableList.of(
new UploadMergesPermissionValidator(perm), new UploadMergesPermissionValidator(perm),
@@ -181,7 +184,7 @@ public class CommitValidators {
new AmendedGerritMergeCommitValidationListener(perm, gerritIdent), new AmendedGerritMergeCommitValidationListener(perm, gerritIdent),
new AuthorUploaderValidator(user, perm, urlFormatter.get()), new AuthorUploaderValidator(user, perm, urlFormatter.get()),
new FileCountValidator(patchListCache, config), new FileCountValidator(patchListCache, config),
new SignedOffByValidator(user, perm, projectCache.checkedGet(branch.project())), new SignedOffByValidator(user, perm, projectState),
new ChangeIdValidator( new ChangeIdValidator(
projectState, user, urlFormatter.get(), config, sshInfo, change), projectState, user, urlFormatter.get(), config, sshInfo, change),
new ConfigValidator(projectConfigFactory, branch, user, rw, allUsers, allProjects), new ConfigValidator(projectConfigFactory, branch, user, rw, allUsers, allProjects),
@@ -208,10 +211,12 @@ public class CommitValidators {
// - Plugin validators may do things like require certain commit message // - Plugin validators may do things like require certain commit message
// formats, so we play it safe and exclude them. // formats, so we play it safe and exclude them.
PermissionBackend.ForRef perm = forProject.ref(branch.branch()); PermissionBackend.ForRef perm = forProject.ref(branch.branch());
ProjectState projectState =
projectCache.get(branch.project()).orElseThrow(illegalState(branch.project()));
return new CommitValidators( return new CommitValidators(
ImmutableList.of( ImmutableList.of(
new UploadMergesPermissionValidator(perm), new UploadMergesPermissionValidator(perm),
new ProjectStateValidationListener(projectCache.checkedGet(branch.project())), new ProjectStateValidationListener(projectState),
new AuthorUploaderValidator(user, perm, urlFormatter.get()), new AuthorUploaderValidator(user, perm, urlFormatter.get()),
new CommitterUploaderValidator(user, perm, urlFormatter.get()))); new CommitterUploaderValidator(user, perm, urlFormatter.get())));
} }

View File

@@ -47,6 +47,7 @@ import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.InvalidChangeOperationException; import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject; import com.google.inject.assistedinject.AssistedInject;
@@ -196,7 +197,10 @@ public class PatchScriptFactory implements Callable<PatchScript> {
throw new NoSuchChangeException(changeId, e); throw new NoSuchChangeException(changeId, e);
} }
if (!projectCache.checkedGet(notes.getProjectName()).statePermitsRead()) { if (!projectCache
.get(notes.getProjectName())
.map(ProjectState::statePermitsRead)
.orElse(false)) {
throw new NoSuchChangeException(changeId); throw new NoSuchChangeException(changeId);
} }

View File

@@ -34,6 +34,7 @@ import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.InvalidChangeOperationException; import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject; import com.google.inject.assistedinject.AssistedInject;
@@ -102,7 +103,10 @@ public class PatchScriptFactoryForAutoFix implements Callable<PatchScript> {
throw new NoSuchChangeException(changeId, e); throw new NoSuchChangeException(changeId, e);
} }
if (!projectCache.checkedGet(notes.getProjectName()).statePermitsRead()) { if (!projectCache
.get(notes.getProjectName())
.map(ProjectState::statePermitsRead)
.orElse(false)) {
throw new NoSuchChangeException(changeId); throw new NoSuchChangeException(changeId);
} }

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.permissions; package com.google.gerrit.server.permissions;
import static com.google.gerrit.server.permissions.DefaultPermissionMappings.globalPermissionName; import static com.google.gerrit.server.permissions.DefaultPermissionMappings.globalPermissionName;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toSet; import static java.util.stream.Collectors.toSet;
@@ -103,7 +104,7 @@ public class DefaultPermissionBackend extends PermissionBackend {
@Override @Override
public ForProject project(Project.NameKey project) { public ForProject project(Project.NameKey project) {
try { try {
ProjectState state = projectCache.checkedGet(project); ProjectState state = projectCache.get(project).orElseThrow(illegalState(project));
ProjectControl control = ProjectControl control =
PerThreadCache.getOrCompute( PerThreadCache.getOrCompute(
PerThreadCache.Key.create(ProjectControl.class, project, user.getCacheKey()), PerThreadCache.Key.create(ProjectControl.class, project, user.getCacheKey()),

View File

@@ -78,11 +78,8 @@ public class ContributorAgreementsChecker {
public void check(Project.NameKey project, CurrentUser user) throws IOException, AuthException { public void check(Project.NameKey project, CurrentUser user) throws IOException, AuthException {
metrics.claCheckCount.increment(); metrics.claCheckCount.increment();
ProjectState projectState = projectCache.checkedGet(project); ProjectState projectState =
if (projectState == null) { projectCache.get(project).orElseThrow(() -> new IOException("Can't load " + project));
throw new IOException("Can't load All-Projects");
}
if (!projectState.is(BooleanProjectConfig.USE_CONTRIBUTOR_AGREEMENTS)) { if (!projectState.is(BooleanProjectConfig.USE_CONTRIBUTOR_AGREEMENTS)) {
return; return;
} }

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.project; package com.google.gerrit.server.project;
import static com.google.gerrit.server.project.ProjectCache.noSuchProject;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.BranchNameKey; import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Project; import com.google.gerrit.entities.Project;
@@ -67,10 +69,8 @@ public class CreateRefControl {
Provider<? extends CurrentUser> user, Repository repo, BranchNameKey branch, RevObject object) Provider<? extends CurrentUser> user, Repository repo, BranchNameKey branch, RevObject object)
throws AuthException, PermissionBackendException, NoSuchProjectException, IOException, throws AuthException, PermissionBackendException, NoSuchProjectException, IOException,
ResourceConflictException { ResourceConflictException {
ProjectState ps = projectCache.checkedGet(branch.project()); ProjectState ps =
if (ps == null) { projectCache.get(branch.project()).orElseThrow(noSuchProject(branch.project()));
throw new NoSuchProjectException(branch.project());
}
ps.checkStatePermitsWrite(); ps.checkStatePermitsWrite();
PermissionBackend.ForRef perm = permissionBackend.user(user.get()).ref(branch); PermissionBackend.ForRef perm = permissionBackend.user(user.get()).ref(branch);

View File

@@ -55,21 +55,9 @@ public interface ProjectCache {
* @return an {@link Optional} wrapping the the cached data; {@code absent} if no such project * @return an {@link Optional} wrapping the the cached data; {@code absent} if no such project
* exists or the projectName is null * exists or the projectName is null
* @throws StorageException when there was an error. * @throws StorageException when there was an error.
* @see #checkedGet(com.google.gerrit.entities.Project.NameKey)
*/ */
Optional<ProjectState> get(@Nullable Project.NameKey projectName) throws StorageException; Optional<ProjectState> get(@Nullable Project.NameKey projectName) throws StorageException;
/**
* Get the cached data for a project by its unique name.
*
* @param projectName name of the project.
* @throws IOException when there was an error.
* @return the cached data; null if no such project exists or projectName is null.
* @deprecated use {@link #get(Project.NameKey)} instead.
*/
@Deprecated
ProjectState checkedGet(@Nullable Project.NameKey projectName) throws IOException;
/** /**
* Invalidate the cached information about the given project, and triggers reindexing for it * Invalidate the cached information about the given project, and triggers reindexing for it
* *

View File

@@ -18,13 +18,13 @@ import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.stream.Collectors.toSet; import static java.util.stream.Collectors.toSet;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Throwables;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.AccountGroup; import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.Project; import com.google.gerrit.entities.Project;
import com.google.gerrit.exceptions.StorageException; import com.google.gerrit.exceptions.StorageException;
@@ -136,41 +136,25 @@ public class ProjectCacheImpl implements ProjectCache {
} }
@Override @Override
public Optional<ProjectState> get(Project.NameKey projectName) { public Optional<ProjectState> get(@Nullable Project.NameKey projectName) {
try {
return Optional.ofNullable(checkedGet(projectName));
} catch (IOException e) {
throw new StorageException("project state not available", e);
}
}
@Override
public ProjectState checkedGet(Project.NameKey projectName) throws IOException {
if (projectName == null) { if (projectName == null) {
return null; return Optional.empty();
}
try {
return strictCheckedGet(projectName);
} catch (Exception e) {
if (!(e.getCause() instanceof RepositoryNotFoundException)) {
logger.atWarning().withCause(e).log("Cannot read project %s", projectName.get());
if (e.getCause() != null) {
Throwables.throwIfInstanceOf(e.getCause(), IOException.class);
}
throw new IOException(e);
}
logger.atFine().log("Cannot find project %s", projectName.get());
return null;
}
} }
private ProjectState strictCheckedGet(Project.NameKey projectName) throws Exception { try {
ProjectState state = byName.get(projectName.get()); ProjectState state = byName.get(projectName.get());
if (state != null && state.needsRefresh(clock.read())) { if (state != null && state.needsRefresh(clock.read())) {
byName.invalidate(projectName.get()); byName.invalidate(projectName.get());
state = byName.get(projectName.get()); state = byName.get(projectName.get());
} }
return state; return Optional.of(state);
} catch (Exception e) {
if ((e.getCause() instanceof RepositoryNotFoundException)) {
logger.atFine().log("Cannot find project %s", projectName.get());
return Optional.empty();
}
throw new StorageException("project state not available", e);
}
} }
@Override @Override

View File

@@ -473,12 +473,7 @@ public class ChangeData {
public LabelTypes getLabelTypes() { public LabelTypes getLabelTypes() {
if (labelTypes == null) { if (labelTypes == null) {
ProjectState state; ProjectState state = projectCache.get(project()).orElseThrow(illegalState(project()));
try {
state = projectCache.checkedGet(project());
} catch (IOException e) {
throw new StorageException("project state not available", e);
}
labelTypes = state.getLabelTypes(change().getDest()); labelTypes = state.getLabelTypes(change().getDest());
} }
return labelTypes; return labelTypes;

View File

@@ -30,7 +30,7 @@ import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState; import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import java.io.IOException; import java.util.Optional;
import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.errors.RepositoryNotFoundException;
public class ChangeIsVisibleToPredicate extends IsVisibleToPredicate<ChangeData> { public class ChangeIsVisibleToPredicate extends IsVisibleToPredicate<ChangeData> {
@@ -68,20 +68,15 @@ public class ChangeIsVisibleToPredicate extends IsVisibleToPredicate<ChangeData>
} }
ChangeNotes notes = notesFactory.createFromIndexedChange(change); ChangeNotes notes = notesFactory.createFromIndexedChange(change);
Optional<ProjectState> projectState = projectCache.get(cd.project());
try { if (!projectState.isPresent()) {
ProjectState projectState = projectCache.checkedGet(cd.project());
if (projectState == null) {
logger.atFine().log("Filter out change %s of non-existing project %s", cd, cd.project()); logger.atFine().log("Filter out change %s of non-existing project %s", cd, cd.project());
return false; return false;
} }
if (!projectState.statePermitsRead()) { if (!projectState.get().statePermitsRead()) {
logger.atFine().log("Filter out change %s of non-reabable project %s", cd, cd.project()); logger.atFine().log("Filter out change %s of non-reabable project %s", cd, cd.project());
return false; return false;
} }
} catch (IOException e) {
throw new StorageException("unable to read project state", e);
}
PermissionBackend.WithUser withUser = PermissionBackend.WithUser withUser =
user.isIdentifiedUser() user.isIdentifiedUser()

View File

@@ -28,7 +28,6 @@ import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException; import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState; import com.google.gerrit.server.project.ProjectState;
import java.io.IOException;
import java.util.Optional; import java.util.Optional;
public class EqualsLabelPredicate extends ChangeIndexPredicate { public class EqualsLabelPredicate extends ChangeIndexPredicate {
@@ -120,14 +119,13 @@ public class EqualsLabelPredicate extends ChangeIndexPredicate {
// Check the user has 'READ' permission. // Check the user has 'READ' permission.
try { try {
PermissionBackend.ForChange perm = permissionBackend.absentUser(approver).change(cd); PermissionBackend.ForChange perm = permissionBackend.absentUser(approver).change(cd);
ProjectState projectState = projectCache.checkedGet(cd.project()); if (!projectCache.get(cd.project()).map(ProjectState::statePermitsRead).orElse(false)) {
if (projectState == null || !projectState.statePermitsRead()) {
return false; return false;
} }
perm.check(ChangePermission.READ); perm.check(ChangePermission.READ);
return true; return true;
} catch (PermissionBackendException | IOException | AuthException e) { } catch (PermissionBackendException | AuthException e) {
return false; return false;
} }
} }

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.gerrit.entities.PatchSet; import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project; import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.common.EditInfo; import com.google.gerrit.extensions.common.EditInfo;
@@ -70,7 +72,7 @@ public class ApplyFix implements RestModifyView<FixResource, Void> {
ResourceNotFoundException, PermissionBackendException { ResourceNotFoundException, PermissionBackendException {
RevisionResource revisionResource = fixResource.getRevisionResource(); RevisionResource revisionResource = fixResource.getRevisionResource();
Project.NameKey project = revisionResource.getProject(); Project.NameKey project = revisionResource.getProject();
ProjectState projectState = projectCache.checkedGet(project); ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project));
PatchSet patchSet = revisionResource.getPatchSet(); PatchSet patchSet = revisionResource.getPatchSet();
try (Repository repository = gitRepositoryManager.openRepository(project)) { try (Repository repository = gitRepositoryManager.openRepository(project)) {

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.gerrit.entities.Change; import com.google.gerrit.entities.Change;
@@ -365,9 +367,10 @@ public class ChangeEdits implements ChildCollection<ChangeResource, ChangeEditRe
public Response<BinaryResult> apply(ChangeEditResource rsrc) throws IOException { public Response<BinaryResult> apply(ChangeEditResource rsrc) throws IOException {
try { try {
ChangeEdit edit = rsrc.getChangeEdit(); ChangeEdit edit = rsrc.getChangeEdit();
Project.NameKey project = rsrc.getChangeResource().getProject();
return Response.ok( return Response.ok(
fileContentUtil.getContent( fileContentUtil.getContent(
projectCache.checkedGet(rsrc.getChangeResource().getProject()), projectCache.get(project).orElseThrow(illegalState(project)),
base ? edit.getBasePatchSet().commitId() : edit.getEditCommit(), base ? edit.getBasePatchSet().commitId() : edit.getEditCommit(),
rsrc.getPath(), rsrc.getPath(),
null)); null));

View File

@@ -39,6 +39,7 @@ import com.google.inject.Provider;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Optional;
@Singleton @Singleton
public class ChangesCollection implements RestCollection<TopLevelResource, ChangeResource> { public class ChangesCollection implements RestCollection<TopLevelResource, ChangeResource> {
@@ -128,19 +129,18 @@ public class ChangesCollection implements RestCollection<TopLevelResource, Chang
} catch (AuthException e) { } catch (AuthException e) {
return false; return false;
} }
ProjectState projectState = projectCache.checkedGet(notes.getProjectName()); Optional<ProjectState> projectState = projectCache.get(notes.getProjectName());
if (projectState == null) { if (!projectState.isPresent()) {
return false; return false;
} }
return projectState.statePermitsRead(); return projectState.get().statePermitsRead();
} }
private void checkProjectStatePermitsRead(Project.NameKey project) private void checkProjectStatePermitsRead(Project.NameKey project)
throws IOException, ResourceNotFoundException, ResourceConflictException { throws ResourceNotFoundException, ResourceConflictException {
ProjectState projectState = projectCache.checkedGet(project); projectCache
if (projectState == null) { .get(project)
throw new ResourceNotFoundException("project not found: " + project.get()); .orElseThrow(() -> new ResourceNotFoundException("project not found: " + project.get()))
} .checkStatePermitsRead();
projectState.checkStatePermitsRead();
} }
} }

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.extensions.conditions.BooleanCondition.and; import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.BranchNameKey; import com.google.gerrit.entities.BranchNameKey;
@@ -38,6 +39,7 @@ import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.update.UpdateException; import com.google.gerrit.server.update.UpdateException;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
@@ -86,7 +88,10 @@ public class CherryPick
.project(rsrc.getChange().getProject()) .project(rsrc.getChange().getProject())
.ref(refName) .ref(refName)
.check(RefPermission.CREATE_CHANGE); .check(RefPermission.CREATE_CHANGE);
projectCache.checkedGet(rsrc.getProject()).checkStatePermitsWrite(); projectCache
.get(rsrc.getProject())
.orElseThrow(illegalState(rsrc.getProject()))
.checkStatePermitsWrite();
try { try {
CherryPickChange.Result cherryPickResult = CherryPickChange.Result cherryPickResult =
@@ -109,13 +114,8 @@ public class CherryPick
@Override @Override
public UiAction.Description getDescription(RevisionResource rsrc) { public UiAction.Description getDescription(RevisionResource rsrc) {
boolean projectStatePermitsWrite = false; boolean projectStatePermitsWrite =
try { projectCache.get(rsrc.getProject()).map(ProjectState::statePermitsWrite).orElse(false);
projectStatePermitsWrite = projectCache.checkedGet(rsrc.getProject()).statePermitsWrite();
} catch (IOException e) {
logger.atSevere().withCause(e).log(
"Failed to check if project state permits write: %s", rsrc.getProject());
}
return new UiAction.Description() return new UiAction.Description()
.setLabel("Cherry Pick") .setLabel("Cherry Pick")
.setTitle("Cherry pick change to a different branch") .setTitle("Cherry pick change to a different branch")

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.gerrit.server.project.ProjectCache.noSuchProject;
import com.google.auto.value.AutoValue; import com.google.auto.value.AutoValue;
import com.google.common.base.Strings; import com.google.common.base.Strings;
@@ -308,10 +309,8 @@ public class CherryPickChange {
String commitMessage = ChangeIdUtil.insertId(message, generatedChangeId).trim() + '\n'; String commitMessage = ChangeIdUtil.insertId(message, generatedChangeId).trim() + '\n';
CodeReviewCommit cherryPickCommit; CodeReviewCommit cherryPickCommit;
ProjectState projectState = projectCache.checkedGet(dest.project()); ProjectState projectState =
if (projectState == null) { projectCache.get(dest.project()).orElseThrow(noSuchProject(dest.project()));
throw new NoSuchProjectException(dest.project());
}
try { try {
MergeUtil mergeUtil; MergeUtil mergeUtil;
if (input.allowConflicts) { if (input.allowConflicts) {

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
@@ -127,7 +129,8 @@ public class CreateMergePatchSet implements RestModifyView<ChangeResource, Merge
rsrc.permissions().check(ChangePermission.ADD_PATCH_SET); rsrc.permissions().check(ChangePermission.ADD_PATCH_SET);
ProjectState projectState = projectCache.checkedGet(rsrc.getProject()); ProjectState projectState =
projectCache.get(rsrc.getProject()).orElseThrow(illegalState(rsrc.getProject()));
projectState.checkStatePermitsWrite(); projectState.checkStatePermitsWrite();
MergeInput merge = in.merge; MergeInput merge = in.merge;

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
@@ -129,7 +130,9 @@ public class DeleteVote implements RestModifyView<VoteResource, DeleteVoteInput>
bu.addOp( bu.addOp(
change.getId(), change.getId(),
new Op( new Op(
projectCache.checkedGet(r.getChange().getProject()), projectCache
.get(r.getChange().getProject())
.orElseThrow(illegalState(r.getChange().getProject())),
r.getReviewerUser().state(), r.getReviewerUser().state(),
rsrc.getLabel(), rsrc.getLabel(),
input)); input));

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.gerrit.extensions.restapi.BinaryResult; import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException; import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.Response; import com.google.gerrit.extensions.restapi.Response;
@@ -47,6 +49,9 @@ public class DownloadContent implements RestReadView<FileResource> {
RevisionResource rev = rsrc.getRevision(); RevisionResource rev = rsrc.getRevision();
return Response.ok( return Response.ok(
fileContentUtil.downloadContent( fileContentUtil.downloadContent(
projectCache.checkedGet(rev.getProject()), rev.getPatchSet().commitId(), path, parent)); projectCache.get(rev.getProject()).orElseThrow(illegalState(rev.getProject())),
rev.getPatchSet().commitId(),
path,
parent));
} }
} }

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.gerrit.entities.Change; import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Patch; import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.PatchSet; import com.google.gerrit.entities.PatchSet;
@@ -79,7 +81,9 @@ public class GetContent implements RestReadView<FileResource> {
} }
return Response.ok( return Response.ok(
fileContentUtil.getContent( fileContentUtil.getContent(
projectCache.checkedGet(rsrc.getRevision().getProject()), projectCache
.get(rsrc.getRevision().getProject())
.orElseThrow(illegalState(rsrc.getRevision().getProject())),
rsrc.getRevision().getPatchSet().commitId(), rsrc.getRevision().getPatchSet().commitId(),
path, path,
parent)); parent));

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.extensions.conditions.BooleanCondition.and; import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
import static com.google.gerrit.server.permissions.ChangePermission.ABANDON; import static com.google.gerrit.server.permissions.ChangePermission.ABANDON;
import static com.google.gerrit.server.permissions.RefPermission.CREATE_CHANGE; import static com.google.gerrit.server.permissions.RefPermission.CREATE_CHANGE;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static com.google.gerrit.server.query.change.ChangeData.asChanges; import static com.google.gerrit.server.query.change.ChangeData.asChanges;
import com.google.common.base.Strings; import com.google.common.base.Strings;
@@ -149,7 +150,7 @@ public class Move implements RestModifyView<ChangeResource, MoveInput>, UiAction
} catch (AuthException denied) { } catch (AuthException denied) {
throw new AuthException("move not permitted", denied); throw new AuthException("move not permitted", denied);
} }
projectCache.checkedGet(project).checkStatePermitsWrite(); projectCache.get(project).orElseThrow(illegalState(project)).checkStatePermitsWrite();
Op op = new Op(input); Op op = new Op(input);
try (BatchUpdate u = updateFactory.create(project, caller, TimeUtil.nowTs())) { try (BatchUpdate u = updateFactory.create(project, caller, TimeUtil.nowTs())) {
@@ -259,7 +260,7 @@ public class Move implements RestModifyView<ChangeResource, MoveInput>, UiAction
for (PatchSetApproval psa : for (PatchSetApproval psa :
approvalsUtil.byPatchSet( approvalsUtil.byPatchSet(
ctx.getNotes(), psId, ctx.getRevWalk(), ctx.getRepoView().getConfig())) { ctx.getNotes(), psId, ctx.getRevWalk(), ctx.getRepoView().getConfig())) {
ProjectState projectState = projectCache.checkedGet(project); ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project));
LabelType type = projectState.getLabelTypes(ctx.getNotes()).byLabel(psa.labelId()); LabelType type = projectState.getLabelTypes(ctx.getNotes()).byLabel(psa.labelId());
// Only keep veto votes, defined as votes where: // Only keep veto votes, defined as votes where:
// 1- the label function allows minimum values to block submission. // 1- the label function allows minimum values to block submission.
@@ -294,10 +295,13 @@ public class Move implements RestModifyView<ChangeResource, MoveInput>, UiAction
} }
try { try {
if (!projectCache.checkedGet(rsrc.getProject()).statePermitsWrite()) { if (!projectCache
.get(rsrc.getProject())
.orElseThrow(illegalState(rsrc.getProject()))
.statePermitsWrite()) {
return description; return description;
} }
} catch (IOException e) { } catch (StorageException e) {
logger.atSevere().withCause(e).log( logger.atSevere().withCause(e).log(
"Failed to check if project state permits write: %s", rsrc.getProject()); "Failed to check if project state permits write: %s", rsrc.getProject());
return description; return description;

View File

@@ -20,6 +20,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.gerrit.server.CommentsUtil.setCommentCommitId; import static com.google.gerrit.server.CommentsUtil.setCommentCommitId;
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER; import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
import static com.google.gerrit.server.permissions.LabelPermission.ForUser.ON_BEHALF_OF; import static com.google.gerrit.server.permissions.LabelPermission.ForUser.ON_BEHALF_OF;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.groupingBy;
@@ -235,7 +236,8 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
if (revision.getEdit().isPresent()) { if (revision.getEdit().isPresent()) {
throw new ResourceConflictException("cannot post review on edit"); throw new ResourceConflictException("cannot post review on edit");
} }
ProjectState projectState = projectCache.checkedGet(revision.getProject()); ProjectState projectState =
projectCache.get(revision.getProject()).orElseThrow(illegalState(revision.getProject()));
LabelTypes labelTypes = projectState.getLabelTypes(revision.getNotes()); LabelTypes labelTypes = projectState.getLabelTypes(revision.getNotes());
logger.atFine().log("strict label checking is %s", (strictLabels ? "enabled" : "disabled")); logger.atFine().log("strict label checking is %s", (strictLabels ? "enabled" : "disabled"));

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.gerrit.common.FooterConstants; import com.google.gerrit.common.FooterConstants;
import com.google.gerrit.entities.BooleanProjectConfig; import com.google.gerrit.entities.BooleanProjectConfig;
import com.google.gerrit.entities.PatchSet; import com.google.gerrit.entities.PatchSet;
@@ -112,7 +114,8 @@ public class PutMessage implements RestModifyView<ChangeResource, CommitMessageI
sanitizedCommitMessage = sanitizedCommitMessage =
ensureChangeIdIsCorrect( ensureChangeIdIsCorrect(
projectCache projectCache
.checkedGet(resource.getProject()) .get(resource.getProject())
.orElseThrow(illegalState(resource.getProject()))
.is(BooleanProjectConfig.REQUIRE_CHANGE_ID), .is(BooleanProjectConfig.REQUIRE_CHANGE_ID),
resource.getChange().getKey().get(), resource.getChange().getKey().get(),
sanitizedCommitMessage); sanitizedCommitMessage);
@@ -188,7 +191,10 @@ public class PutMessage implements RestModifyView<ChangeResource, CommitMessageI
.user(userProvider.get()) .user(userProvider.get())
.change(changeNotes) .change(changeNotes)
.check(ChangePermission.ADD_PATCH_SET); .check(ChangePermission.ADD_PATCH_SET);
projectCache.checkedGet(changeNotes.getProjectName()).checkStatePermitsWrite(); projectCache
.get(changeNotes.getProjectName())
.orElseThrow(illegalState(changeNotes.getProjectName()))
.checkStatePermitsWrite();
} catch (AuthException denied) { } catch (AuthException denied) {
throw new AuthException("modifying commit message not permitted", denied); throw new AuthException("modifying commit message not permitted", denied);
} }

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
@@ -104,7 +106,10 @@ public class Rebase
patchSetUtil.checkPatchSetNotLocked(rsrc.getNotes()); patchSetUtil.checkPatchSetNotLocked(rsrc.getNotes());
rsrc.permissions().check(ChangePermission.REBASE); rsrc.permissions().check(ChangePermission.REBASE);
projectCache.checkedGet(rsrc.getProject()).checkStatePermitsWrite(); projectCache
.get(rsrc.getProject())
.orElseThrow(illegalState(rsrc.getProject()))
.checkStatePermitsWrite();
Change change = rsrc.getChange(); Change change = rsrc.getChange();
try (Repository repo = repoManager.openRepository(change.getProject()); try (Repository repo = repoManager.openRepository(change.getProject());
@@ -217,10 +222,13 @@ public class Rebase
} }
try { try {
if (!projectCache.checkedGet(rsrc.getProject()).statePermitsWrite()) { if (!projectCache
.get(rsrc.getProject())
.orElseThrow(illegalState(rsrc.getProject()))
.statePermitsWrite()) {
return description; return description;
} }
} catch (IOException e) { } catch (StorageException e) {
logger.atSevere().withCause(e).log( logger.atSevere().withCause(e).log(
"Failed to check if project state permits write: %s", rsrc.getProject()); "Failed to check if project state permits write: %s", rsrc.getProject());
return description; return description;

View File

@@ -235,15 +235,14 @@ class RelatedChangesSorter {
return result; return result;
} }
private boolean isVisible(PatchSetData psd) throws PermissionBackendException, IOException { private boolean isVisible(PatchSetData psd) throws PermissionBackendException {
PermissionBackend.WithUser perm = permissionBackend.currentUser(); PermissionBackend.WithUser perm = permissionBackend.currentUser();
try { try {
perm.change(psd.data()).check(ChangePermission.READ); perm.change(psd.data()).check(ChangePermission.READ);
} catch (AuthException e) { } catch (AuthException e) {
return false; return false;
} }
ProjectState state = projectCache.checkedGet(psd.data().project()); return projectCache.get(psd.data().project()).map(ProjectState::statePermitsRead).orElse(false);
return state != null && state.statePermitsRead();
} }
@AutoValue @AutoValue

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Change; import com.google.gerrit.entities.Change;
@@ -40,6 +42,7 @@ import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.permissions.ChangePermission; import com.google.gerrit.server.permissions.ChangePermission;
import com.google.gerrit.server.permissions.PermissionBackendException; import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.update.BatchUpdate; import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp; import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext; import com.google.gerrit.server.update.ChangeContext;
@@ -88,7 +91,10 @@ public class Restore
psUtil.checkPatchSetNotLocked(rsrc.getNotes()); psUtil.checkPatchSetNotLocked(rsrc.getNotes());
rsrc.permissions().check(ChangePermission.RESTORE); rsrc.permissions().check(ChangePermission.RESTORE);
projectCache.checkedGet(rsrc.getProject()).checkStatePermitsWrite(); projectCache
.get(rsrc.getProject())
.orElseThrow(illegalState(rsrc.getProject()))
.checkStatePermitsWrite();
Op op = new Op(input); Op op = new Op(input);
try (BatchUpdate u = try (BatchUpdate u =
@@ -166,10 +172,10 @@ public class Restore
} }
try { try {
if (!projectCache.checkedGet(rsrc.getProject()).statePermitsWrite()) { if (!projectCache.get(rsrc.getProject()).map(ProjectState::statePermitsRead).orElse(false)) {
return description; return description;
} }
} catch (IOException e) { } catch (StorageException e) {
logger.atSevere().withCause(e).log( logger.atSevere().withCause(e).log(
"Failed to check if project state permits write: %s", rsrc.getProject()); "Failed to check if project state permits write: %s", rsrc.getProject());
return description; return description;

View File

@@ -16,10 +16,12 @@ package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.extensions.conditions.BooleanCondition.and; import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
import static com.google.gerrit.server.permissions.RefPermission.CREATE_CHANGE; import static com.google.gerrit.server.permissions.RefPermission.CREATE_CHANGE;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Change; import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.PatchSet; import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.api.changes.RevertInput; import com.google.gerrit.extensions.api.changes.RevertInput;
import com.google.gerrit.extensions.common.ChangeInfo; import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.restapi.ResourceConflictException; import com.google.gerrit.extensions.restapi.ResourceConflictException;
@@ -40,6 +42,7 @@ import com.google.gerrit.server.project.ContributorAgreementsChecker;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.update.UpdateException; import com.google.gerrit.server.update.UpdateException;
import com.google.gerrit.server.util.time.TimeUtil; import com.google.gerrit.server.util.time.TimeUtil;
import com.google.inject.Inject; import com.google.inject.Inject;
@@ -87,7 +90,10 @@ public class Revert
contributorAgreements.check(rsrc.getProject(), rsrc.getUser()); contributorAgreements.check(rsrc.getProject(), rsrc.getUser());
permissionBackend.user(rsrc.getUser()).ref(change.getDest()).check(CREATE_CHANGE); permissionBackend.user(rsrc.getUser()).ref(change.getDest()).check(CREATE_CHANGE);
projectCache.checkedGet(rsrc.getProject()).checkStatePermitsWrite(); projectCache
.get(rsrc.getProject())
.orElseThrow(illegalState(rsrc.getProject()))
.checkStatePermitsWrite();
ChangeNotes notes = rsrc.getNotes(); ChangeNotes notes = rsrc.getNotes();
Change.Id changeIdToRevert = notes.getChangeId(); Change.Id changeIdToRevert = notes.getChangeId();
PatchSet.Id patchSetId = notes.getChange().currentPatchSetId(); PatchSet.Id patchSetId = notes.getChange().currentPatchSetId();
@@ -108,8 +114,9 @@ public class Revert
Change change = rsrc.getChange(); Change change = rsrc.getChange();
boolean projectStatePermitsWrite = false; boolean projectStatePermitsWrite = false;
try { try {
projectStatePermitsWrite = projectCache.checkedGet(rsrc.getProject()).statePermitsWrite(); projectStatePermitsWrite =
} catch (IOException e) { projectCache.get(rsrc.getProject()).map(ProjectState::statePermitsWrite).orElse(false);
} catch (StorageException e) {
logger.atSevere().withCause(e).log( logger.atSevere().withCause(e).log(
"Failed to check if project state permits write: %s", rsrc.getProject()); "Failed to check if project state permits write: %s", rsrc.getProject());
} }

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.restapi.change;
import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.gerrit.extensions.conditions.BooleanCondition.and; import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
import static com.google.gerrit.server.permissions.RefPermission.CREATE_CHANGE; import static com.google.gerrit.server.permissions.RefPermission.CREATE_CHANGE;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ArrayListMultimap;
@@ -62,6 +63,7 @@ import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ContributorAgreementsChecker; import com.google.gerrit.server.project.ContributorAgreementsChecker;
import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery; import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.restapi.change.CherryPickChange.Result; import com.google.gerrit.server.restapi.change.CherryPickChange.Result;
@@ -213,7 +215,10 @@ public class RevertSubmission
contributorAgreements.check(change.getProject(), changeResource.getUser()); contributorAgreements.check(change.getProject(), changeResource.getUser());
permissionBackend.currentUser().ref(change.getDest()).check(CREATE_CHANGE); permissionBackend.currentUser().ref(change.getDest()).check(CREATE_CHANGE);
permissionBackend.currentUser().change(changeData).check(ChangePermission.READ); permissionBackend.currentUser().change(changeData).check(ChangePermission.READ);
projectCache.checkedGet(change.getProject()).checkStatePermitsWrite(); projectCache
.get(change.getProject())
.orElseThrow(illegalState(change.getProject()))
.checkStatePermitsWrite();
requireNonNull( requireNonNull(
psUtil.get(changeData.notes(), change.currentPatchSetId()), psUtil.get(changeData.notes(), change.currentPatchSetId()),
@@ -533,8 +538,9 @@ public class RevertSubmission
Change change = rsrc.getChange(); Change change = rsrc.getChange();
boolean projectStatePermitsWrite = false; boolean projectStatePermitsWrite = false;
try { try {
projectStatePermitsWrite = projectCache.checkedGet(rsrc.getProject()).statePermitsWrite(); projectStatePermitsWrite =
} catch (IOException e) { projectCache.get(rsrc.getProject()).map(ProjectState::statePermitsWrite).orElse(false);
} catch (StorageException e) {
logger.atSevere().withCause(e).log( logger.atSevere().withCause(e).log(
"Failed to check if project state permits write: %s", rsrc.getProject()); "Failed to check if project state permits write: %s", rsrc.getProject());
} }

View File

@@ -34,6 +34,7 @@ import com.google.gerrit.server.permissions.ChangePermission;
import com.google.gerrit.server.permissions.PermissionBackend; import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException; import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.io.IOException; import java.io.IOException;
@@ -111,7 +112,10 @@ public class Revisions implements ChildCollection<ChangeResource, RevisionResour
.user(change.getUser()) .user(change.getUser())
.change(change.getNotes()) .change(change.getNotes())
.check(ChangePermission.READ); .check(ChangePermission.READ);
return projectCache.checkedGet(change.getProject()).statePermitsRead(); return projectCache
.get(change.getProject())
.map(ProjectState::statePermitsRead)
.orElse(false);
} catch (AuthException e) { } catch (AuthException e) {
return false; return false;
} }

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.git.ObjectIds.abbreviateName; import static com.google.gerrit.git.ObjectIds.abbreviateName;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.joining;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
@@ -54,6 +55,7 @@ import com.google.gerrit.server.permissions.ChangePermission;
import com.google.gerrit.server.permissions.PermissionBackend; import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException; import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery; import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.submit.ChangeSet; import com.google.gerrit.server.submit.ChangeSet;
@@ -181,7 +183,10 @@ public class Submit
rsrc.permissions().check(ChangePermission.SUBMIT); rsrc.permissions().check(ChangePermission.SUBMIT);
submitter = rsrc.getUser().asIdentifiedUser(); submitter = rsrc.getUser().asIdentifiedUser();
} }
projectCache.checkedGet(rsrc.getProject()).checkStatePermitsWrite(); projectCache
.get(rsrc.getProject())
.orElseThrow(illegalState(rsrc.getProject()))
.checkStatePermitsWrite();
return mergeChange(rsrc, submitter, input); return mergeChange(rsrc, submitter, input);
} }
@@ -291,10 +296,13 @@ public class Submit
} }
try { try {
if (!projectCache.checkedGet(resource.getProject()).statePermitsWrite()) { if (!projectCache
.get(resource.getProject())
.map(ProjectState::statePermitsWrite)
.orElse(false)) {
return null; // submit not visible return null; // submit not visible
} }
} catch (IOException e) { } catch (StorageException e) {
logger.atSevere().withCause(e).log("Error checking if change is submittable"); logger.atSevere().withCause(e).log("Error checking if change is submittable");
throw new StorageException("Could not determine problems for the change", e); throw new StorageException("Could not determine problems for the change", e);
} }

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.restapi.change; package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.gerrit.extensions.client.ReviewerState; import com.google.gerrit.extensions.client.ReviewerState;
import com.google.gerrit.extensions.common.AccountVisibility; import com.google.gerrit.extensions.common.AccountVisibility;
import com.google.gerrit.extensions.common.SuggestedReviewerInfo; import com.google.gerrit.extensions.common.SuggestedReviewerInfo;
@@ -96,7 +98,7 @@ public class SuggestChangeReviewers extends SuggestReviewers
reviewerState, reviewerState,
rsrc.getNotes(), rsrc.getNotes(),
this, this,
projectCache.checkedGet(rsrc.getProject()), projectCache.get(rsrc.getProject()).orElseThrow(illegalState(rsrc.getProject())),
getVisibility(rsrc), getVisibility(rsrc),
excludeGroups)); excludeGroups));
} }

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.restapi.project; package com.google.gerrit.server.restapi.project;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.gerrit.common.data.AccessSection; import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.entities.Change; import com.google.gerrit.entities.Change;
@@ -105,7 +107,10 @@ public class CreateAccessChange implements RestModifyView<ProjectResource, Proje
throw new AuthException("cannot create change for " + RefNames.REFS_CONFIG, denied); throw new AuthException("cannot create change for " + RefNames.REFS_CONFIG, denied);
} }
} }
projectCache.checkedGet(rsrc.getNameKey()).checkStatePermitsWrite(); projectCache
.get(rsrc.getNameKey())
.orElseThrow(illegalState(rsrc.getNameKey()))
.checkStatePermitsWrite();
MetaDataUpdate.User metaDataUpdateUser = metaDataUpdateFactory.get(); MetaDataUpdate.User metaDataUpdateUser = metaDataUpdateFactory.get();
List<AccessSection> removals = setAccess.getAccessSections(input.remove); List<AccessSection> removals = setAccess.getAccessSections(input.remove);

View File

@@ -20,6 +20,7 @@ import static com.google.gerrit.server.permissions.ProjectPermission.CREATE_TAG_
import static com.google.gerrit.server.permissions.RefPermission.CREATE_CHANGE; import static com.google.gerrit.server.permissions.RefPermission.CREATE_CHANGE;
import static com.google.gerrit.server.permissions.RefPermission.READ; import static com.google.gerrit.server.permissions.RefPermission.READ;
import static com.google.gerrit.server.permissions.RefPermission.WRITE_CONFIG; import static com.google.gerrit.server.permissions.RefPermission.WRITE_CONFIG;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toMap;
import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableBiMap;
@@ -118,10 +119,8 @@ public class GetAccess implements RestReadView<ProjectResource> {
} }
public ProjectAccessInfo apply(Project.NameKey nameKey) throws Exception { public ProjectAccessInfo apply(Project.NameKey nameKey) throws Exception {
ProjectState state = projectCache.checkedGet(nameKey); ProjectState state =
if (state == null) { projectCache.get(nameKey).orElseThrow(() -> new ResourceNotFoundException(nameKey.get()));
throw new ResourceNotFoundException(nameKey.get());
}
return apply(new ProjectResource(state, user.get())).value(); return apply(new ProjectResource(state, user.get())).value();
} }
@@ -135,7 +134,8 @@ public class GetAccess implements RestReadView<ProjectResource> {
Project.NameKey projectName = rsrc.getNameKey(); Project.NameKey projectName = rsrc.getNameKey();
ProjectAccessInfo info = new ProjectAccessInfo(); ProjectAccessInfo info = new ProjectAccessInfo();
ProjectState projectState = projectCache.checkedGet(projectName); ProjectState projectState =
projectCache.get(projectName).orElseThrow(illegalState(projectName));
PermissionBackend.ForProject perm = permissionBackend.currentUser().project(projectName); PermissionBackend.ForProject perm = permissionBackend.currentUser().project(projectName);
ProjectConfig config; ProjectConfig config;
@@ -154,12 +154,12 @@ public class GetAccess implements RestReadView<ProjectResource> {
md.setMessage("Update group names\n"); md.setMessage("Update group names\n");
config.commit(md); config.commit(md);
projectCache.evict(config.getProject()); projectCache.evict(config.getProject());
projectState = projectCache.checkedGet(projectName); projectState = projectCache.get(projectName).orElseThrow(illegalState(projectName));
perm = permissionBackend.currentUser().project(projectName); perm = permissionBackend.currentUser().project(projectName);
} else if (config.getRevision() != null } else if (config.getRevision() != null
&& !config.getRevision().equals(projectState.getConfig().getRevision())) { && !config.getRevision().equals(projectState.getConfig().getRevision())) {
projectCache.evict(config.getProject()); projectCache.evict(config.getProject());
projectState = projectCache.checkedGet(projectName); projectState = projectCache.get(projectName).orElseThrow(illegalState(projectName));
perm = permissionBackend.currentUser().project(projectName); perm = permissionBackend.currentUser().project(projectName);
} }
} catch (ConfigInvalidException e) { } catch (ConfigInvalidException e) {

View File

@@ -43,6 +43,7 @@ import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.io.IOException; import java.io.IOException;
import java.util.Optional;
@Singleton @Singleton
public class ProjectsCollection public class ProjectsCollection
@@ -139,19 +140,19 @@ public class ProjectsCollection
id = ProjectUtil.sanitizeProjectName(id); id = ProjectUtil.sanitizeProjectName(id);
Project.NameKey nameKey = Project.nameKey(id); Project.NameKey nameKey = Project.nameKey(id);
ProjectState state = projectCache.checkedGet(nameKey); Optional<ProjectState> state = projectCache.get(nameKey);
if (state == null) { if (!state.isPresent()) {
return null; return null;
} }
logger.atFine().log("Project %s has state %s", nameKey, state.getProject().getState()); logger.atFine().log("Project %s has state %s", nameKey, state.get().getProject().getState());
if (checkAccess) { if (checkAccess) {
// Hidden projects(permitsRead = false) should only be accessible by the project owners. // Hidden projects(permitsRead = false) should only be accessible by the project owners.
// WRITE_CONFIG is checked here because it's only allowed to project owners (ACCESS may also // WRITE_CONFIG is checked here because it's only allowed to project owners (ACCESS may also
// be allowed for other users). Allowing project owners to access here will help them to view // be allowed for other users). Allowing project owners to access here will help them to view
// and update the config of hidden projects easily. // and update the config of hidden projects easily.
if (state.statePermitsRead()) { if (state.get().statePermitsRead()) {
try { try {
permissionBackend.currentUser().project(nameKey).check(ProjectPermission.ACCESS); permissionBackend.currentUser().project(nameKey).check(ProjectPermission.ACCESS);
} catch (AuthException e) { } catch (AuthException e) {
@@ -161,11 +162,11 @@ public class ProjectsCollection
try { try {
permissionBackend.currentUser().project(nameKey).check(ProjectPermission.WRITE_CONFIG); permissionBackend.currentUser().project(nameKey).check(ProjectPermission.WRITE_CONFIG);
} catch (AuthException e) { } catch (AuthException e) {
state.checkStatePermitsRead(); state.get().checkStatePermitsRead();
} }
} }
} }
return new ProjectResource(state, user.get()); return new ProjectResource(state.get(), user.get());
} }
@Override @Override

View File

@@ -179,12 +179,10 @@ public class LocalMergeSuperSetComputation implements MergeSuperSetComputation {
} }
private boolean isVisible(ChangeSet changeSet, ChangeData cd, CurrentUser user) private boolean isVisible(ChangeSet changeSet, ChangeData cd, CurrentUser user)
throws PermissionBackendException, IOException { throws PermissionBackendException {
ProjectState projectState = projectCache.checkedGet(cd.project()); boolean statePermitsRead =
boolean visible = projectCache.get(cd.project()).map(ProjectState::statePermitsRead).orElse(false);
changeSet.ids().contains(cd.getId()) boolean visible = statePermitsRead && changeSet.ids().contains(cd.getId());
&& (projectState != null)
&& projectState.statePermitsRead();
if (!visible) { if (!visible) {
return false; return false;
} }

View File

@@ -110,9 +110,7 @@ public class MergeSuperSet {
ChangeData cd = changeDataFactory.create(change.getProject(), change.getId()); ChangeData cd = changeDataFactory.create(change.getProject(), change.getId());
boolean visible = false; boolean visible = false;
if (cd != null) { if (cd != null) {
ProjectState projectState = projectCache.checkedGet(cd.project()); if (projectCache.get(cd.project()).map(ProjectState::statePermitsRead).orElse(false)) {
if (projectState.statePermitsRead()) {
try { try {
permissionBackend.user(user).change(cd).check(ChangePermission.READ); permissionBackend.user(user).change(cd).check(ChangePermission.READ);
visible = true; visible = true;
@@ -210,10 +208,8 @@ public class MergeSuperSet {
return queryProvider.get().byTopicOpen(topic); return queryProvider.get().byTopicOpen(topic);
} }
private boolean canRead(CurrentUser user, ChangeData cd) private boolean canRead(CurrentUser user, ChangeData cd) throws PermissionBackendException {
throws PermissionBackendException, IOException { if (!projectCache.get(cd.project()).map(ProjectState::statePermitsRead).orElse(false)) {
ProjectState projectState = projectCache.checkedGet(cd.project());
if (projectState == null || !projectState.statePermitsRead()) {
return false; return false;
} }

View File

@@ -325,8 +325,8 @@ public class ReviewCommand extends SshCommand {
ProjectState allProjectsState; ProjectState allProjectsState;
try { try {
allProjectsState = projectCache.checkedGet(allProjects); allProjectsState = projectCache.getAllProjects();
} catch (IOException e) { } catch (Exception e) {
throw die("missing " + allProjects.get(), e); throw die("missing " + allProjects.get(), e);
} }

View File

@@ -36,6 +36,7 @@ import static com.google.gerrit.server.StarredChangesUtil.IGNORE_LABEL;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_GPGKEY; import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_GPGKEY;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS; import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS; import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static com.google.gerrit.testing.GerritJUnit.assertThrows; import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static com.google.gerrit.truth.ConfigSubject.assertThat; import static com.google.gerrit.truth.ConfigSubject.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
@@ -260,7 +261,7 @@ public class AccountIT extends AbstractDaemonTest {
int min, int min,
int max) int max)
throws IOException { throws IOException {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig(); ProjectConfig cfg = projectCache.get(project).orElseThrow(illegalState(project)).getConfig();
AccessSection accessSection = cfg.getAccessSection(ref); AccessSection accessSection = cfg.getAccessSection(ref);
assertThat(accessSection).isNotNull(); assertThat(accessSection).isNotNull();

View File

@@ -397,7 +397,10 @@ public class RevertIT extends AbstractDaemonTest {
.revision(result.getCommit().name()) .revision(result.getCommit().name())
.review(ReviewInput.approve()); .review(ReviewInput.approve());
gApi.changes().id(result.getChangeId()).revision(result.getCommit().name()).submit(); gApi.changes().id(result.getChangeId()).revision(result.getCommit().name()).submit();
projectCache.checkedGet(project).getProject().setState(ProjectState.READ_ONLY); try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig().getProject().setState(ProjectState.READ_ONLY);
u.save();
}
String expected = "project state " + ProjectState.READ_ONLY + " does not permit write"; String expected = "project state " + ProjectState.READ_ONLY + " does not permit write";
ResourceConflictException thrown = ResourceConflictException thrown =
@@ -461,7 +464,10 @@ public class RevertIT extends AbstractDaemonTest {
gApi.changes().id(change1).current().submit(); gApi.changes().id(change1).current().submit();
// revoke write permissions for the first repository. // revoke write permissions for the first repository.
projectCache.checkedGet(project).getProject().setState(ProjectState.READ_ONLY); try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig().getProject().setState(ProjectState.READ_ONLY);
u.save();
}
String expected = "project state " + ProjectState.READ_ONLY + " does not permit write"; String expected = "project state " + ProjectState.READ_ONLY + " does not permit write";

View File

@@ -27,6 +27,7 @@ import static com.google.gerrit.extensions.client.ListChangesOption.LABELS;
import static com.google.gerrit.extensions.client.ListChangesOption.SUBMITTABLE; import static com.google.gerrit.extensions.client.ListChangesOption.SUBMITTABLE;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS; import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS; import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static com.google.gerrit.server.project.testing.TestLabels.label; import static com.google.gerrit.server.project.testing.TestLabels.label;
import static com.google.gerrit.server.project.testing.TestLabels.value; import static com.google.gerrit.server.project.testing.TestLabels.value;
import static com.google.gerrit.testing.GerritJUnit.assertThrows; import static com.google.gerrit.testing.GerritJUnit.assertThrows;
@@ -332,7 +333,7 @@ public class CustomLabelIT extends AbstractDaemonTest {
public void customLabel_withBranch() throws Exception { public void customLabel_withBranch() throws Exception {
label.setRefPatterns(Arrays.asList("master")); label.setRefPatterns(Arrays.asList("master"));
saveLabelConfig(); saveLabelConfig();
ProjectConfig cfg = projectCache.checkedGet(project).getConfig(); ProjectConfig cfg = projectCache.get(project).orElseThrow(illegalState(project)).getConfig();
assertThat(cfg.getLabelSections().get(label.getName()).getRefPatterns()).contains("master"); assertThat(cfg.getLabelSections().get(label.getName()).getRefPatterns()).contains("master");
} }

View File

@@ -30,6 +30,7 @@ import static com.google.gerrit.common.data.GlobalCapability.QUERY_LIMIT;
import static com.google.gerrit.entities.RefNames.REFS_CONFIG; import static com.google.gerrit.entities.RefNames.REFS_CONFIG;
import static com.google.gerrit.server.group.SystemGroupBackend.PROJECT_OWNERS; import static com.google.gerrit.server.group.SystemGroupBackend.PROJECT_OWNERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS; import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static com.google.gerrit.testing.GerritJUnit.assertThrows; import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static com.google.gerrit.truth.ConfigSubject.assertThat; import static com.google.gerrit.truth.ConfigSubject.assertThat;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
@@ -100,14 +101,15 @@ public class ProjectOperationsImplTest extends AbstractDaemonTest {
public void mutatingResultOfGetProjectConfigDoesNotMutateGlobalCachedValue() throws Exception { public void mutatingResultOfGetProjectConfigDoesNotMutateGlobalCachedValue() throws Exception {
Project.NameKey key = projectOperations.newProject().create(); Project.NameKey key = projectOperations.newProject().create();
ProjectConfig projectConfig = projectOperations.project(key).getProjectConfig(); ProjectConfig projectConfig = projectOperations.project(key).getProjectConfig();
ProjectState cachedProjectState1 = projectCache.checkedGet(key); ProjectState cachedProjectState1 = projectCache.get(key).orElseThrow(illegalState(project));
ProjectConfig cachedProjectConfig1 = cachedProjectState1.getConfig(); ProjectConfig cachedProjectConfig1 = cachedProjectState1.getConfig();
assertThat(cachedProjectConfig1).isNotSameInstanceAs(projectConfig); assertThat(cachedProjectConfig1).isNotSameInstanceAs(projectConfig);
assertThat(cachedProjectConfig1.getProject().getDescription()).isEmpty(); assertThat(cachedProjectConfig1.getProject().getDescription()).isEmpty();
assertThat(projectConfig.getProject().getDescription()).isEmpty(); assertThat(projectConfig.getProject().getDescription()).isEmpty();
projectConfig.getProject().setDescription("my fancy project"); projectConfig.getProject().setDescription("my fancy project");
ProjectConfig cachedProjectConfig2 = projectCache.checkedGet(key).getConfig(); ProjectConfig cachedProjectConfig2 =
projectCache.get(key).orElseThrow(illegalState(project)).getConfig();
assertThat(cachedProjectConfig2).isNotSameInstanceAs(projectConfig); assertThat(cachedProjectConfig2).isNotSameInstanceAs(projectConfig);
assertThat(cachedProjectConfig2.getProject().getDescription()).isEmpty(); assertThat(cachedProjectConfig2.getProject().getDescription()).isEmpty();
} }

View File

@@ -215,7 +215,7 @@ public class CommitsCollectionTest {
// Anonymous user group has ALLOW READ permission in refs/*. // Anonymous user group has ALLOW READ permission in refs/*.
// This method is idempotent, so is safe to call on every test setup. // This method is idempotent, so is safe to call on every test setup.
TestProjectUpdate.Builder u = projectOperations.allProjectsForUpdate(); TestProjectUpdate.Builder u = projectOperations.allProjectsForUpdate();
projectCache.checkedGet(allProjects).getConfig().getAccessSectionNames().stream() projectCache.getAllProjects().getConfig().getAccessSectionNames().stream()
.filter(sec -> sec.startsWith(R_REFS)) .filter(sec -> sec.startsWith(R_REFS))
.forEach(sec -> u.remove(permissionKey(Permission.READ).ref(sec))); .forEach(sec -> u.remove(permissionKey(Permission.READ).ref(sec)));
getAdmins().forEach(admin -> u.add(allow(Permission.READ).ref("refs/*").group(admin))); getAdmins().forEach(admin -> u.add(allow(Permission.READ).ref("refs/*").group(admin)));