Peer review

This commit is contained in:
René Pfeuffer
2018-08-17 09:33:45 +02:00
parent 8ee550e8e7
commit 6a7987481a
8 changed files with 73 additions and 28 deletions

View File

@@ -11,6 +11,8 @@ import org.junit.runners.Parameterized;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import static java.lang.Thread.sleep;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeFalse;
import static sonia.scm.it.RestUtil.given; import static sonia.scm.it.RestUtil.given;
@@ -64,4 +66,34 @@ public class RepositoryAccessITCase {
assertNotNull(branchName); assertNotNull(branchName);
} }
@Test
public void shouldReadContent() throws IOException, InterruptedException {
repositoryUtil.createAndCommitFile("a.txt", "a");
sleep(1000);
String sourcesUrl = given()
.when()
.get(TestData.getDefaultRepositoryUrl(repositoryType))
.then()
.statusCode(HttpStatus.SC_OK)
.extract()
.path("_links.sources.href");
String contentUrl = given()
.when()
.get(sourcesUrl)
.then()
.statusCode(HttpStatus.SC_OK)
.extract()
.path("files[0]._links.content.href");
given()
.when()
.get(contentUrl)
.then()
.statusCode(HttpStatus.SC_OK)
.body(equalTo("a"));
}
} }

View File

