/*
* 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 javax.ws.rs.core.HttpHeaders.ACCEPT;
import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
import static javax.ws.rs.core.Response.Status.NO_CONTENT;
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 javax.ws.rs.core.Response.Status.CREATED;
import static org.fcrepo.http.commons.domain.RDFMediaType.POSSIBLE_RDF_RESPONSE_VARIANTS_STRING;
import static org.fcrepo.kernel.api.FedoraTypes.DEFAULT_DIGEST_ALGORITHM;
import static org.fcrepo.kernel.api.RdfLexicon.HAS_FIXITY_RESULT;
import static org.fcrepo.kernel.api.RdfLexicon.HAS_FIXITY_STATE;
import static org.fcrepo.kernel.api.RdfLexicon.HAS_MESSAGE_DIGEST;
import static org.fcrepo.kernel.api.RdfLexicon.HAS_MESSAGE_DIGEST_ALGORITHM;
import static org.fcrepo.kernel.api.RdfLexicon.HAS_SIZE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.Iterator;
import org.apache.http.client.methods.CloseableHttpResponse;
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.fcrepo.http.commons.test.util.CloseableDataset;
import org.junit.Test;
import org.apache.jena.datatypes.RDFDatatype;
import org.apache.jena.datatypes.TypeMapper;
import org.apache.jena.sparql.core.DatasetGraph;
import org.apache.jena.sparql.core.Quad;
/**
* <p>FedoraFixityIT class.</p>
*
* @author awoods
* @author ajs6f
*/
public class FedoraFixityIT extends AbstractResourceIT {
private static final RDFDatatype IntegerType = TypeMapper.getInstance().getTypeByClass(Integer.class);
private static final RDFDatatype StringType = TypeMapper.getInstance().getTypeByClass(String.class);
@Test
public void testCheckDatastreamFixity() throws IOException {
final String id = getRandomUniqueId();
createObjectAndClose(id);
createDatastream(id, "zxc", "foo");
try (final CloseableDataset dataset =
getDataset(new HttpGet(serverAddress + id + "/zxc/fcr:fixity"))) {
final DatasetGraph graphStore = dataset.asDatasetGraph();
logger.debug("Got triples {}", graphStore);
assertTrue(graphStore.contains(ANY,
createURI(serverAddress + id + "/zxc"), HAS_FIXITY_RESULT.asNode(), ANY));
assertTrue(graphStore.contains(ANY, ANY, HAS_FIXITY_STATE.asNode(), createLiteral("SUCCESS")));
assertTrue(graphStore.contains(ANY,
ANY, HAS_MESSAGE_DIGEST.asNode(), createURI("urn:sha1:0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33")));
assertTrue(graphStore.contains(ANY, ANY, HAS_MESSAGE_DIGEST_ALGORITHM.asNode(), ANY));
assertTrue(graphStore.contains(ANY, ANY, HAS_SIZE.asNode(), createLiteral("3", IntegerType)));
}
}
@Test
public void testCheckDatastreamFixityMD5() throws IOException {
final String id = getRandomUniqueId();
final String childId = id + "/child";
final HttpPut put = putDSMethod(id, "child", "text-body");
put.setHeader("Digest", "md5=888c09337d6869fa48bbeff802ddd05a");
assertEquals("Did not create successfully!", CREATED.getStatusCode(), getStatus(put));
// Set default digest algorithm
final HttpPatch patch = patchObjMethod(childId + "/fcr:metadata");
patch.setHeader(CONTENT_TYPE, "application/sparql-update");
final String updateString = "PREFIX config: <info:fedoraconfig/>\n" +
"INSERT DATA { <> " + DEFAULT_DIGEST_ALGORITHM + " \"md5\" }";
patch.setEntity(new StringEntity(updateString));
assertEquals("Did not update successfully!", NO_CONTENT.getStatusCode(), getStatus(patch));
try (final CloseableDataset dataset = getDataset(new HttpGet(serverAddress + childId + "/fcr:fixity"))) {
final DatasetGraph graphStore = dataset.asDatasetGraph();
logger.debug("Got triples {}", graphStore);
assertTrue(graphStore.contains(ANY,
createURI(serverAddress + childId), HAS_FIXITY_RESULT.asNode(), ANY));
assertTrue(graphStore.contains(ANY, ANY, HAS_FIXITY_STATE.asNode(), createLiteral("SUCCESS")));
assertTrue(graphStore.contains(ANY,
ANY, HAS_MESSAGE_DIGEST.asNode(), createURI("urn:md5:888c09337d6869fa48bbeff802ddd05a")));
assertTrue(graphStore.contains(ANY, ANY, HAS_MESSAGE_DIGEST_ALGORITHM.asNode(),
createLiteral("MD5", StringType)));
assertTrue(graphStore.contains(ANY, ANY, HAS_SIZE.asNode(), createLiteral("9", IntegerType)));
}
}
@Test
public void testResponseContentTypes() throws IOException {
final String id = getRandomUniqueId();
createObjectAndClose(id);
createDatastream(id, "zxc", "foo");
for (final String type : POSSIBLE_RDF_RESPONSE_VARIANTS_STRING) {
final HttpGet method = new HttpGet(serverAddress + id + "/zxc/fcr:fixity");
method.addHeader(ACCEPT, type);
assertEquals(type, getContentType(method));
}
}
@Test
public void testBinaryVersionFixity() throws IOException {
final String id = getRandomUniqueId();
createObjectAndClose(id);
createDatastream(id, "dsid", "foo");
logger.debug("Creating binary content version v0 ...");
postVersion(id + "/dsid", "v0");
try (final CloseableDataset dataset =
getDataset(new HttpGet(serverAddress + id + "/dsid/fcr%3aversions/v0/fcr:fixity"))) {
final DatasetGraph graphStore = dataset.asDatasetGraph();
logger.debug("Got binary content versioned fixity triples {}", graphStore);
final Iterator<Quad> stmtIt = graphStore.find(ANY, ANY, HAS_FIXITY_RESULT.asNode(), ANY);
assertTrue(stmtIt.hasNext());
assertTrue(graphStore.contains(ANY, ANY, HAS_FIXITY_STATE.asNode(), createLiteral("SUCCESS")));
assertTrue(graphStore.contains(ANY, ANY, HAS_MESSAGE_DIGEST.asNode(), ANY));
assertTrue(graphStore.contains(ANY, ANY, HAS_SIZE.asNode(), createLiteral("3", IntegerType)));
}
}
private static 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));
final String locationHeader = getLocation(response);
assertNotNull("No version location header found", locationHeader);
}
}
}