Fix reading /default for inherited dashboards
When loading the default dashboard for a project the default REST approach is to load only the default defined locally in this project. If no such default is defined, the caller may supply an optional ?inherited query parameter to search up the inheritance tree. Change-Id: I5ed3d63f734fa9734c7ccd05c940fbdcf9dcab1d
This commit is contained in:
@@ -31,7 +31,9 @@ public class DashboardList extends NativeList<DashboardInfo> {
|
||||
|
||||
public static void defaultDashboard(Project.NameKey project,
|
||||
AsyncCallback<DashboardInfo> callback) {
|
||||
new RestApi(base(project) + "default").get(callback);
|
||||
new RestApi(base(project) + "default")
|
||||
.addParameterTrue("inherited")
|
||||
.get(callback);
|
||||
}
|
||||
|
||||
public static void get(Project.NameKey project, String dashboardId,
|
||||
|
||||
@@ -19,29 +19,29 @@ import com.google.gerrit.extensions.restapi.RestView;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
public class DashboardResource implements RestResource {
|
||||
public static final TypeLiteral<RestView<DashboardResource>> DASHBOARD_KIND =
|
||||
new TypeLiteral<RestView<DashboardResource>>() {};
|
||||
|
||||
static DashboardResource projectDefault(ProjectControl ctl) {
|
||||
return new DashboardResource(ctl, null, null, null, true);
|
||||
}
|
||||
|
||||
private final ProjectControl control;
|
||||
private final String refName;
|
||||
private final String pathName;
|
||||
private final ObjectId objId;
|
||||
private final Config config;
|
||||
private final boolean projectDefault;
|
||||
|
||||
DashboardResource(ProjectControl control,
|
||||
String refName,
|
||||
String pathName,
|
||||
ObjectId objId,
|
||||
Config config,
|
||||
boolean projectDefault) {
|
||||
this.control = control;
|
||||
this.refName = refName;
|
||||
this.pathName = pathName;
|
||||
this.objId = objId;
|
||||
this.config = config;
|
||||
this.projectDefault = projectDefault;
|
||||
}
|
||||
@@ -58,10 +58,6 @@ public class DashboardResource implements RestResource {
|
||||
return pathName;
|
||||
}
|
||||
|
||||
public ObjectId getObjectId() {
|
||||
return objId;
|
||||
}
|
||||
|
||||
public Config getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.errors.AmbiguousObjectException;
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.eclipse.jgit.lib.BlobBasedConfig;
|
||||
@@ -43,6 +44,7 @@ import org.eclipse.jgit.lib.Config;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
@@ -84,12 +86,10 @@ class DashboardsCollection implements
|
||||
|
||||
@Override
|
||||
public DashboardResource parse(ProjectResource parent, String id)
|
||||
throws ResourceNotFoundException, Exception {
|
||||
throws ResourceNotFoundException, IOException, ConfigInvalidException {
|
||||
ProjectControl ctl = parent.getControl();
|
||||
boolean def = false;
|
||||
if ("default".equals(id)) {
|
||||
id = defaultOf(ctl.getProject());
|
||||
def = true;
|
||||
return DashboardResource.projectDefault(ctl);
|
||||
}
|
||||
|
||||
List<String> parts = Lists.newArrayList(
|
||||
@@ -117,7 +117,7 @@ class DashboardsCollection implements
|
||||
try {
|
||||
ObjectId objId;
|
||||
try {
|
||||
objId = git.resolve(Joiner.on(':').join(ref, path));
|
||||
objId = git.resolve(ref + ':' + path);
|
||||
} catch (AmbiguousObjectException e) {
|
||||
throw new ResourceNotFoundException(id);
|
||||
} catch (IncorrectObjectTypeException e) {
|
||||
@@ -127,7 +127,7 @@ class DashboardsCollection implements
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
BlobBasedConfig cfg = new BlobBasedConfig(null, git, objId);
|
||||
return new DashboardResource(ctl, ref, path, objId, cfg, def);
|
||||
return new DashboardResource(ctl, ref, path, cfg, false);
|
||||
} finally {
|
||||
git.close();
|
||||
}
|
||||
|
||||
@@ -16,19 +16,78 @@ package com.google.gerrit.server.project;
|
||||
|
||||
import static com.google.gerrit.server.git.GitRepositoryManager.REFS_DASHBOARDS;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.project.DashboardsCollection.DashboardInfo;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.kohsuke.args4j.Option;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
class GetDashboard implements RestReadView<DashboardResource> {
|
||||
private final DashboardsCollection dashboards;
|
||||
|
||||
@Option(name = "--inherited", usage = "include inherited dashboards")
|
||||
private boolean inherited;
|
||||
|
||||
@Inject
|
||||
GetDashboard(DashboardsCollection dashboards) {
|
||||
this.dashboards = dashboards;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DashboardInfo apply(DashboardResource resource)
|
||||
throws UnsupportedEncodingException {
|
||||
throws ResourceNotFoundException, IOException, ConfigInvalidException {
|
||||
if (inherited && !resource.isProjectDefault()) {
|
||||
// inherited flag can only be used with default.
|
||||
throw new ResourceNotFoundException("inherited");
|
||||
}
|
||||
|
||||
if (resource.isProjectDefault()) {
|
||||
// The default is not resolved to a definition yet.
|
||||
resource = defaultOf(resource.getControl());
|
||||
}
|
||||
|
||||
return DashboardsCollection.parse(
|
||||
resource.getControl().getProject(),
|
||||
resource.getRefName().substring(REFS_DASHBOARDS.length()),
|
||||
resource.getPathName(),
|
||||
resource.getConfig());
|
||||
}
|
||||
|
||||
private DashboardResource defaultOf(ProjectControl ctl)
|
||||
throws ResourceNotFoundException, IOException, ConfigInvalidException {
|
||||
String id = ctl.getProject().getLocalDefaultDashboard();
|
||||
if (Strings.isNullOrEmpty(id)) {
|
||||
id = ctl.getProject().getDefaultDashboard();
|
||||
}
|
||||
if ("default".equals(id)) {
|
||||
throw new ResourceNotFoundException();
|
||||
} else if (!Strings.isNullOrEmpty(id)) {
|
||||
return dashboards.parse(new ProjectResource(ctl), id);
|
||||
} else if (!inherited) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
Set<Project.NameKey> seen = Sets.newHashSet();
|
||||
seen.add(ctl.getProject().getNameKey());
|
||||
ProjectState ps = ctl.getProjectState().getParentState();
|
||||
while (ps != null && seen.add(ps.getProject().getNameKey())) {
|
||||
id = ps.getProject().getDefaultDashboard();
|
||||
if ("default".equals(id)) {
|
||||
throw new ResourceNotFoundException();
|
||||
} else if (!Strings.isNullOrEmpty(id)) {
|
||||
ctl = ps.controlFor(ctl.getCurrentUser());
|
||||
return dashboards.parse(new ProjectResource(ctl), id);
|
||||
}
|
||||
ps = ps.getParentState();
|
||||
}
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.kohsuke.args4j.Option;
|
||||
|
||||
class SetDefaultDashboard implements RestModifyView<DashboardResource, Input> {
|
||||
private final ProjectCache cache;
|
||||
@@ -39,6 +40,9 @@ class SetDefaultDashboard implements RestModifyView<DashboardResource, Input> {
|
||||
private final DashboardsCollection dashboards;
|
||||
private final Provider<GetDashboard> get;
|
||||
|
||||
@Option(name = "--inherited", usage = "set dashboard inherited by children")
|
||||
private boolean inherited;
|
||||
|
||||
@Inject
|
||||
SetDefaultDashboard(ProjectCache cache,
|
||||
MetaDataUpdate.Server updateFactory,
|
||||
@@ -84,7 +88,11 @@ class SetDefaultDashboard implements RestModifyView<DashboardResource, Input> {
|
||||
try {
|
||||
ProjectConfig config = ProjectConfig.read(md);
|
||||
Project project = config.getProject();
|
||||
if (inherited) {
|
||||
project.setDefaultDashboard(input.id);
|
||||
} else {
|
||||
project.setLocalDefaultDashboard(input.id);
|
||||
}
|
||||
|
||||
String msg = Objects.firstNonNull(
|
||||
Strings.emptyToNull(input.commitMessage),
|
||||
@@ -120,6 +128,9 @@ class SetDefaultDashboard implements RestModifyView<DashboardResource, Input> {
|
||||
RestModifyView<ProjectResource, SetDashboard.Input> {
|
||||
private final Provider<SetDefaultDashboard> setDefault;
|
||||
|
||||
@Option(name = "--inherited", usage = "set dashboard inherited by children")
|
||||
private boolean inherited;
|
||||
|
||||
@Inject
|
||||
CreateDefault(Provider<SetDefaultDashboard> setDefault) {
|
||||
this.setDefault = setDefault;
|
||||
@@ -134,9 +145,11 @@ class SetDefaultDashboard implements RestModifyView<DashboardResource, Input> {
|
||||
public Object apply(ProjectResource resource, Input input)
|
||||
throws AuthException, BadRequestException, ResourceConflictException,
|
||||
Exception {
|
||||
ProjectControl ctl = resource.getControl();
|
||||
return setDefault.get().apply(
|
||||
new DashboardResource(ctl, null, null, null, null, true), input);
|
||||
SetDefaultDashboard set = setDefault.get();
|
||||
set.inherited = inherited;
|
||||
return set.apply(
|
||||
DashboardResource.projectDefault(resource.getControl()),
|
||||
input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user