diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt index 0635a7fdf7..a701c52546 100644 --- a/Documentation/rest-api-changes.txt +++ b/Documentation/rest-api-changes.txt @@ -1269,6 +1269,32 @@ When change edit doesn't exist for this change yet it is created. HTTP/1.1 204 No Content ---- +[[get-edit-file]] +=== Retrieve file content from Change Edit +-- +'GET /changes/link:#change-id[\{change-id\}]/edit/path%2fto%2ffile +-- + +Retrieves content of a file from a change edit. + +.Request +---- + GET /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/edit/foo HTTP/1.0 +---- + +The content of the file is returned as text encoded inside base64. When +specified file was deleted in the change edit "`204 No Content`" is returned. + +.Response +---- + HTTP/1.1 200 OK + Content-Disposition: attachment + Content-Type: text/plain;charset=ISO-8859-1 + X-FYI-Content-Encoding: base64 + + RnJvbSA3ZGFkY2MxNTNmZGVhMTdhYTg0ZmYzMmE2ZTI0NWRiYjY... +---- + [[reviewer-endpoints]] == Reviewer Endpoints diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/BUCK b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/BUCK index 610631f26b..be6fcdc2bb 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/BUCK +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/BUCK @@ -3,5 +3,8 @@ include_defs('//gerrit-acceptance-tests/tests.defs') acceptance_tests( srcs = ['ChangeEditIT.java'], labels = ['edit'], - deps = ['//lib/joda:joda-time'], + deps = [ + '//lib/commons:codec', + '//lib/joda:joda-time', + ], ) diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java index 80a7119249..ad80b7edf6 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java @@ -39,8 +39,8 @@ import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.IdentifiedUser; -import com.google.gerrit.server.change.ChangeEdits.Put; import com.google.gerrit.server.change.ChangeEdits.Post; +import com.google.gerrit.server.change.ChangeEdits.Put; import com.google.gerrit.server.change.FileContentUtil; import com.google.gerrit.server.edit.ChangeEdit; import com.google.gerrit.server.edit.ChangeEditModifier; @@ -50,6 +50,8 @@ import com.google.gwtorm.server.SchemaFactory; import com.google.inject.Inject; import com.google.inject.util.Providers; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.StringUtils; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.RefUpdate; @@ -428,6 +430,44 @@ public class ChangeEditIT extends AbstractDaemonTest { edit.get().getRevision().get(), FILE_NAME))); } + @Test + public void getFileContentRest() throws Exception { + Put.Input in = new Put.Input(); + in.content = RestSession.newRawInput(CONTENT_NEW); + assertEquals(SC_NO_CONTENT, session.putRaw(urlEditFile(), + in.content).getStatusCode()); + Optional edit = editUtil.byChange(change); + assertEquals(RefUpdate.Result.FORCED, + modifier.modifyFile( + edit.get(), + FILE_NAME, + CONTENT_NEW2)); + edit = editUtil.byChange(change); + RestResponse r = session.get(urlEditFile()); + assertEquals(SC_OK, r.getStatusCode()); + String content = r.getEntityContent(); + assertEquals(StringUtils.newStringUtf8(CONTENT_NEW2), + StringUtils.newStringUtf8(Base64.decodeBase64(content))); + } + + @Test + public void getFileNotFoundRest() throws Exception { + assertEquals(RefUpdate.Result.NEW, + modifier.createEdit( + change, + ps)); + assertEquals(SC_NO_CONTENT, session.delete(urlEditFile()).getStatusCode()); + Optional edit = editUtil.byChange(change); + try { + fileUtil.getContent(edit.get().getChange().getProject(), + edit.get().getRevision().get(), FILE_NAME); + fail("ResourceNotFoundException expected"); + } catch (ResourceNotFoundException rnfe) { + } + RestResponse r = session.get(urlEditFile()); + assertEquals(SC_NO_CONTENT, r.getStatusCode()); + } + @Test public void addNewFile() throws Exception { assertEquals(RefUpdate.Result.NEW, diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java index 4d673b94eb..fd91476746 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java @@ -310,4 +310,27 @@ public class ChangeEdits implements return Response.none(); } } + + @Singleton + static class Get implements RestReadView { + private final FileContentUtil fileContentUtil; + + @Inject + Get(FileContentUtil fileContentUtil) { + this.fileContentUtil = fileContentUtil; + } + + @Override + public Response apply(ChangeEditResource rsrc) + throws ResourceNotFoundException, IOException { + try { + return Response.ok(fileContentUtil.getContent( + rsrc.getChangeEdit().getChange().getProject(), + rsrc.getChangeEdit().getRevision().get(), + rsrc.getPath())); + } catch (ResourceNotFoundException rnfe) { + return Response.none(); + } + } + } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java index 61808fc6a1..eb29dbda60 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java @@ -104,6 +104,7 @@ public class Module extends RestApiModule { child(CHANGE_KIND, "edit").to(ChangeEdits.class); put(CHANGE_EDIT_KIND, "/").to(ChangeEdits.Put.class); delete(CHANGE_EDIT_KIND).to(ChangeEdits.DeleteContent.class); + get(CHANGE_EDIT_KIND, "/").to(ChangeEdits.Get.class); install(new FactoryModule() { @Override