diff --git a/Documentation/rest-api-projects.txt b/Documentation/rest-api-projects.txt index f169dcd6a1..542c3c7844 100644 --- a/Documentation/rest-api-projects.txt +++ b/Documentation/rest-api-projects.txt @@ -535,6 +535,38 @@ returned that describe the child projects. ] ---- +[[get-child-project]] +Get Child Project +~~~~~~~~~~~~~~~~~ +[verse] +'GET /projects/link:#project-name[\{project-name\}]/children/link:#project-name[\{project-name\}]' + +Retrieves a child project. + +.Request +---- + GET /projects/Public-Plugins/children/plugins%2Freplication HTTP/1.0 +---- + +As response a link:#project-info[ProjectInfo] entity is returned that +describes the child project. + +.Response +---- + HTTP/1.1 200 OK + Content-Disposition: attachment + Content-Type: application/json;charset=UTF-8 + + )]}' + { + "kind": "gerritcodereview#project", + "id": "plugins%2Freplication", + "name": "plugins/replication", + "parent": "Public-Plugins", + "description": "Copies to other servers using the Git protocol" + } +---- + [[dashboard-endpoints]] Dashboard Endpoints ------------------- diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/GetChildProjectIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/GetChildProjectIT.java new file mode 100644 index 0000000000..6adb43e1da --- /dev/null +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/GetChildProjectIT.java @@ -0,0 +1,109 @@ +// Copyright (C) 2013 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.acceptance.rest.project; + +import static com.google.gerrit.acceptance.git.GitUtil.createProject; +import static com.google.gerrit.acceptance.rest.project.ProjectAssert.assertProjectInfo; +import static org.junit.Assert.assertEquals; + +import com.google.gerrit.acceptance.AbstractDaemonTest; +import com.google.gerrit.acceptance.AccountCreator; +import com.google.gerrit.acceptance.RestResponse; +import com.google.gerrit.acceptance.RestSession; +import com.google.gerrit.acceptance.SshSession; +import com.google.gerrit.acceptance.TestAccount; +import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.server.config.AllProjectsName; +import com.google.gerrit.server.project.ProjectCache; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.google.inject.Inject; + +import com.jcraft.jsch.JSchException; + +import org.apache.http.HttpStatus; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +public class GetChildProjectIT extends AbstractDaemonTest { + + @Inject + private AccountCreator accounts; + + @Inject + private AllProjectsName allProjects; + + @Inject + private ProjectCache projectCache; + + private TestAccount admin; + private RestSession session; + + @Before + public void setUp() throws Exception { + admin = + accounts.create("admin", "admin@example.com", "Administrator", + "Administrators"); + session = new RestSession(admin); + } + + @Test + public void getNonExistingChildProject_NotFound() throws IOException { + assertEquals(HttpStatus.SC_NOT_FOUND, + GET("/projects/" + allProjects.get() + "/children/non-existing").getStatusCode()); + } + + @Test + public void getNonChildProject_NotFound() throws IOException, JSchException { + SshSession sshSession = new SshSession(admin); + Project.NameKey p1 = new Project.NameKey("p1"); + createProject(sshSession, p1.get()); + Project.NameKey p2 = new Project.NameKey("p2"); + createProject(sshSession, p2.get()); + assertEquals(HttpStatus.SC_NOT_FOUND, + GET("/projects/" + p1.get() + "/children/" + p2.get()).getStatusCode()); + } + + @Test + public void getChildProject() throws IOException, JSchException { + SshSession sshSession = new SshSession(admin); + Project.NameKey child = new Project.NameKey("p1"); + createProject(sshSession, child.get()); + RestResponse r = GET("/projects/" + allProjects.get() + "/children/" + child.get()); + assertEquals(HttpStatus.SC_OK, r.getStatusCode()); + ProjectInfo childInfo = + (new Gson()).fromJson(r.getReader(), + new TypeToken() {}.getType()); + assertProjectInfo(projectCache.get(child).getProject(), childInfo); + } + + @Test + public void getGrandChildProject_NotFound() throws IOException, JSchException { + SshSession sshSession = new SshSession(admin); + Project.NameKey child = new Project.NameKey("p1"); + createProject(sshSession, child.get()); + Project.NameKey grandChild = new Project.NameKey("p1.1"); + createProject(sshSession, grandChild.get(), child); + assertEquals(HttpStatus.SC_NOT_FOUND, + GET("/projects/" + allProjects.get() + "/children/" + grandChild.get()) + .getStatusCode()); + } + + private RestResponse GET(String endpoint) throws IOException { + return session.get(endpoint); + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChildProjectsCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChildProjectsCollection.java index 3d1c143af7..29fd43b2e2 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChildProjectsCollection.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChildProjectsCollection.java @@ -14,24 +14,29 @@ package com.google.gerrit.server.project; +import com.google.common.collect.Iterables; import com.google.gerrit.extensions.registration.DynamicMap; import com.google.gerrit.extensions.restapi.AuthException; import com.google.gerrit.extensions.restapi.ChildCollection; import com.google.gerrit.extensions.restapi.IdString; import com.google.gerrit.extensions.restapi.ResourceNotFoundException; import com.google.gerrit.extensions.restapi.RestView; +import com.google.gerrit.extensions.restapi.TopLevelResource; import com.google.inject.Inject; import com.google.inject.Provider; public class ChildProjectsCollection implements ChildCollection { private final Provider list; + private final Provider projectsCollection; private final DynamicMap> views; @Inject ChildProjectsCollection(Provider list, + Provider projectsCollection, DynamicMap> views) { this.list = list; + this.projectsCollection = projectsCollection; this.views = views; } @@ -44,6 +49,13 @@ public class ChildProjectsCollection implements @Override public ChildProjectResource parse(ProjectResource parent, IdString id) throws ResourceNotFoundException { + ProjectResource p = + projectsCollection.get().parse(TopLevelResource.INSTANCE, id); + ProjectState pp = + Iterables.getFirst(p.getControl().getProjectState().parents(), null); + if (pp != null && parent.getNameKey().equals(pp.getProject().getNameKey())) { + return new ChildProjectResource(parent, p.getControl()); + } throw new ResourceNotFoundException(id); } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/GetChildProject.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/GetChildProject.java new file mode 100644 index 0000000000..9a1529f2c8 --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/GetChildProject.java @@ -0,0 +1,33 @@ +// Copyright (C) 2013 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.project; + +import com.google.gerrit.extensions.restapi.RestReadView; +import com.google.gerrit.server.project.ProjectJson.ProjectInfo; +import com.google.inject.Inject; + +public class GetChildProject implements RestReadView { + private final ProjectJson json; + + @Inject + GetChildProject(ProjectJson json) { + this.json = json; + } + + @Override + public ProjectInfo apply(ChildProjectResource rsrc) { + return json.format(rsrc.getChild().getProject()); + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/Module.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/Module.java index a6e8a3698e..d9792453f7 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/Module.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/Module.java @@ -43,6 +43,7 @@ public class Module extends RestApiModule { put(PROJECT_KIND, "parent").to(SetParent.class); child(PROJECT_KIND, "children").to(ChildProjectsCollection.class); + get(CHILD_PROJECT_KIND).to(GetChildProject.class); get(PROJECT_KIND, "HEAD").to(GetHead.class); put(PROJECT_KIND, "HEAD").to(SetHead.class);