Skip to content

Commit

Permalink
Adding Last-Modified header with create/update timestamp when nodes a…
Browse files Browse the repository at this point in the history
…nd datastreams are created/updated (https://www.pivotaltracker.com/story/show/68301562)
  • Loading branch information
escowles committed Apr 15, 2014
1 parent 6153212 commit c871354
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 9 deletions.
Expand Up @@ -25,6 +25,7 @@
import org.slf4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletResponse;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
Expand Down Expand Up @@ -59,6 +60,7 @@
import static org.apache.http.HttpStatus.SC_CONFLICT;
import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT;
import static org.slf4j.LoggerFactory.getLogger;
import static org.fcrepo.jcr.FedoraJcrTypes.JCR_LASTMODIFIED;

/**
* Content controller for adding, reading, and manipulating
Expand Down Expand Up @@ -89,6 +91,7 @@ public Response create(@PathParam("path")
@HeaderParam("Content-Disposition") final String contentDisposition,
@QueryParam("checksum") final String checksum,
@HeaderParam("Content-Type") final MediaType requestContentType,
@Context final HttpServletResponse servletResponse,
final InputStream requestBodyStream)
throws InvalidChecksumException, RepositoryException, URISyntaxException, ParseException {
final MediaType contentType =
Expand Down Expand Up @@ -152,6 +155,11 @@ public Response create(@PathParam("path")

session.save();
versionService.nodeUpdated(datastreamNode);
if ( datastreamNode.hasProperty(JCR_LASTMODIFIED) ) {
final long modified = datastreamNode.getProperty(JCR_LASTMODIFIED).getDate().getTimeInMillis();
servletResponse.setDateHeader("Last-Modified", modified);
}

return created(
new URI(subjects.getGraphSubject(
datastreamNode.getNode(JCR_CONTENT)).getURI()))
Expand Down Expand Up @@ -179,7 +187,8 @@ public Response modifyContent(@PathParam("path") final List<PathSegment> pathLis
@HeaderParam("Content-Disposition") final String contentDisposition,
@HeaderParam("Content-Type") final MediaType requestContentType,
final InputStream requestBodyStream,
@Context final Request request)
@Context final Request request,
@Context final HttpServletResponse servletResponse)
throws RepositoryException, InvalidChecksumException, URISyntaxException, ParseException {

try {
Expand Down Expand Up @@ -234,6 +243,10 @@ public Response modifyContent(@PathParam("path") final List<PathSegment> pathLis
session.save();
versionService.nodeUpdated(datastreamNode);

if (datastreamNode.hasProperty(JCR_LASTMODIFIED)) {
final long modified = datastreamNode.getProperty(JCR_LASTMODIFIED).getDate().getTimeInMillis();
servletResponse.setDateHeader("Last-Modified", modified);
}
if (isNew) {
final HttpGraphSubjects subjects =
new HttpGraphSubjects(session, FedoraNodes.class,
Expand Down
Expand Up @@ -374,7 +374,7 @@ public Response createOrReplaceObjectRdf(
session.save();
versionService.nodeUpdated(resource.getNode());

return status(SC_NO_CONTENT).build();
return status(SC_NO_CONTENT).lastModified(resource.getLastModifiedDate()).build();
} finally {
session.logout();
}
Expand Down Expand Up @@ -532,7 +532,8 @@ public Response createObject(@PathParam("path")
.getURI());
}

return created(location).entity(location.toString()).build();
return created(location).lastModified(result.getLastModifiedDate())
.entity(location.toString()).build();

} finally {
session.logout();
Expand Down
Expand Up @@ -42,6 +42,7 @@
import java.text.ParseException;
import java.util.Date;

import javax.servlet.http.HttpServletResponse;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
Expand Down Expand Up @@ -76,6 +77,9 @@ public class FedoraContentTest {
@Mock
private VersionService mockVersions;

@Mock
private HttpServletResponse mockResponse;

@Mock
private Session mockSession;

Expand Down Expand Up @@ -133,7 +137,7 @@ public void testPutContent() throws RepositoryException, InvalidChecksumExceptio
when(mockDatastreams.exists(mockSession, dsPath)).thenReturn(true);
final Response actual =
testObj.modifyContent(createPathList(pid, dsId), null, "inline; filename=\"xyz\"", null,
dsContentStream, null);
dsContentStream, null, mockResponse);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockDatastreams).createDatastreamNode(any(Session.class),
eq(dsPath), anyString(), eq("xyz"), any(InputStream.class), eq((URI)null));
Expand All @@ -160,7 +164,7 @@ public void testCreateContent() throws RepositoryException, IOException,
when(mockDatastreams.exists(mockSession, dsPath)).thenReturn(true);
final Response actual =
testObj.create(createPathList(pid, dsId), null, null, null, TEXT_PLAIN_TYPE,
dsContentStream);
mockResponse, dsContentStream);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockDatastreams).createDatastreamNode(mockSession, dsPath,
"text/plain", null, dsContentStream, null);
Expand All @@ -187,7 +191,7 @@ public void testCreateContentAtMintedPath() throws RepositoryException, InvalidC
when(mockDatastreams.exists(mockSession, dsPath)).thenReturn(true);
final Response actual =
testObj.create(createPathList(pid), null, null, null, TEXT_PLAIN_TYPE,
dsContentStream);
mockResponse, dsContentStream);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockDatastreams).createDatastreamNode(mockSession,
"/" + pid + "/xyz", "text/plain", null, dsContentStream, null);
Expand Down Expand Up @@ -215,7 +219,7 @@ public void testCreateContentWithSlug() throws RepositoryException, InvalidCheck
when(mockDatastreams.exists(mockSession, dsPath)).thenReturn(true);
final Response actual =
testObj.create(createPathList(pid), dsid, null, null, TEXT_PLAIN_TYPE,
dsContentStream);
mockResponse, dsContentStream);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockDatastreams).createDatastreamNode(mockSession,
"/" + pid + "/slug", "text/plain", null, dsContentStream, null);
Expand Down Expand Up @@ -245,7 +249,7 @@ public void testModifyContent() throws RepositoryException, InvalidChecksumExcep
when(mockDatastreams.exists(mockSession, dsPath)).thenReturn(true);
final Response actual =
testObj.modifyContent(createPathList(pid, dsId), "urn:sha1:some-checksum", null, null,
dsContentStream, mockRequest);
dsContentStream, mockRequest, mockResponse);
assertEquals(NO_CONTENT.getStatusCode(), actual.getStatus());
verify(mockDatastreams).createDatastreamNode(any(Session.class),
eq(dsPath), anyString(), eq((String)null), any(InputStream.class), eq(checksum));
Expand Down Expand Up @@ -275,4 +279,4 @@ public void testGetContent() throws RepositoryException, IOException {
assertEquals("asdf", actualContent);
}

}
}
Expand Up @@ -19,6 +19,8 @@
import static java.util.TimeZone.getTimeZone;
import static java.util.UUID.randomUUID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.text.SimpleDateFormat;
Expand Down Expand Up @@ -55,6 +57,11 @@ public void testAddDatastream() throws Exception {
assertEquals(
"Got wrong URI in Location header for datastream creation!",
serverAddress + "FedoraDatastreamsTest2/zxc/fcr:content", location);

assertTrue("Didn't find Last-Modified header!", response.containsHeader("Last-Modified"));
final String lastmod = response.getFirstHeader("Last-Modified").getValue();
assertNotNull("Should set Last-Modified for new nodes", lastmod);
assertNotEquals("Last-Modified should not be blank for new nodes", lastmod.trim(), "");
}

@Test
Expand Down Expand Up @@ -86,6 +93,11 @@ public void testPutDatastream() throws Exception {
assertEquals(
"Got wrong URI in Location header for datastream creation!",
serverAddress + pid + "/zxc/fcr:content", location);

assertTrue("Didn't find Last-Modified header!", response.containsHeader("Last-Modified"));
final String lastmod = response.getFirstHeader("Last-Modified").getValue();
assertNotNull("Should set Last-Modified for new nodes", lastmod);
assertNotEquals("Last-Modified should not be blank for new nodes", lastmod.trim(), "");
}

@Test
Expand Down
Expand Up @@ -53,6 +53,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

Expand Down Expand Up @@ -164,6 +165,11 @@ public void testIngestWithNewAndSparqlQuery() throws Exception {
assertTrue(graphStore.contains(ANY, createResource(location).asNode(),
DC_TITLE.asNode(), createPlainLiteral("this is a title")
.asNode()));

assertTrue("Didn't find Last-Modified header!", response.containsHeader("Last-Modified"));
final String lastmod = response.getFirstHeader("Last-Modified").getValue();
assertNotNull("Should set Last-Modified for new nodes", lastmod);
assertNotEquals("Last-Modified should not be blank for new nodes", lastmod.trim(), "");
}

@Test
Expand All @@ -190,6 +196,10 @@ public void testIngestWithNewAndGraph() throws Exception {
DC_TITLE.asNode(), createPlainLiteral("this is a title")
.asNode()));

assertTrue("Didn't find Last-Modified header!", response.containsHeader("Last-Modified"));
final String lastmod = response.getFirstHeader("Last-Modified").getValue();
assertNotNull("Should set Last-Modified for new nodes", lastmod);
assertNotEquals("Last-Modified should not be blank for new nodes", lastmod.trim(), "");
}

@Test
Expand Down

0 comments on commit c871354

Please sign in to comment.