Package org.fcrepo.test.integration

Source Code of org.fcrepo.test.integration.TestLargeDatastreams

/* 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.integration;

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

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import java.util.Random;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import junit.framework.JUnit4TestAdapter;

import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.util.EntityUtils;
import org.fcrepo.client.FedoraClient;

import org.fcrepo.server.access.FedoraAPIAMTOM;
import org.fcrepo.server.management.FedoraAPIMMTOM;
import org.fcrepo.server.types.mtom.gen.MIMETypedStream;
import org.fcrepo.server.utilities.TypeUtility;

import org.fcrepo.test.FedoraTestCase;


/**
* Performs ingest and export tests using large datastreams.
* This test creates and moves very large files and as such
* takes significant time to run.
* <p/>
* Non-SSL transports *MUST* be available for all APIs in order
* for this test to run properly.
*
* @author Bill Branan
*/
public class TestLargeDatastreams
        extends FedoraTestCase {

    private FedoraClient fedoraClient;

    private FedoraAPIMMTOM apim;

    private FedoraAPIAMTOM apia;

    private static final String pid = "demo:LargeDatastreams";

    private static byte[] DEMO_FOXML;

    private static long gigabyte = 1073741824;
    private final long fileSize = gigabyte * 5;

    static {
        // Test FOXML object
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        sb.append("<foxml:digitalObject VERSION=\"1.1\" PID=\"" + pid + "\" ");
        sb.append("  xmlns:foxml=\"info:fedora/fedora-system:def/foxml#\" ");
        sb.append("  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
        sb.append("  xsi:schemaLocation=\"info:fedora/fedora-system:def/foxml# ");
        sb.append("  http://www.fedora.info/definitions/1/0/foxml1-1.xsd\">");
        sb.append("  <foxml:objectProperties>");
        sb.append("    <foxml:property NAME=\"info:fedora/fedora-system:def/model#state\" VALUE=\"A\"/>");
        sb.append("  </foxml:objectProperties>");
        sb.append("</foxml:digitalObject>");

        try {
            DEMO_FOXML = sb.toString().getBytes("UTF-8");
        } catch (UnsupportedEncodingException uee) {
        }
    }

    @Before
    public void setUp() throws Exception {
        fedoraClient = getFedoraClient();
        apim = fedoraClient.getAPIMMTOM();
        apia = fedoraClient.getAPIAMTOM();
    }
   
    @After
    public void tearDown() {
        fedoraClient.shutdown();
    }

    @Test
    public void testLargeDatastreamIO() throws Exception {
        System.out.println("Running testLargeDatastreams...");

        // Create the object, add the datastream
        System.out.println("  Uploading a file of size " + fileSize + " bytes...");
        String uploadId = upload();
        System.out.println("  Creating data object...");
        apim.ingest(TypeUtility.convertBytesToDataHandler(DEMO_FOXML), FOXML1_1.uri, "new foxml object");
        System.out.println("  Adding uploaded file as a datastream...");
        apim.addDatastream(pid,
                           "DS1",
                           null,
                           "Large Datastream",
                           false,
                           "text/plain",
                           null,
                           uploadId,
                           "M",
                           "A",
                           null,
                           null,
                           "Adding Large Datastream");

        // Export the datastream via API-A-Lite
        System.out.println("  Exporting datastream via API-A-Lite...");
        long exportFileAPIALiteSize = exportAPIALite("DS1");

        // Check the file size to make sure the entire file was retrieved
        assertEquals(fileSize, exportFileAPIALiteSize);

        // Export the datastream via API-A
        System.out.println("  Exporting datastream via API-A...");
        long exportFileAPIASize = exportAPIA("DS1");

        // If file was small enough to transfer via API-A
        if (exportFileAPIASize >= 0) {
            assertEquals(fileSize, exportFileAPIASize);
        }

        // Clean up
        apim.purgeObject(pid, "Removing Test Object", false);
        System.out.println("  Test Complete.");
    }

    private String upload() throws Exception {
        String url = fedoraClient.getUploadURL();
        HttpPost post = new HttpPost(url);
        post.setHeader(HttpHeaders.CONNECTION, "Keep-Alive");
        post.setHeader(HttpHeaders.TRANSFER_ENCODING, "chunked");
        MultipartEntity entity = new MultipartEntity();
        entity.addPart("file", new InputStreamBody(new SizedInputStream(), "file"));
        post.setEntity(entity);
        HttpClient client = fedoraClient.getHttpClient();
        HttpResponse response = null;
        try {
            response = client.execute(post);
            int status = response.getStatusLine().getStatusCode();
            String body = EntityUtils.toString(response.getEntity());

            if (status != HttpStatus.SC_CREATED) {
                throw new IOException("Upload failed: "
                                      + response.getStatusLine().getReasonPhrase()
                                      + ": " + replaceNewlines(body, " "));
            } else {
                body = body.replaceAll("\r", "").replaceAll("\n", "");
                return body;
            }
        } finally {
            if (response != null && response.getEntity() != null) {
                response.getEntity().getContent().close();
            }
        }
    }

    private long exportAPIALite(String dsId) throws Exception {
        String url = apia.describeRepository().getRepositoryBaseURL() +
                     "/get/" + pid + "/" + dsId;
        HttpGet httpMethod = new HttpGet(url);
        httpMethod.setHeader(HttpHeaders.CONNECTION, "Keep-Alive");

        HttpClient client = fedoraClient.getHttpClient();
        HttpResponse response = client.execute(httpMethod);
        BufferedInputStream dataStream =
                new BufferedInputStream(response.getEntity().getContent());

        long bytesRead = 0;
        while (dataStream.read() >= 0) {
            ++bytesRead;
        }

        return bytesRead;
    }

    private long exportAPIA(String dsId) throws Exception {
        MIMETypedStream fileStream = null;
        try {
            fileStream = apia.getDatastreamDissemination(pid, dsId, null);
        } catch (Exception e) {
            if (e.getMessage().indexOf("The datastream you are attempting " +
                                       "to retrieve is too large") > 0) {
                System.out.println("  Expected error generated in API-A export:");
                System.out.println("    Error text: " + e.getMessage());
                return -1;
            } else {
                fail("  Unexpected exception encountered in exportAPIA: " +
                     e.getMessage());
            }
        }

        return TypeUtility.convertDataHandlerToBytes(fileStream.getStream()).length;
    }

    /**
     * Replace newlines with the given string.
     */
    private static String replaceNewlines(String in, String replaceWith) {
        return in.replaceAll("\r", replaceWith).replaceAll("\n", replaceWith);
    }

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

    private class SizedInputStream extends InputStream {

        private long bytesRead = 0;
        Random generator = new Random(System.currentTimeMillis());

        @Override
        public int available() throws IOException {
            return (int) (fileSize - bytesRead);
        }

        @Override
        public int read() throws IOException {
            if (bytesRead < fileSize) {
                ++bytesRead;
                return generator.nextInt(100);
            } else {
                return -1;
            }
        }
    }
}
TOP

Related Classes of org.fcrepo.test.integration.TestLargeDatastreams

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.