@@ -38,10 +38,8 @@ package sonia.scm.repository;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.io.Closeables; import com.google.common.io.Closeables;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.tmatesoft.svn.core.SVNErrorCode; import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNLogEntry; import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNLogEntryPath; import org.tmatesoft.svn.core.SVNLogEntryPath;
@@ -52,20 +50,17 @@ import org.tmatesoft.svn.core.internal.util.SVNXMLUtil;
import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc.SVNClientManager; import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.admin.SVNChangeEntry; import org.tmatesoft.svn.core.wc.admin.SVNChangeEntry;
import sonia.scm.util.HttpUtil; import sonia.scm.util.HttpUtil;
import sonia.scm.util.Util; import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletRequest; //~--- JDK imports ------------------------------------------------------------
import javax.servlet.http.HttpServletResponse;
/** /**
* *
@@ -366,6 +361,7 @@ public final class SvnUtil
public static long getRevisionNumber(String revision) public static long getRevisionNumber(String revision)
throws RepositoryException throws RepositoryException
{ {
// REVIEW Bei SVN wird ohne Revision die -1 genommen, was zu einem Fehler führt
long revisionNumber = -1; long revisionNumber = -1;
if (Util.isNotEmpty(revision)) if (Util.isNotEmpty(revision))

View File

@@ -16,6 +16,7 @@ public class BrowserResultDto extends HalRepresentation implements Iterable<File
private String revision; private String revision;
private String tag; private String tag;
private String branch; private String branch;
// REVIEW files nicht embedded?
private List<FileObjectDto> files; private List<FileObjectDto> files;
@Override @Override
@@ -24,6 +25,7 @@ public class BrowserResultDto extends HalRepresentation implements Iterable<File
return super.add(links); return super.add(links);
} }
// REVIEW return null?
@Override @Override
public Iterator<FileObjectDto> iterator() { public Iterator<FileObjectDto> iterator() {
Iterator<FileObjectDto> it = null; Iterator<FileObjectDto> it = null;

View File

@@ -39,8 +39,12 @@ public class BrowserResultMapper {
} }
private void addLinks(BrowserResult browserResult, BrowserResultDto dto, NamespaceAndName namespaceAndName) { private void addLinks(BrowserResult browserResult, BrowserResultDto dto, NamespaceAndName namespaceAndName) {
if (browserResult.getRevision() == null) {
dto.add(Links.linkingTo().self(resourceLinks.source().selfWithoutRevision(namespaceAndName.getNamespace(), namespaceAndName.getName())).build());
} else {
dto.add(Links.linkingTo().self(resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), browserResult.getRevision())).build()); dto.add(Links.linkingTo().self(resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), browserResult.getRevision())).build());
} }
}
} }

View File

@@ -25,9 +25,12 @@ public abstract class FileObjectMapper extends BaseMapper<FileObject, FileObject
@AfterMapping @AfterMapping
void addLinks(FileObject fileObject, @MappingTarget FileObjectDto dto, @Context NamespaceAndName namespaceAndName, @Context String revision) { void addLinks(FileObject fileObject, @MappingTarget FileObjectDto dto, @Context NamespaceAndName namespaceAndName, @Context String revision) {
dto.add(Links.linkingTo() Links.Builder links = Links.linkingTo()
.self(resourceLinks.source().sourceWithPath(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, fileObject.getName())) .self(resourceLinks.source().sourceWithPath(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, fileObject.getPath()));
.single(link("content", resourceLinks.source().content(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, fileObject.getName()))) if (!dto.isDirectory()) {
.build()); links.single(link("content", resourceLinks.source().content(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, fileObject.getPath())));
}
dto.add(links.build());
} }
} }

View File

@@ -291,11 +291,11 @@ class ResourceLinks {
} }
String self(String namespace, String name, String revision) { String self(String namespace, String name, String revision) {
return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name, revision).method("sources").parameters().method("getAll").parameters("").href(); return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("getAll").parameters(revision).href();
} }
String selfWithoutRevision(String namespace, String name) { String selfWithoutRevision(String namespace, String name) {
return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("getAll").parameters("").href(); return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("getAllWithoutRevision").parameters().href();
} }
public String source(String namespace, String name, String revision) { public String source(String namespace, String name, String revision) {
@@ -303,8 +303,12 @@ class ResourceLinks {
} }
public String sourceWithPath(String namespace, String name, String revision, String path) { public String sourceWithPath(String namespace, String name, String revision, String path) {
if (revision == null) {
return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("get").parameters(null, path).href();
} else {
return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("get").parameters(revision, path).href(); return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("get").parameters(revision, path).href();
} }
}
public String content(String namespace, String name, String revision, String path) { public String content(String namespace, String name, String revision, String path) {
return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("content").parameters().method("get").parameters(revision, path).href(); return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("content").parameters().method("get").parameters(revision, path).href();

View File

@@ -31,7 +31,14 @@ public class SourceRootResource {
@GET @GET
@Produces(VndMediaType.SOURCE) @Produces(VndMediaType.SOURCE)
@Path("{revision : (\\w+)?}") @Path("")
public Response getAllWithoutRevision(@PathParam("namespace") String namespace, @PathParam("name") String name) {
return getSource(namespace, name, "/", null);
}
@GET
@Produces(VndMediaType.SOURCE)
@Path("{revision}")
public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision) { public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision) {
return getSource(namespace, name, "/", revision); return getSource(namespace, name, "/", revision);
} }
@@ -44,8 +51,6 @@ public class SourceRootResource {
} }
private Response getSource(String namespace, String repoName, String path, String revision) { private Response getSource(String namespace, String repoName, String path, String revision) {
BrowserResult browserResult;
Response response;
NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, repoName); NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, repoName);
try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) { try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) {
BrowseCommandBuilder browseCommand = repositoryService.getBrowseCommand(); BrowseCommandBuilder browseCommand = repositoryService.getBrowseCommand();
@@ -53,19 +58,18 @@ public class SourceRootResource {
if (revision != null && !revision.isEmpty()) { if (revision != null && !revision.isEmpty()) {
browseCommand.setRevision(revision); browseCommand.setRevision(revision);
} }
browserResult = browseCommand.getBrowserResult(); BrowserResult browserResult = browseCommand.getBrowserResult();
if (browserResult != null) { if (browserResult != null) {
response = Response.ok(browserResultMapper.map(browserResult, namespaceAndName)).build(); return Response.ok(browserResultMapper.map(browserResult, namespaceAndName)).build();
} else { } else {
response = Response.status(Response.Status.NOT_FOUND).build(); return Response.status(Response.Status.NOT_FOUND).build();
} }
} catch (RepositoryNotFoundException e) { } catch (RepositoryNotFoundException e) {
response = Response.status(Response.Status.NOT_FOUND).build(); return Response.status(Response.Status.NOT_FOUND).build();
} catch (RepositoryException | IOException e) { } catch (RepositoryException | IOException e) {
response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} }
return response;
} }
} }

View File

@@ -54,7 +54,7 @@ public class FileObjectMapperTest {
FileObject fileObject = createFileObject(); FileObject fileObject = createFileObject();
FileObjectDto dto = mapper.map(fileObject, new NamespaceAndName("namespace", "name"), "revision"); FileObjectDto dto = mapper.map(fileObject, new NamespaceAndName("namespace", "name"), "revision");
assertThat(dto.getLinks().getLinkBy("self").get().getHref()).isEqualTo(expectedBaseUri.resolve("namespace/name/sources/revision/foo").toString()); assertThat(dto.getLinks().getLinkBy("self").get().getHref()).isEqualTo(expectedBaseUri.resolve("namespace/name/sources/revision/foo%2Fbar").toString());
} }
@Test @Test
@@ -62,14 +62,14 @@ public class FileObjectMapperTest {
FileObject fileObject = createFileObject(); FileObject fileObject = createFileObject();
FileObjectDto dto = mapper.map(fileObject, new NamespaceAndName("namespace", "name"), "revision"); FileObjectDto dto = mapper.map(fileObject, new NamespaceAndName("namespace", "name"), "revision");
assertThat(dto.getLinks().getLinkBy("content").get().getHref()).isEqualTo(expectedBaseUri.resolve("namespace/name/content/revision/foo").toString()); assertThat(dto.getLinks().getLinkBy("content").get().getHref()).isEqualTo(expectedBaseUri.resolve("namespace/name/content/revision/foo%2Fbar").toString());
} }
private FileObject createFileObject() { private FileObject createFileObject() {
FileObject fileObject = new FileObject(); FileObject fileObject = new FileObject();
fileObject.setName("foo"); fileObject.setName("foo");
fileObject.setDescription("bar"); fileObject.setDescription("bar");
fileObject.setPath("/foo/bar"); fileObject.setPath("foo/bar");
fileObject.setDirectory(false); fileObject.setDirectory(false);
fileObject.setLength(100); fileObject.setLength(100);
fileObject.setLastModified(123L); fileObject.setLastModified(123L);