/*
* Licensed to DuraSpace under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership.
*
* DuraSpace licenses this file to you 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 org.fcrepo.integration.http.api;
import static org.apache.jena.graph.Node.ANY;
import static org.apache.jena.graph.NodeFactory.createLiteral;
import static org.apache.jena.graph.NodeFactory.createURI;
import static org.apache.jena.rdf.model.ResourceFactory.createResource;
import static org.apache.jena.vocabulary.RDF.type;
import static org.apache.jena.vocabulary.DC.title;
import static java.util.stream.Stream.empty;
import static java.util.stream.Stream.of;
import static javax.ws.rs.core.Link.fromUri;
import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
import static javax.ws.rs.core.HttpHeaders.ACCEPT;
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import static javax.ws.rs.core.Response.Status.CONFLICT;
import static javax.ws.rs.core.Response.Status.NO_CONTENT;
import static javax.ws.rs.core.Response.Status.CREATED;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static javax.ws.rs.core.Response.Status.OK;
import static com.google.common.collect.Iterators.size;
import static org.fcrepo.http.commons.domain.RDFMediaType.POSSIBLE_RDF_RESPONSE_VARIANTS_STRING;
import static org.fcrepo.kernel.api.FedoraTypes.FCR_METADATA;
import static org.fcrepo.kernel.api.RdfLexicon.CREATED_DATE;
import static org.fcrepo.kernel.api.RdfLexicon.DESCRIBED_BY;
import static org.fcrepo.kernel.api.RdfLexicon.EMBED_CONTAINS;
import static org.fcrepo.kernel.api.RdfLexicon.HAS_VERSION;
import static org.fcrepo.kernel.api.RdfLexicon.HAS_VERSION_HISTORY;
import static org.fcrepo.kernel.api.RdfLexicon.HAS_VERSION_LABEL;
import static org.fcrepo.kernel.api.RdfLexicon.NON_RDF_SOURCE;
import static org.fcrepo.kernel.api.RdfLexicon.REPOSITORY_NAMESPACE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.http.client.methods.HttpHead;
import org.fcrepo.http.commons.test.util.CloseableDataset;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.apache.jena.graph.Node;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.sparql.core.DatasetGraph;
import org.apache.jena.sparql.core.Quad;
import javax.ws.rs.core.Link;
/**
* <p>
* FedoraVersionsIT class.
* </p>
*
* @author awoods
* @author ajs6f
*/
public class FedoraVersionsIT extends AbstractResourceIT {
private static final String[] jcrVersioningTriples = new String[] {
REPOSITORY_NAMESPACE + "baseVersion",
REPOSITORY_NAMESPACE + "isCheckedOut",
REPOSITORY_NAMESPACE + "predecessors",
REPOSITORY_NAMESPACE + "versionHistory" };
@Test
public void testGetObjectVersionProfile() throws IOException {
final String id = getRandomUniqueId();
final String label = "v0.0.1";
createObjectAndClose(id);
enableVersioning(id);
postObjectVersion(id, label);
logger.debug("Retrieved version profile:");
try (final CloseableDataset dataset = getDataset(new HttpGet(serverAddress + id + "/fcr:versions"))) {
final DatasetGraph graph = dataset.asDatasetGraph();
assertEquals("Expected exactly 3 triples!", 3, countTriples(graph));
final Resource subject = createResource(serverAddress + id);
final Iterator<Quad> hasVersionTriple = graph.find(ANY, subject.asNode(), HAS_VERSION.asNode(), ANY);
assertTrue("Didn't find a version triple!", hasVersionTriple.hasNext());
final Node versionURI = hasVersionTriple.next().getObject();
assertFalse("Found extra version triple!", hasVersionTriple.hasNext());
assertTrue("Version label wasn't presented!",
graph.contains(ANY, versionURI, HAS_VERSION_LABEL.asNode(), createLiteral(label)));
assertTrue("Version creation date wasn't present!",
graph.contains(ANY, versionURI, CREATED_DATE.asNode(), ANY));
}
}
private static int countTriples(final DatasetGraph g) {
return size(g.find());
}
private static void enableVersioning(final String pid) {
final HttpPut createTx = new HttpPut(serverAddress + pid + "/fcr:versions");
try {
execute(createTx);
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
@Test
public void testGetUnversionedObjectVersionProfile() {
final String pid = getRandomUniqueId();
createObject(pid);
final HttpGet getVersion = new HttpGet(serverAddress + pid + "/fcr:versions");
assertEquals(NOT_FOUND.getStatusCode(), getStatus(getVersion));
}
@Test
public void testAddAndRetrieveVersion() throws IOException {
final String id = getRandomUniqueId();
createObjectAndClose(id);
enableVersioning(id);
logger.debug("Setting a title");
patchLiteralProperty(serverAddress + id, title.getURI(), "First Title");
try (final CloseableDataset dataset = getContent(serverAddress + id)) {
assertTrue("Should find original title", dataset.asDatasetGraph().contains(ANY,
ANY, title.asNode(), createLiteral("First Title")));
}
logger.debug("Posting version v0.0.1");
postObjectVersion(id, "v0.0.1");
logger.debug("Replacing the title");
patchLiteralProperty(serverAddress + id, title.getURI(), "Second Title");
try (final CloseableDataset dataset = getContent(serverAddress + id + "/fcr:versions/v0.0.1")) {
logger.debug("Got version profile:");
final DatasetGraph versionResults = dataset.asDatasetGraph();
assertTrue("Didn't find a version triple!", versionResults.contains(ANY,
ANY, type.asNode(), createURI(REPOSITORY_NAMESPACE + "Version")));
assertTrue("Should find a title in historic version", versionResults.contains(ANY,
ANY, title.asNode(), ANY));
assertTrue("Should find original title in historic version", versionResults.contains(ANY,
ANY, title.asNode(), createLiteral("First Title")));
assertFalse("Should not find the updated title in historic version", versionResults.contains(ANY,
ANY, title.asNode(), createLiteral("Second Title")));
}
}
@Test
public void testVersioningANodeWithAVersionableChild() throws IOException {
final String id = getRandomUniqueId();
createObjectAndClose(id);
enableVersioning(id);
logger.debug("Adding a child");
createDatastream(id, "ds", "This DS will not be versioned");
logger.debug("Posting version");
postObjectVersion(id, "label");
logger.debug("Retrieved version profile:");
try (final CloseableDataset dataset = getDataset(new HttpGet(serverAddress + id + "/fcr:versions"))) {
final DatasetGraph results = dataset.asDatasetGraph();
final Node subject = createURI(serverAddress + id);
assertTrue("Didn't find a version triple!", results.contains(ANY, subject, HAS_VERSION.asNode(), ANY));
final Iterator<Quad> versionIt = results.find(ANY, subject, HAS_VERSION.asNode(), ANY);
while (versionIt.hasNext()) {
final String url = versionIt.next().getObject().getURI();
assertEquals("Version " + url + " isn't accessible!", OK.getStatusCode(), getStatus(new HttpGet(url)));
}
}
}
@Test
public void testVersionHeaders() throws IOException {
final String id = getRandomUniqueId();
createObjectAndClose(id);
enableVersioning(id);
createDatastream(id, "ds", "This DS will be versioned");
final String dsId = id + "/ds";
enableVersioning(dsId);
// Version datastream
postObjectVersion(dsId, "label");
final String versionId = dsId + "/fcr:versions/label";
final Link NON_RDF_SOURCE_LINK = fromUri(NON_RDF_SOURCE.getURI()).rel(type.getLocalName()).build();
final Link DESCRIBED_BY_LINK = fromUri(serverAddress + versionId + "/" + FCR_METADATA).rel(
DESCRIBED_BY.getLocalName()).build();
// Look for expected Link headers
final HttpHead headObjMethod = headObjMethod(versionId);
try (final CloseableHttpResponse response = execute(headObjMethod)) {
final Collection<String> linkHeaders = getLinkHeaders(response);
final Set<Link> resultSet = linkHeaders.stream().map(Link::valueOf).flatMap(link -> {
final String linkRel = link.getRel();
final URI linkUri = link.getUri();
if (linkRel.equals(NON_RDF_SOURCE_LINK.getRel()) && linkUri.equals(NON_RDF_SOURCE_LINK.getUri())) {
// Found nonRdfSource!
return of(NON_RDF_SOURCE_LINK);
} else if (linkRel.equals(DESCRIBED_BY_LINK.getRel()) && linkUri.equals(DESCRIBED_BY_LINK.getUri())) {
// Found describedby!
return of(DESCRIBED_BY_LINK);
}
return empty();
}).collect(Collectors.toSet());
assertTrue("No link headers found!", !linkHeaders.isEmpty());
assertTrue("Didn't find NonRdfSource link header! " + NON_RDF_SOURCE_LINK + " ?= " + linkHeaders,
resultSet.contains(NON_RDF_SOURCE_LINK));
assertTrue("Didn't find describedby link header! " + DESCRIBED_BY_LINK + " ?= " + linkHeaders,
resultSet.contains(DESCRIBED_BY_LINK));
}
}
@Test
public void testCreateLabeledVersion() throws IOException {
logger.debug("Creating an object");
final String objId = getRandomUniqueId();
createObjectAndClose(objId);
enableVersioning(objId);
logger.debug("Setting a title");
patchLiteralProperty(serverAddress + objId, title.getURI(), "Example Title");
logger.debug("Posting a labeled version");
postObjectVersion(objId, "label");
}
@Test
public void testCreateUnlabeledVersion() throws IOException {
logger.debug("Creating an object");
final String objId = getRandomUniqueId();
createObjectAndClose(objId);
enableVersioning(objId);
logger.debug("Setting a title");
patchLiteralProperty(serverAddress + objId, title.getURI(), "Example Title");
logger.debug("Posting an unlabeled version");
final HttpPost postVersion = postObjMethod(objId + "/fcr:versions");
assertEquals(BAD_REQUEST.getStatusCode(), getStatus(postVersion));
}
@Test
public void testVersionLabelWithSpace() throws IOException {
final String label = "label with space";
logger.debug("creating an object");
final String objId = getRandomUniqueId();
createObjectAndClose(objId);
enableVersioning(objId);
logger.debug("Posting a version with label \"" + label + "\"");
postObjectVersion(objId, label);
}
@Test
public void testVersionLabelWithInvalidCharacters() {
final String label = "\"label with quotes";
final String objId = getRandomUniqueId();
createObjectAndClose(objId);
enableVersioning(objId);
final HttpPost postVersion = postObjMethod(objId + "/fcr:versions");
postVersion.addHeader("Slug", label);
assertEquals(BAD_REQUEST.getStatusCode(), getStatus(postVersion));
}
@Test
public void testCreateTwoVersionsWithSameLabel() throws IOException {
final String label1 = "label";
final String label2 = "different-label";
logger.debug("creating an object");
final String objId = getRandomUniqueId();
createObjectAndClose(objId);
enableVersioning(objId);
logger.debug("Setting a title");
patchLiteralProperty(serverAddress + objId, title.getURI(), "First title");
logger.debug("Posting a version with label \"" + label1 + "\"");
postObjectVersion(objId, label1);
logger.debug("Resetting the title");
patchLiteralProperty(serverAddress + objId, title.getURI(), "Second title");
logger.debug("Posting a version with label \"" + label1 + "\"");
final HttpPost postVersion = postObjMethod(objId + "/fcr:versions");
postVersion.addHeader("Slug", "label");
assertEquals("Must not be allowed to create a version with a duplicate label!",
CONFLICT.getStatusCode(), getStatus(postVersion));
final HttpGet getVersions = new HttpGet(serverAddress + objId + "/fcr:versions");
logger.debug("Retrieved versions");
try (final CloseableDataset dataset = getDataset(getVersions)) {
final DatasetGraph results = dataset.asDatasetGraph();
assertEquals("Expected exactly 3 triples!", 3, countTriples(results));
logger.debug("Posting a version with label \"" + label2 + "\"");
postObjectVersion(objId, label2);
logger.debug("Deleting first labeled version \"" + label1 + "\"");
final HttpDelete remove = new HttpDelete(serverAddress + objId + "/fcr:versions/" + label1);
assertEquals(NO_CONTENT.getStatusCode(), getStatus(remove));
/**
* This is the behavior we support... allowing a label to be reused if it's been deleted.
*/
logger.debug("Making a new version with label \"" + label1 + "\"");
postObjectVersion(objId, label1);
}
}
/**
* This test just makes sure that while an object may not have two versions with the same label, two different
* objects may have versions with the same label.
*
* @throws IOException exception thrown during this function
*/
@Test
// TODO this test requires some kind of assertion or negative assertion to make its intent more clear
public
void testCreateTwoObjectsWithVersionsWithTheSameLabel() throws IOException {
final String label = "label";
logger.debug("creating an object");
final String objId1 = getRandomUniqueId();
createObjectAndClose(objId1);
enableVersioning(objId1);
logger.debug("Posting a version with label \"" + label + "\"");
postObjectVersion(objId1, label);
logger.debug("creating another object");
final String objId2 = getRandomUniqueId();
createObjectAndClose(objId2);
enableVersioning(objId2);
logger.debug("Posting a version with label \"" + label + "\"");
postObjectVersion(objId2, label);
}
@Test
public void testGetDatastreamVersionNotFound() throws Exception {
final String pid = getRandomUniqueId();
createObjectAndClose(pid);
enableVersioning(pid);
createDatastream(pid, "ds1", "foo");
enableVersioning(pid + "/ds1");
final HttpGet getVersion = new HttpGet(serverAddress + pid + "/ds1/fcr:versions/lastVersion");
assertEquals(NOT_FOUND.getStatusCode(), getStatus(getVersion));
}
public void mutateDatastream(final String objName, final String dsName, final String contentText)
throws IOException {
assertEquals("Couldn't mutate a datastream!",
NO_CONTENT.getStatusCode(), getStatus(putDSMethod(objName, dsName, contentText)));
}
@Test
public void testInvalidVersionReversion() {
final String objId = getRandomUniqueId();
createObjectAndClose(objId);
enableVersioning(objId);
assertEquals(NOT_FOUND.getStatusCode(),
getStatus(new HttpPatch(serverAddress + objId + "/fcr:versions/invalid-version-label")));
}
@Test
public void testVersionReversion() throws IOException {
final String objId = getRandomUniqueId();
final Node subject = createURI(serverAddress + objId);
final String title1 = "foo";
final String firstVersionLabel = "v1";
final String title2 = "bar";
final String secondVersionLabel = "v2";
createObjectAndClose(objId);
enableVersioning(objId);
patchLiteralProperty(serverAddress + objId, title.getURI(), title1);
postObjectVersion(objId, firstVersionLabel);
patchLiteralProperty(serverAddress + objId, title.getURI(), title2);
postObjectVersion(objId, secondVersionLabel);
try (final CloseableDataset dataset = getDataset(new HttpGet(serverAddress + objId))) {
final DatasetGraph preRollback = dataset.asDatasetGraph();
assertTrue("First title must be present!", preRollback.contains(ANY,
subject, title.asNode(), createLiteral(title1)));
assertTrue("Second title must be present!", preRollback.contains(ANY,
subject, title.asNode(), createLiteral(title2)));
}
revertToVersion(objId, firstVersionLabel);
try (final CloseableDataset dataset = getDataset(new HttpGet(serverAddress + objId))) {
final DatasetGraph postRollback = dataset.asDatasetGraph();
assertTrue("First title must be present!", postRollback.contains(ANY,
subject, title.asNode(), createLiteral(title1)));
assertFalse("Second title must NOT be present!", postRollback.contains(ANY,
subject, title.asNode(), createLiteral(title2)));
}
/*
* Make the sure the node is checked out and able to be updated. Because the JCR concept of checked-out is
* something we don't intend to expose through Fedora in the future, the following line is simply to test that
* writes can be completed after a reversion.
*/
patchLiteralProperty(serverAddress + objId, title.getURI(), "additional change");
}
@Test
public void testRemoveVersion() throws IOException {
// create an object and a named version
final String objId = getRandomUniqueId();
final String versionLabel1 = "versionLabelNumberOne";
final String versionLabel2 = "versionLabelNumberTwo";
createResource(serverAddress + objId);
createObjectAndClose(objId);
enableVersioning(objId);
postObjectVersion(objId, versionLabel1);
postObjectVersion(objId, versionLabel2);
// make sure the version exists
assertEquals(OK.getStatusCode(),
getStatus(new HttpGet(serverAddress + objId + "/fcr:versions/" + versionLabel1)));
// remove the version we created
assertEquals(NO_CONTENT.getStatusCode(),
getStatus(new HttpDelete(serverAddress + objId + "/fcr:versions/" + versionLabel1)));
// make sure the version is gone
assertEquals(NOT_FOUND.getStatusCode(),
getStatus(new HttpGet(serverAddress + objId + "/fcr:versions/" + versionLabel1)));
}
@Test
public void testRemoveInvalidVersion() {
// create an object
final String objId = getRandomUniqueId();
createObjectAndClose(objId);
enableVersioning(objId);
// removing a non-existent version should 404
assertEquals(NOT_FOUND.getStatusCode(),
getStatus(new HttpDelete(serverAddress + objId + "/fcr:versions/invalid-version-label")));
}
@Test
public void testRemoveCurrentVersion() throws IOException {
// create an object
final String versionLabel = "testVersionNumberUno";
final String objId = getRandomUniqueId();
createObjectAndClose(objId);
enableVersioning(objId);
postObjectVersion(objId, versionLabel);
// removing the current version should 400
assertEquals(BAD_REQUEST.getStatusCode(),
getStatus(new HttpDelete(serverAddress + objId + "/fcr:versions/" + versionLabel)));
}
@Test
public void testVersionOperationAddsVersionableMixin() throws IOException {
final String id = getRandomUniqueId();
createObjectAndClose(id);
final Node subject = createURI(serverAddress + id);
try (final CloseableDataset dataset = getContent(serverAddress + id)) {
assertFalse("Node must not have versionable mixin.", dataset.asDatasetGraph().contains(ANY,
subject, HAS_VERSION_HISTORY.asNode(), ANY));
}
postObjectVersion(id, "label");
try (final CloseableDataset dataset = getContent(serverAddress + id)) {
final DatasetGraph updatedObjectProperties = dataset.asDatasetGraph();
assertTrue("Node is expected to contain hasVersions triple.", updatedObjectProperties.contains(ANY,
subject, HAS_VERSION_HISTORY.asNode(), ANY));
}
}
@Test
public void testDatastreamAutoMixinAndRevert() throws IOException {
final String pid = getRandomUniqueId();
final String dsid = "ds1";
createObjectAndClose(pid);
final String originalContent = "This is the original content";
final String versionLabel = "ver1";
createDatastream(pid, dsid, originalContent);
// datastream should not have fcr:versions endpoint
assertEquals(NOT_FOUND.getStatusCode(),
getStatus(new HttpGet(serverAddress + pid + "/" + dsid + "/fcr:versions")));
// datastream should not be versionable
try (final CloseableDataset dataset = getContent(serverAddress + pid + "/" + dsid + "/fcr:metadata")) {
final DatasetGraph originalObjectProperties = dataset.asDatasetGraph();
final Node subject = createURI(serverAddress + pid + "/" + dsid);
assertFalse("Node must not contain any hasVersions triples.", originalObjectProperties.contains(ANY,
subject, HAS_VERSION_HISTORY.asNode(), ANY));
}
// creating a version should succeed
final HttpPost httpPost = new HttpPost(serverAddress + pid + "/" + dsid + "/fcr:versions");
httpPost.setHeader("Slug", versionLabel);
try (final CloseableHttpResponse response = execute(httpPost)) {
assertEquals(CREATED.getStatusCode(), getStatus(response));
final String dsVersionURI = getLocation(response);
assertNotNull("No version location header found", dsVersionURI);
// version triples should not have fcr:metadata as the subject
try (final CloseableDataset dataset = getContent(dsVersionURI)) {
final DatasetGraph dsVersionProperties = dataset.asDatasetGraph();
assertTrue("Should have triples about the datastream", dsVersionProperties.contains(ANY,
createURI(dsVersionURI.replaceAll("/fcr:metadata","")), ANY, ANY));
assertFalse("Shouldn't have triples about fcr:metadata", dsVersionProperties.contains(ANY,
createURI(dsVersionURI), ANY, ANY));
}
}
// datastream should then have versions endpoint
assertEquals(OK.getStatusCode(), getStatus(new HttpGet(serverAddress + pid + "/" + dsid + "/fcr:versions")));
// datastream should then be versionable
try (final CloseableDataset dataset = getContent(serverAddress + pid + "/" + dsid + "/fcr:metadata")) {
assertTrue("Node is expected to contain hasVersions triple.", dataset.asDatasetGraph().contains(
ANY, createURI(serverAddress + pid + "/" + dsid), HAS_VERSION_HISTORY.asNode(), ANY));
}
// update the content
final String updatedContent = "This is the updated content";
executeAndClose(putDSMethod(pid, dsid, updatedContent));
try (final CloseableHttpResponse dsResponse = execute(getDSMethod(pid, dsid))) {
assertEquals(updatedContent, EntityUtils.toString(dsResponse.getEntity()));
}
// revert to the original content
revertToVersion(pid + "/" + dsid, versionLabel);
try (final CloseableHttpResponse dsResponse2 = execute(getDSMethod(pid, dsid))) {
assertEquals(originalContent, EntityUtils.toString(dsResponse2.getEntity()));
}
}
@Test
public void testIndexResponseContentTypes() throws IOException {
final String id = getRandomUniqueId();
createObjectAndClose(id);
enableVersioning(id);
for (final String type : POSSIBLE_RDF_RESPONSE_VARIANTS_STRING) {
final HttpGet method = new HttpGet(serverAddress + id + "/fcr:versions");
method.addHeader(ACCEPT, type);
assertEquals(type, getContentType(method));
}
}
@Test
public void testGetVersionResponseContentTypes() throws IOException {
final String id = getRandomUniqueId();
final String versionName = "v1";
createObjectAndClose(id);
enableVersioning(id);
postObjectVersion(id, versionName);
for (final String type : POSSIBLE_RDF_RESPONSE_VARIANTS_STRING) {
final HttpGet method = new HttpGet(serverAddress + id + "/fcr:versions/" + versionName);
method.addHeader(ACCEPT, type);
assertEquals(type, getContentType(method));
}
}
@Test
public void testOmissionOfJCRCVersionRDF() throws IOException {
final String id = getRandomUniqueId();
createObjectAndClose(id);
enableVersioning(id);
try (final CloseableDataset dataset = getDataset(new HttpGet(serverAddress + id))) {
final Node subject = createURI(serverAddress + id);
for (final String prohibitedProperty : jcrVersioningTriples) {
assertFalse(prohibitedProperty + " must not appear in RDF for version-enabled node!",
dataset.asDatasetGraph().contains(ANY, subject, createURI(prohibitedProperty), ANY));
}
}
}
private static void patchLiteralProperty(final String url, final String predicate, final String literal)
throws IOException {
final HttpPatch updateObjectGraphMethod = new HttpPatch(url);
updateObjectGraphMethod.addHeader(CONTENT_TYPE, "application/sparql-update");
updateObjectGraphMethod.setEntity(new StringEntity(
"INSERT DATA { <> <" + predicate + "> \"" + literal + "\" } "));
assertEquals(NO_CONTENT.getStatusCode(), getStatus(updateObjectGraphMethod));
}
private CloseableDataset getContent(final String url) throws IOException {
final HttpGet getVersion = new HttpGet(url);
getVersion.addHeader("Prefer", "return=representation; include=\"" + EMBED_CONTAINS.toString() + "\"");
return getDataset(getVersion);
}
public void postObjectVersion(final String pid) throws IOException {
postVersion(pid, null);
}
public void postObjectVersion(final String pid, final String versionLabel) throws IOException {
postVersion(pid, versionLabel);
}
public void postDsVersion(final String pid, final String dsId) throws IOException {
postVersion(pid + "/" + dsId, null);
}
public void postVersion(final String path, final String label) throws IOException {
logger.debug("Posting version");
final HttpPost postVersion = postObjMethod(path + "/fcr:versions");
postVersion.addHeader("Slug", label);
try (final CloseableHttpResponse response = execute(postVersion)) {
assertEquals(CREATED.getStatusCode(), getStatus(response));
assertNotNull("No version location header found", getLocation(response));
}
}
private static void revertToVersion(final String objId, final String versionLabel) {
assertEquals(NO_CONTENT.getStatusCode(),
getStatus(new HttpPatch(serverAddress + objId + "/fcr:versions/" + versionLabel)));
}
}