Package org.fcrepo.test.api

Source Code of org.fcrepo.test.api.TestExternalDatastreams

/* The contents of this file are subject to the license and copyright terms
* detailed in the license directory at the root of the source tree (also
* available online at http://fedora-commons.org/license/).
*/
package org.fcrepo.test.api;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.security.MessageDigest;
import java.util.Date;

import javax.xml.ws.soap.SOAPFaultException;

import junit.framework.JUnit4TestAdapter;

import org.fcrepo.client.FedoraClient;
import org.fcrepo.common.PID;
import org.fcrepo.server.access.FedoraAPIA;
import org.fcrepo.server.management.FedoraAPIM;
import org.fcrepo.server.utilities.StringUtility;
import org.fcrepo.server.utilities.TypeUtility;
import org.fcrepo.test.FedoraServerTestCase;
import org.fcrepo.utilities.Foxml11Document;
import org.fcrepo.utilities.Foxml11Document.ControlGroup;
import org.fcrepo.utilities.Foxml11Document.Property;
import org.fcrepo.utilities.Foxml11Document.State;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
* @author Edwin Shin, Benjamin Armintor
* @version $Id$
* @since 3.6
*/
public class TestExternalDatastreams
        extends FedoraServerTestCase {

    private static final Logger LOGGER =
        LoggerFactory.getLogger(TestExternalDatastreams.class);
    private static FedoraClient s_client;
   
    private FedoraAPIM apim;
    private FedoraAPIA apia;
   
    @BeforeClass
    public static void bootStrap() throws Exception {
        s_client = getFedoraClient();
    }
   
    @AfterClass
    public static void cleanUp() {
        s_client.shutdown();
    }


   
    /**
     * @throws java.lang.Exception
     */
    @Before
    public void setUp() throws Exception {
        apim = s_client.getAPIM();
        apia = s_client.getAPIA();
        System.setProperty("fedoraServerHost", "localhost");
        System.setProperty("fedoraServerPort", "8080");
    }

    /**
     * @throws java.lang.Exception
     */
    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void testIngest() throws Exception {
        String pid = "demo:e_ds_test";
        File content = null;
        try {
            content = getTempFile(true);
            String dsLocation = content.getCanonicalFile().toURI().toString();
            LOGGER.debug("Expect to succeed: {}", dsLocation);
            apim.ingest(getFoxmlObject(pid, dsLocation), FOXML1_1.uri, null);
            apia.getDatastreamDissemination(pid, "DS", null);
        } finally {
            if (content != null) content.delete();
            apim.purgeObject(pid, "test", false);
        }
        try {
            content = getTempFile(false);
            String dsLocation = content.getCanonicalFile().toURI().toString();
            LOGGER.debug("Expect to fail: {}", dsLocation);
            apim.ingest(getFoxmlObject(pid, dsLocation), FOXML1_1.uri, null);
            apia.getDatastreamDissemination(pid, "DS", null);
            fail("Datastream Dissemination with unallowed dsLocation should have failed.");
        } catch (SOAPFaultException e) {
            LOGGER.debug("Checking failure :\"{}\" for \"Policy blocked datastream resolution\"",  e.getMessage());
            assertTrue(e.getMessage().contains("Policy blocked datastream resolution"));
        } finally {
            if (content != null) content.delete();
            apim.purgeObject(pid, "test", false);
        }

    }

    @Test
    public void testAddDatastream() throws Exception {
        String pid = "demo:e_ds_test_add";
        File content = null;

        apim.ingest(getFoxmlObject(pid, null), FOXML1_1.uri, null);
        try {
            content = getTempFile(true);
            String dsLocation = content.getCanonicalFile().toURI().toString();
            addDatastream(pid, dsLocation);
            apia.getDatastreamDissemination(pid, "DS", null);
        } finally {
            if (content != null) content.delete();
            apim.purgeObject(pid, "test", false);
        }

        apim.ingest(getFoxmlObject(pid, null), FOXML1_1.uri, null);
        try {
            content = getTempFile(false);
            String dsLocation = content.getCanonicalFile().toURI().toString();
            addDatastream(pid, dsLocation);
            apia.getDatastreamDissemination(pid, "DS", null);
            fail("Datastream Dissemination with unallowed dsLocation should have failed.");
        } catch (SOAPFaultException e) {
            LOGGER.debug("Checking failure :\"{}\" for \"Policy blocked datastream resolution\"", e.getMessage());
            assertTrue(e.getMessage().contains("Policy blocked datastream resolution"));
        } finally {
            if (content != null) content.delete();
            apim.purgeObject(pid, "test", false);
        }
    }

    @Test
    public void testModifyDatastreamByReference() throws Exception {
        String pid = "demo:e_ds_test_add";

        String dsLocation = getBaseURL() + "/get/fedora-system:ContentModel-3.0/DC";
        apim.ingest(getFoxmlObject(pid, dsLocation), FOXML1_1.uri, null);
        apia.getDatastreamDissemination(pid, "DS", null);
        try {
            dsLocation = getBaseURL() + "/get/fedora-system:ContentModel-3.0/RELS-EXT";
            modifyDatastreamByReference(pid, dsLocation);
        } finally {
            apim.purgeObject(pid, "test", false);
        }

        File content = null;
        dsLocation = getBaseURL() + "/get/fedora-system:ContentModel-3.0/DC";
        apim.ingest(getFoxmlObject(pid, dsLocation), FOXML1_1.uri, null);
        try {
            content = getTempFile(false);
            dsLocation = content.getCanonicalFile().toURI().toString();
            modifyDatastreamByReference(pid, dsLocation);
            apia.getDatastreamDissemination(pid, "DS", null);
            fail("Pointing a datastream to an unallowed dsLocation should have failed.");
        } catch (SOAPFaultException e) {
            LOGGER.debug("Checking failure :\"{}\" for \"Policy blocked datastream resolution\"", e.getMessage());
            assertTrue(e.getMessage().contains("Policy blocked datastream resolution"));
        } finally {
            if (content != null) content.delete();
            apim.purgeObject(pid, "test", false);
        }
    }

    @Test
    public void testAddDatastreamWithChecksum() throws Exception {
        String pid = "demo:e_ds_test_add";
        String checksumType = "MD5";
        apim.ingest(getFoxmlObject(pid, null), FOXML1_1.uri, null);
        File temp = null;

        try {
            temp = getTempFile(true);
            String dsLocation = temp.getCanonicalFile().toURI().toString();
            String checksum = computeChecksum(checksumType, new FileInputStream(temp));
            String dsId = addDatastream(pid, dsLocation, checksumType, checksum);
            assertEquals("DS", dsId);

            // Now ensure that bogus checksums do indeed fail
            apim.purgeDatastream(pid, dsId, null, null, null, false);
            addDatastream(pid, dsLocation, checksumType, checksum);

            apim.purgeDatastream(pid, dsId, null, null, null, false);
            checksum = "bogus";
            try {
                addDatastream(pid, dsLocation, checksumType, checksum);
                fail("Adding datastream with bogus checksum should have failed.");
            } catch (SOAPFaultException e) {
                assertTrue(e.getMessage().contains("Checksum Mismatch"));
            }
        } finally {
            apim.purgeObject(pid, "test", false);
            if (temp != null) temp.delete();
        }

        pid = "demo:e_ds_test_add_portable";
        apim.ingest(getFoxmlObject(pid, null), FOXML1_1.uri, null);
        try {
            String dsLocation = "http://local.fedora.server/fedora/objects/fedora-system:ContentModel-3.0/datastreams/DC/content";
            org.fcrepo.server.types.gen.MIMETypedStream dc_content = apia.getDatastreamDissemination("fedora-system:ContentModel-3.0", "DC", null);
            String checksum = computeChecksum(checksumType, new ByteArrayInputStream(dc_content.getStream()));
            String dsId = addDatastream(pid, dsLocation, checksumType, checksum);
            assertEquals("DS", dsId);
        } finally {
            apim.purgeObject(pid, "testAddDatastreamWithChecksumType", false);
            if (temp != null) temp.delete();
        }
    }

    @Test
    public void testAddDatastreamWithChecksumType() throws Exception {
        String pid = "demo:e_ds_test_add";
        String checksumType = "MD5";
        apim.ingest(getFoxmlObject(pid, null), FOXML1_1.uri, "testAddDatastreamWithChecksumType");
        File temp = null;

        try {
            temp = getTempFile(true);
            String dsLocation = temp.getCanonicalFile().toURI().toString();
            String dsId = addDatastream(pid, dsLocation, checksumType, null);
            assertEquals("DS", dsId);
            String checksum = computeChecksum(checksumType, new FileInputStream(temp));
            assertEquals(apim.getDatastream(pid, "DS", null).getChecksum(),checksum);
        } finally {
            apim.purgeObject(pid, "testAddDatastreamWithChecksumType", false);
            if (temp != null) temp.delete();
        }
        // Now test portable URLs
        pid = "demo:e_ds_test_portable";
        apim.ingest(getFoxmlObject(pid, null), FOXML1_1.uri, "testAddDatastreamWithChecksumType");
        try {
            String dsLocation = "http://local.fedora.server/fedora/objects/fedora-system:ContentModel-3.0/datastreams/DC/content";
            String dsId = addDatastream(pid, dsLocation, checksumType, null);
            assertEquals("DS", dsId);
        } finally {
            apim.purgeObject(pid, "testAddDatastreamWithChecksumType", false);
            if (temp != null) temp.delete();
        }
    }

    @Test
    public void testModifyDatastreamByReferenceWithChecksum() throws Exception {
        String pid = "file:e_ds_test_add"; // file pid namespace should work as well as demo
        String checksumType = "MD5";
        apim.ingest(getFoxmlObject(pid, null), FOXML1_1.uri, null);
        File temp = null;
        try {
            temp = getTempFile(true);
            String contentLocation = temp.getCanonicalFile().toURI().toString();
            String checksum = computeChecksum(checksumType, new FileInputStream(temp));
            String dsId = addDatastream(pid, contentLocation, checksumType, checksum);
            assertEquals("DS", dsId);

            FileOutputStream os = new FileOutputStream(temp);
            os.write("testModifyDatastreamByReferenceWithChecksum".getBytes());
            os.close();
            checksum = computeChecksum(checksumType, new FileInputStream(temp));
            modifyDatastreamByReference(pid, contentLocation, checksumType, checksum);

            // Now ensure that bogus checksums do indeed fail
            checksum = "bogus";
            try {
                modifyDatastreamByReference(pid, contentLocation, checksumType, checksum);
                fail("Modifying datastream with bogus checksum should have failed.");
            } catch (SOAPFaultException e) {
                assertTrue(e.getMessage().contains("Checksum Mismatch"));
            }
        } finally {
            apim.purgeObject(pid, "test", false);
            if (temp != null) temp.delete();
        }
    }

    private File getTempFile(boolean allowed) throws IOException {
        File temp = allowed? File.createTempFile("foo", "isallowed") : File.createTempFile("foo", "banned");
        Writer writer = new FileWriter(temp);
        writer.write("Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit");
        writer.flush();
        writer.close();
        return temp;
    }

    private byte[] getFoxmlObject(String pid, String contentLocation) throws Exception {
        Foxml11Document doc = createFoxmlObject(pid, contentLocation);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        doc.serialize(out);
        return out.toByteArray();
    }

    private String addDatastream(String pid, String contentLocation)
            throws Exception {
        return addDatastream(pid, contentLocation, null, null);
    }

    private String addDatastream(String pid, String dsLocation, String checksumType, String checksum)
            throws Exception {
        return apim.addDatastream(pid,
                                  "DS",
                                  null,
                                  "testExternalDatastreams",
                                  true,
                                  "text/plain",
                                  "",
                                  dsLocation,
                                  "E",
                                  "A",
                                  checksumType,
                                  checksum,
                                  "testExternalDatastreams");
    }

    private String modifyDatastreamByReference(String pid,
                                               String contentLocation)
            throws Exception {
        return modifyDatastreamByReference(pid, contentLocation, null, null);
    }

    private String modifyDatastreamByReference(String pid,
                                               String contentLocation,
                                               String checksumType,
                                               String checksum)
            throws Exception {
        return apim.modifyDatastreamByReference(pid,
                                                "DS",
                                                TypeUtility.convertStringtoAOS(new String[]{}),
                                                "testExternalDatastreams",
                                                "text/plain",
                                                "",
                                                contentLocation,
                                                checksumType,
                                                checksum,
                                                "testExternalDatastreams",
                                                false);
    }


    private Foxml11Document createFoxmlObject(String spid, String contentLocation) throws Exception {
        PID pid = PID.getInstance(spid);
        Date date = new Date(1);

        Foxml11Document doc = new Foxml11Document(pid.toString());
        doc.addObjectProperty(Property.STATE, "A");

        if (contentLocation != null && contentLocation.length() > 0) {
            String ds = "DS";
            String dsv = "DS1.0";
            doc.addDatastream(ds, State.A, ControlGroup.E, true);
            doc.addDatastreamVersion(ds, dsv, "text/plain", "label", 1, date);
            doc.setContentLocation(dsv, contentLocation, org.fcrepo.server.storage.types.Datastream.DS_LOCATION_TYPE_URL);
        }
        return doc;
    }

    private String computeChecksum(String csType, InputStream is) throws Exception {
        MessageDigest md = MessageDigest.getInstance(csType);
        if (is == null) {
            throw new IllegalArgumentException("InputStream cannot be null");
        }
        byte buffer[] = new byte[5000];
        int numread;
        while ((numread = is.read(buffer, 0, 5000)) > 0) {
            md.update(buffer, 0, numread);
        }
        return StringUtility.byteArraytoHexString(md.digest());
    }

    public static junit.framework.Test suite() {
        return new JUnit4TestAdapter(TestExternalDatastreams.class);
    }
}
TOP

Related Classes of org.fcrepo.test.api.TestExternalDatastreams

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.