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,
|
public static void defaultDashboard(Project.NameKey project,
|
||||||
AsyncCallback<DashboardInfo> callback) {
|
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,
|
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 com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
import org.eclipse.jgit.lib.Config;
|
import org.eclipse.jgit.lib.Config;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
|
||||||
|
|
||||||
public class DashboardResource implements RestResource {
|
public class DashboardResource implements RestResource {
|
||||||
public static final TypeLiteral<RestView<DashboardResource>> DASHBOARD_KIND =
|
public static final TypeLiteral<RestView<DashboardResource>> DASHBOARD_KIND =
|
||||||
new TypeLiteral<RestView<DashboardResource>>() {};
|
new TypeLiteral<RestView<DashboardResource>>() {};
|
||||||
|
|
||||||
|
static DashboardResource projectDefault(ProjectControl ctl) {
|
||||||
|
return new DashboardResource(ctl, null, null, null, true);
|
||||||
|
}
|
||||||
|
|
||||||
private final ProjectControl control;
|
private final ProjectControl control;
|
||||||
private final String refName;
|
private final String refName;
|
||||||
private final String pathName;
|
private final String pathName;
|
||||||
private final ObjectId objId;
|
|
||||||
private final Config config;
|
private final Config config;
|
||||||
private final boolean projectDefault;
|
private final boolean projectDefault;
|
||||||
|
|
||||||
DashboardResource(ProjectControl control,
|
DashboardResource(ProjectControl control,
|
||||||
String refName,
|
String refName,
|
||||||
String pathName,
|
String pathName,
|
||||||
ObjectId objId,
|
|
||||||
Config config,
|
Config config,
|
||||||
boolean projectDefault) {
|
boolean projectDefault) {
|
||||||
this.control = control;
|
this.control = control;
|
||||||
this.refName = refName;
|
this.refName = refName;
|
||||||
this.pathName = pathName;
|
this.pathName = pathName;
|
||||||
this.objId = objId;
|
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.projectDefault = projectDefault;
|
this.projectDefault = projectDefault;
|
||||||
}
|
}
|
||||||
@@ -58,10 +58,6 @@ public class DashboardResource implements RestResource {
|
|||||||
return pathName;
|
return pathName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectId getObjectId() {
|
|
||||||
return objId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Config getConfig() {
|
public Config getConfig() {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import com.google.inject.Inject;
|
|||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
import org.eclipse.jgit.errors.AmbiguousObjectException;
|
import org.eclipse.jgit.errors.AmbiguousObjectException;
|
||||||
|
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||||
import org.eclipse.jgit.lib.BlobBasedConfig;
|
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.ObjectId;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
@@ -84,12 +86,10 @@ class DashboardsCollection implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DashboardResource parse(ProjectResource parent, String id)
|
public DashboardResource parse(ProjectResource parent, String id)
|
||||||
throws ResourceNotFoundException, Exception {
|
throws ResourceNotFoundException, IOException, ConfigInvalidException {
|
||||||
ProjectControl ctl = parent.getControl();
|
ProjectControl ctl = parent.getControl();
|
||||||
boolean def = false;
|
|
||||||
if ("default".equals(id)) {
|
if ("default".equals(id)) {
|
||||||
id = defaultOf(ctl.getProject());
|
return DashboardResource.projectDefault(ctl);
|
||||||
def = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> parts = Lists.newArrayList(
|
List<String> parts = Lists.newArrayList(
|
||||||
@@ -117,7 +117,7 @@ class DashboardsCollection implements
|
|||||||
try {
|
try {
|
||||||
ObjectId objId;
|
ObjectId objId;
|
||||||
try {
|
try {
|
||||||
objId = git.resolve(Joiner.on(':').join(ref, path));
|
objId = git.resolve(ref + ':' + path);
|
||||||
} catch (AmbiguousObjectException e) {
|
} catch (AmbiguousObjectException e) {
|
||||||
throw new ResourceNotFoundException(id);
|
throw new ResourceNotFoundException(id);
|
||||||
} catch (IncorrectObjectTypeException e) {
|
} catch (IncorrectObjectTypeException e) {
|
||||||
@@ -127,7 +127,7 @@ class DashboardsCollection implements
|
|||||||
throw new ResourceNotFoundException();
|
throw new ResourceNotFoundException();
|
||||||
}
|
}
|
||||||
BlobBasedConfig cfg = new BlobBasedConfig(null, git, objId);
|
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 {
|
} finally {
|
||||||
git.close();
|
git.close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,19 +16,78 @@ package com.google.gerrit.server.project;
|
|||||||
|
|
||||||
import static com.google.gerrit.server.git.GitRepositoryManager.REFS_DASHBOARDS;
|
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.extensions.restapi.RestReadView;
|
||||||
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
import com.google.gerrit.server.project.DashboardsCollection.DashboardInfo;
|
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> {
|
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
|
@Override
|
||||||
public DashboardInfo apply(DashboardResource resource)
|
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(
|
return DashboardsCollection.parse(
|
||||||
resource.getControl().getProject(),
|
resource.getControl().getProject(),
|
||||||
resource.getRefName().substring(REFS_DASHBOARDS.length()),
|
resource.getRefName().substring(REFS_DASHBOARDS.length()),
|
||||||
resource.getPathName(),
|
resource.getPathName(),
|
||||||
resource.getConfig());
|
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.ConfigInvalidException;
|
||||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||||
|
import org.kohsuke.args4j.Option;
|
||||||
|
|
||||||
class SetDefaultDashboard implements RestModifyView<DashboardResource, Input> {
|
class SetDefaultDashboard implements RestModifyView<DashboardResource, Input> {
|
||||||
private final ProjectCache cache;
|
private final ProjectCache cache;
|
||||||
@@ -39,6 +40,9 @@ class SetDefaultDashboard implements RestModifyView<DashboardResource, Input> {
|
|||||||
private final DashboardsCollection dashboards;
|
private final DashboardsCollection dashboards;
|
||||||
private final Provider<GetDashboard> get;
|
private final Provider<GetDashboard> get;
|
||||||
|
|
||||||
|
@Option(name = "--inherited", usage = "set dashboard inherited by children")
|
||||||
|
private boolean inherited;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SetDefaultDashboard(ProjectCache cache,
|
SetDefaultDashboard(ProjectCache cache,
|
||||||
MetaDataUpdate.Server updateFactory,
|
MetaDataUpdate.Server updateFactory,
|
||||||
@@ -84,7 +88,11 @@ class SetDefaultDashboard implements RestModifyView<DashboardResource, Input> {
|
|||||||
try {
|
try {
|
||||||
ProjectConfig config = ProjectConfig.read(md);
|
ProjectConfig config = ProjectConfig.read(md);
|
||||||
Project project = config.getProject();
|
Project project = config.getProject();
|
||||||
project.setLocalDefaultDashboard(input.id);
|
if (inherited) {
|
||||||
|
project.setDefaultDashboard(input.id);
|
||||||
|
} else {
|
||||||
|
project.setLocalDefaultDashboard(input.id);
|
||||||
|
}
|
||||||
|
|
||||||
String msg = Objects.firstNonNull(
|
String msg = Objects.firstNonNull(
|
||||||
Strings.emptyToNull(input.commitMessage),
|
Strings.emptyToNull(input.commitMessage),
|
||||||
@@ -120,6 +128,9 @@ class SetDefaultDashboard implements RestModifyView<DashboardResource, Input> {
|
|||||||
RestModifyView<ProjectResource, SetDashboard.Input> {
|
RestModifyView<ProjectResource, SetDashboard.Input> {
|
||||||
private final Provider<SetDefaultDashboard> setDefault;
|
private final Provider<SetDefaultDashboard> setDefault;
|
||||||
|
|
||||||
|
@Option(name = "--inherited", usage = "set dashboard inherited by children")
|
||||||
|
private boolean inherited;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CreateDefault(Provider<SetDefaultDashboard> setDefault) {
|
CreateDefault(Provider<SetDefaultDashboard> setDefault) {
|
||||||
this.setDefault = setDefault;
|
this.setDefault = setDefault;
|
||||||
@@ -134,9 +145,11 @@ class SetDefaultDashboard implements RestModifyView<DashboardResource, Input> {
|
|||||||
public Object apply(ProjectResource resource, Input input)
|
public Object apply(ProjectResource resource, Input input)
|
||||||
throws AuthException, BadRequestException, ResourceConflictException,
|
throws AuthException, BadRequestException, ResourceConflictException,
|
||||||
Exception {
|
Exception {
|
||||||
ProjectControl ctl = resource.getControl();
|
SetDefaultDashboard set = setDefault.get();
|
||||||
return setDefault.get().apply(
|
set.inherited = inherited;
|
||||||
new DashboardResource(ctl, null, null, null, null, true), input);
|
return set.apply(
|
||||||
|
DashboardResource.projectDefault(resource.getControl()),
|
||||||
|
input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user