Skip to content

Commit

Permalink
Merge pull request #156 from futures/http-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Woods committed Nov 19, 2013
2 parents 7564c9b + f3dd9d0 commit e5ba8d6
Show file tree
Hide file tree
Showing 10 changed files with 259 additions and 50 deletions.
Expand Up @@ -174,11 +174,11 @@ public Response create(@PathParam("path")
*/
@PUT
@Timed
public Response modifyContent(@PathParam("path")
final List<PathSegment> pathList, @HeaderParam("Content-Type")
final MediaType requestContentType,
final InputStream requestBodyStream, @Context
final Request request) throws RepositoryException,
public Response modifyContent(@PathParam("path") final List<PathSegment> pathList,
@QueryParam("checksum") final String checksum,
@HeaderParam("Content-Type") final MediaType requestContentType,
final InputStream requestBodyStream,
@Context final Request request) throws RepositoryException,
IOException, InvalidChecksumException, URISyntaxException {
try {
final String path = toPath(pathList);
Expand Down Expand Up @@ -206,9 +206,20 @@ public Response modifyContent(@PathParam("path")
}

logger.debug("create Datastream {}", path);

final URI checksumURI;

if (checksum != null && !checksum.equals("")) {
checksumURI = new URI(checksum);
} else {
checksumURI = null;
}


final Node datastreamNode =
datastreamService.createDatastreamNode(session, path,
contentType.toString(), requestBodyStream);
datastreamService.createDatastreamNode(session, path,
contentType.toString(), requestBodyStream, checksumURI);

final boolean isNew = datastreamNode.isNew();
session.save();
versionService.checkpoint(session, path);
Expand Down
Expand Up @@ -76,9 +76,9 @@ public class FedoraIdentifiers extends AbstractResource {
/**
* Mint identifiers (without creating the objects)
*
* POST /path/to/mint/from/fcr:identifier?numPids=15
* POST /path/to/mint/from/fcr:identifier?count=15
*
* @param numPids number of PIDs to return
* @param count number of PIDs to return
* @return HTTP 200 with block of PIDs
*/
@POST
Expand All @@ -87,9 +87,9 @@ public class FedoraIdentifiers extends AbstractResource {
TEXT_HTML})
public Dataset getNextPid(@PathParam("path")
final List<PathSegment> pathList,
@QueryParam("numPids")
@QueryParam("count")
@DefaultValue("1")
final Integer numPids,
final Integer count,
@Context
final UriInfo uriInfo) throws RepositoryException {

Expand All @@ -101,7 +101,7 @@ public Dataset getNextPid(@PathParam("path")
createResource(uriInfo.getAbsolutePath().toASCIIString());

final Collection<String> identifiers =
transform(create(closed(1, numPids), integers()), pidMinter
transform(create(closed(1, count), integers()), pidMinter
.makePid());

final HttpGraphSubjects subjects =
Expand Down
66 changes: 57 additions & 9 deletions fcrepo-http-api/src/main/java/org/fcrepo/http/api/FedoraNodes.java
Expand Up @@ -266,6 +266,7 @@ public Response updateSparql(@PathParam("path")
try {

if (requestBodyStream != null) {

final FedoraResource resource =
nodeService.getObject(session, path);

Expand Down Expand Up @@ -338,6 +339,7 @@ public Response createOrReplaceObjectRdf(
try {
final FedoraResource resource =
nodeService.getObject(session, path);

final Date date = resource.getLastModifiedDate();
final Date roundedDate = new Date();

Expand Down Expand Up @@ -522,7 +524,7 @@ public Response createObject(@PathParam("path")
.getURI());
}

return created(location).entity(newObjectPath).build();
return created(location).entity(location.toString()).build();

} finally {
session.logout();
Expand Down Expand Up @@ -564,10 +566,33 @@ public Response createObjectFromFormPost(
@DELETE
@Timed
public Response deleteObject(@PathParam("path")
final List<PathSegment> path) throws RepositoryException {
final List<PathSegment> pathList,
@Context final Request request) throws RepositoryException {

try {
nodeService.deleteObject(session, toPath(path));

final String path = toPath(pathList);

final FedoraResource resource =
nodeService.getObject(session, path);


final EntityTag etag = new EntityTag(resource.getEtagValue());
final Date date = resource.getLastModifiedDate();
final Date roundedDate = new Date();

if (date != null) {
roundedDate.setTime(date.getTime() - date.getTime() % 1000);
}

final ResponseBuilder builder =
request.evaluatePreconditions(roundedDate, etag);

if (builder != null) {
throw new WebApplicationException(builder.build());
}

nodeService.deleteObject(session, path);
session.save();
return noContent().build();
} finally {
Expand Down Expand Up @@ -621,27 +646,50 @@ public Response copyObject(@PathParam("path") final List<PathSegment> path,
*/
@MOVE
@Timed
public Response moveObject(@PathParam("path") final List<PathSegment> path,
@HeaderParam("Destination") final String destinationUri)
public Response moveObject(@PathParam("path") final List<PathSegment> pathList,
@HeaderParam("Destination") final String destinationUri,
@Context final Request request)
throws RepositoryException, URISyntaxException {

try {

final GraphSubjects subjects =
new HttpGraphSubjects(session, FedoraNodes.class, uriInfo);
final String path = toPath(pathList);

if (!nodeService.exists(session, toPath(path))) {
if (!nodeService.exists(session, path)) {
return status(SC_CONFLICT).entity("The source path does not exist").build();
}


final FedoraResource resource =
nodeService.getObject(session, path);


final EntityTag etag = new EntityTag(resource.getEtagValue());
final Date date = resource.getLastModifiedDate();
final Date roundedDate = new Date();

if (date != null) {
roundedDate.setTime(date.getTime() - date.getTime() % 1000);
}

final ResponseBuilder builder =
request.evaluatePreconditions(roundedDate, etag);

if (builder != null) {
throw new WebApplicationException(builder.build());
}

final GraphSubjects subjects =
new HttpGraphSubjects(session, FedoraNodes.class, uriInfo);

final String destination =
subjects.getPathFromGraphSubject(ResourceFactory.createResource(destinationUri));

if (destination == null) {
return status(SC_BAD_GATEWAY).entity("Destination was not a valid resource path").build();
}

nodeService.moveObject(session, toPath(path), destination);
nodeService.moveObject(session, path, destination);
session.save();
versionService.checkpoint(session, destination);
return created(new URI(destinationUri)).build();
Expand Down
Expand Up @@ -18,9 +18,10 @@

import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
import static com.hp.hpl.jena.vocabulary.RDF.type;
import static java.util.Collections.singletonMap;
import static com.sun.jersey.api.Responses.clientError;
import static javax.ws.rs.core.MediaType.TEXT_HTML;
import static javax.ws.rs.core.Response.created;
import static javax.ws.rs.core.Response.noContent;
import static org.fcrepo.http.commons.domain.RDFMediaType.N3;
import static org.fcrepo.http.commons.domain.RDFMediaType.N3_ALT1;
import static org.fcrepo.http.commons.domain.RDFMediaType.N3_ALT2;
Expand All @@ -32,22 +33,28 @@
import static org.slf4j.LoggerFactory.getLogger;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.fcrepo.http.api.FedoraNodes;
import org.fcrepo.http.commons.AbstractResource;
import org.fcrepo.http.commons.api.rdf.HttpGraphSubjects;
import org.fcrepo.http.commons.responses.HtmlTemplate;
import org.fcrepo.http.commons.session.InjectedSession;
import org.fcrepo.kernel.rdf.GraphSubjects;
import org.fcrepo.kernel.utils.JcrRdfTools;
import org.slf4j.Logger;
import org.springframework.context.annotation.Scope;
Expand Down Expand Up @@ -82,7 +89,8 @@ public class FedoraRepositoryWorkspaces extends AbstractResource {
@Produces({TURTLE, N3, N3_ALT1, N3_ALT2, RDF_XML, RDF_JSON, NTRIPLES,
TEXT_HTML})
@HtmlTemplate("jcr:workspaces")
public Dataset getWorkspaces() throws RepositoryException {
public Dataset getWorkspaces(@Context final UriInfo uriInfo)
throws RepositoryException {

final Model workspaceModel =
JcrRdfTools.withContext(null, session).getNamespaceTriples().asModel();
Expand Down Expand Up @@ -118,17 +126,47 @@ public Dataset getWorkspaces() throws RepositoryException {
*/
@POST
@Path("{path}")
public Response createWorkspace(@PathParam("path")
final String path,
@Context
final UriInfo uriInfo) throws RepositoryException,
MalformedURLException {
final Workspace workspace = session.getWorkspace();
workspace.createWorkspace(path);

return created(
uriInfo.getAbsolutePathBuilder().path(FedoraNodes.class)
.buildFromMap(singletonMap("path", path))).build();
public Response createWorkspace(@PathParam("path") final String path,
@Context final UriInfo uriInfo)
throws RepositoryException, MalformedURLException, URISyntaxException {

try {
final Workspace workspace = session.getWorkspace();

if (!workspace.getName().equals("default")) {
throw new WebApplicationException(
clientError().entity("Unable to create workspace from non-default workspace")
.build());
}

workspace.createWorkspace(path);

final GraphSubjects subjects =
new HttpGraphSubjects(session.getRepository().login(path), FedoraNodes.class, uriInfo);


return created(new URI(subjects.getGraphSubject("/").getURI())).build();
} finally {
session.logout();
}
}

/**
* Delete a workspace from the repository
* @param path
* @return
* @throws RepositoryException
*/
@DELETE
@Path("{path}")
public Response deleteWorkspace(@PathParam("path") final String path) throws RepositoryException {
try {
final Workspace workspace = session.getWorkspace();
workspace.deleteWorkspace(path);

return noContent().build();
} finally {
session.logout();
}
}
}
Expand Up @@ -117,15 +117,15 @@ public void testPutContent() throws RepositoryException, IOException,
when(mockNodeService.exists(mockSession, dsPath)).thenReturn(false);
when(
mockDatastreams.createDatastreamNode(any(Session.class),
eq(dsPath), anyString(), any(InputStream.class)))
eq(dsPath), anyString(), any(InputStream.class), eq((URI)null)))
.thenReturn(mockNode);
when(mockDatastreams.exists(mockSession, dsPath)).thenReturn(true);
final Response actual =
testObj.modifyContent(createPathList(pid, dsId), null,
testObj.modifyContent(createPathList(pid, dsId), null, null,
dsContentStream, null);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockDatastreams).createDatastreamNode(any(Session.class),
eq(dsPath), anyString(), any(InputStream.class));
eq(dsPath), anyString(), any(InputStream.class), eq((URI)null));
verify(mockSession).save();
}

Expand Down Expand Up @@ -223,6 +223,7 @@ public void testModifyContent() throws RepositoryException, IOException,
final String dsId = "testDS";
final String dsContent = "asdf";
final String dsPath = "/" + pid + "/" + dsId;
final URI checksum = new URI("urn:sha1:some-checksum");
final InputStream dsContentStream = IOUtils.toInputStream(dsContent);
when(mockNode.isNew()).thenReturn(false);
final Datastream mockDs = mockDatastream(pid, dsId, dsContent);
Expand All @@ -234,15 +235,15 @@ public void testModifyContent() throws RepositoryException, IOException,
any(EntityTag.class))).thenReturn(null);
when(
mockDatastreams.createDatastreamNode(any(Session.class),
eq(dsPath), anyString(), any(InputStream.class)))
eq(dsPath), anyString(), any(InputStream.class), eq(checksum)))
.thenReturn(mockNode);
when(mockDatastreams.exists(mockSession, dsPath)).thenReturn(true);
final Response actual =
testObj.modifyContent(createPathList(pid, dsId), null,
testObj.modifyContent(createPathList(pid, dsId), "urn:sha1:some-checksum", null,
dsContentStream, mockRequest);
assertEquals(NO_CONTENT.getStatusCode(), actual.getStatus());
verify(mockDatastreams).createDatastreamNode(any(Session.class),
eq(dsPath), anyString(), any(InputStream.class));
eq(dsPath), anyString(), any(InputStream.class), eq(checksum));
verify(mockSession).save();
}

Expand Down

0 comments on commit e5ba8d6

Please sign in to comment.