001/*
002 * Copyright 2015 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fcrepo.migration;
017
018import java.io.ByteArrayInputStream;
019import java.io.ByteArrayOutputStream;
020import java.io.File;
021import java.io.FileNotFoundException;
022import java.io.IOException;
023import java.io.InputStream;
024import java.net.URL;
025import java.util.ArrayList;
026import java.util.Collections;
027import java.util.Iterator;
028import java.util.List;
029
030import javax.xml.stream.XMLStreamException;
031
032import org.apache.commons.io.IOUtils;
033import org.fcrepo.migration.foxml.CachedContent;
034import org.fcrepo.migration.foxml.FoxmlInputStreamFedoraObjectProcessor;
035import org.fcrepo.migration.foxml.InternalIDResolver;
036import org.fcrepo.migration.foxml.URLFetcher;
037import org.junit.Assert;
038import org.junit.Test;
039
040/**
041 * An abstract base class that defines some dummy classes useful for
042 * testing a Migrator instance and a suite of tests appropriate for
043 * a single example object.  Subclasses may expose this example object
044 * in different ways.
045 * @author mdurbin
046 */
047public abstract class Example1TestSuite {
048
049    protected abstract DummyHandler getResult();
050
051    protected abstract DummyURLFetcher getFetcher();
052
053
054    @Test
055    public void testObjectInfoParsing() {
056        Assert.assertEquals("example:1", getResult().objectInfo.getPid());
057        Assert.assertNull(getResult().objectInfo.getFedoraURI());
058    }
059
060    @Test
061    public void testPropertiesParsing() {
062        final List<? extends ObjectProperty> propertyList = getResult().properties.listProperties();
063        Assert.assertEquals(5, propertyList.size());
064        Assert.assertEquals("info:fedora/fedora-system:def/model#state", propertyList.get(0).getName());
065        Assert.assertEquals("Active", propertyList.get(0).getValue());
066        Assert.assertEquals("info:fedora/fedora-system:def/model#label", propertyList.get(1).getName());
067        Assert.assertEquals("This is an example object.", propertyList.get(1).getValue());
068        Assert.assertEquals("info:fedora/fedora-system:def/model#ownerId", propertyList.get(2).getName());
069        Assert.assertEquals("exampleOwner", propertyList.get(2).getValue());
070        Assert.assertEquals("info:fedora/fedora-system:def/model#createdDate", propertyList.get(3).getName());
071        Assert.assertEquals("2015-01-27T19:07:33.120Z", propertyList.get(3).getValue());
072        Assert.assertEquals("info:fedora/fedora-system:def/view#lastModifiedDate", propertyList.get(4).getName());
073        Assert.assertEquals("2015-01-27T20:26:16.998Z", propertyList.get(4).getValue());
074    }
075
076    @Test
077    public void testDatastreamParsing() throws XMLStreamException, IOException {
078        Assert.assertEquals(7, getResult().dsVersions.size());
079    }
080
081    @Test
082    public void testAuditDatastreamParsing() {
083        final DatastreamVersion audit0 = getResult().dsVersions.get(0);
084        Assert.assertEquals("AUDIT", audit0.getDatastreamInfo().getDatastreamId());
085        Assert.assertEquals("A", audit0.getDatastreamInfo().getState());
086        Assert.assertEquals("X", audit0.getDatastreamInfo().getControlGroup());
087        Assert.assertFalse(audit0.getDatastreamInfo().getVersionable());
088        Assert.assertEquals("AUDIT.0", audit0.getVersionId());
089        Assert.assertEquals("Audit Trail for this object", audit0.getLabel());
090        Assert.assertEquals("2015-01-27T19:07:33.120Z", audit0.getCreated());
091        Assert.assertEquals("text/xml", audit0.getMimeType());
092        Assert.assertEquals("info:fedora/fedora-system:format/xml.fedora.audit", audit0.getFormatUri());
093        Assert.assertTrue(audit0.getFile().isEmpty());
094    }
095
096    @Test
097    public void testDCDatastreamParsing() throws IOException {
098        final DatastreamVersion dc0 = getResult().dsVersions.get(1);
099        Assert.assertEquals("DC", dc0.getDatastreamInfo().getDatastreamId());
100        Assert.assertEquals("A", dc0.getDatastreamInfo().getState());
101        Assert.assertEquals("X", dc0.getDatastreamInfo().getControlGroup());
102        Assert.assertTrue(dc0.getDatastreamInfo().getVersionable());
103        Assert.assertEquals("DC1.0", dc0.getVersionId());
104        Assert.assertEquals("Dublin Core Record for this object", dc0.getLabel());
105        Assert.assertEquals("2015-01-27T19:07:33.120Z", dc0.getCreated());
106        Assert.assertEquals("text/xml", dc0.getMimeType());
107        Assert.assertEquals("http://www.openarchives.org/OAI/2.0/oai_dc/", dc0.getFormatUri());
108        Assert.assertEquals(dc0.getSize(), IOUtils.toByteArray(dc0.getContent()).length);
109        Assert.assertEquals("<oai_dc:dc xmlns:oai_dc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\"\n" +
110                "xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +
111                "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
112                "xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd\">\n" +
113                "  <dc:title>This is an example object.</dc:title>\n" +
114                "  <dc:identifier>example:1</dc:identifier>\n" +
115                "</oai_dc:dc>", IOUtils.toString(dc0.getContent()).trim());
116        Assert.assertTrue(dc0.getFile().isEmpty());
117    }
118
119    @Test
120    public void testDS1VersionedDatastreamParsing() throws IOException {
121        final DatastreamVersion ds1 = getResult().dsVersions.get(2);
122        Assert.assertEquals("DS1", ds1.getDatastreamInfo().getDatastreamId());
123        Assert.assertEquals("A", ds1.getDatastreamInfo().getState());
124        Assert.assertEquals("X", ds1.getDatastreamInfo().getControlGroup());
125        Assert.assertTrue(ds1.getDatastreamInfo().getVersionable());
126        Assert.assertEquals("DS1.0", ds1.getVersionId());
127        Assert.assertEquals("Example inline XML datastream", ds1.getLabel());
128        Assert.assertEquals("2015-01-27T19:08:43.701Z", ds1.getCreated());
129        Assert.assertEquals("text/xml", ds1.getMimeType());
130        Assert.assertEquals("alternate_id", ds1.getAltIds());
131        Assert.assertEquals("format:uri", ds1.getFormatUri());
132        Assert.assertEquals(34, ds1.getSize());
133        Assert.assertEquals("<test>\n" +
134                "  This is a test.\n" +
135                "</test>", IOUtils.toString(ds1.getContent()).trim());
136        Assert.assertTrue(ds1.getFile().isEmpty());
137
138        final DatastreamVersion ds2 = getResult().dsVersions.get(3);
139        Assert.assertEquals("DS1", ds2.getDatastreamInfo().getDatastreamId());
140        Assert.assertEquals("A", ds2.getDatastreamInfo().getState());
141        Assert.assertEquals("X", ds2.getDatastreamInfo().getControlGroup());
142        Assert.assertTrue(ds2.getDatastreamInfo().getVersionable());
143        Assert.assertEquals("DS1.1", ds2.getVersionId());
144        Assert.assertEquals("Example inline XML datastream", ds2.getLabel());
145        Assert.assertEquals("2015-01-27T19:20:40.678Z", ds2.getCreated());
146        Assert.assertEquals("text/xml", ds2.getMimeType());
147        Assert.assertEquals("alternate_id", ds2.getAltIds());
148        Assert.assertEquals("format:uri", ds2.getFormatUri());
149        Assert.assertEquals(50, ds2.getSize());
150        Assert.assertNull(ds2.getContentDigest());
151        Assert.assertEquals("<test>\n" +
152                "  This is a test that was edited.\n" +
153                "</test>", IOUtils.toString(ds2.getContent()).trim());
154        Assert.assertTrue(ds2.getFile().isEmpty());
155    }
156
157    @Test
158    public void testDS2BinaryParsing() throws IOException {
159        final DatastreamVersion ds2 = getResult().dsVersions.get(4);
160        Assert.assertEquals("DS2", ds2.getDatastreamInfo().getDatastreamId());
161        Assert.assertEquals("A", ds2.getDatastreamInfo().getState());
162        Assert.assertEquals("M", ds2.getDatastreamInfo().getControlGroup());
163        Assert.assertFalse(ds2.getDatastreamInfo().getVersionable());
164        Assert.assertEquals("DS2.0", ds2.getVersionId());
165        Assert.assertEquals("Example Managed binary datastream", ds2.getLabel());
166        Assert.assertEquals("2015-01-27T19:09:18.112Z", ds2.getCreated());
167        Assert.assertEquals("image/jpeg", ds2.getMimeType());
168        Assert.assertEquals(46168, ds2.getSize());
169        Assert.assertEquals("MD5", ds2.getContentDigest().getType());
170        Assert.assertEquals("d4f18b8b9c64466819ddaad46228fb9b", ds2.getContentDigest().getDigest());
171        Assert.assertTrue("Managed Base64 encoded datastream must be preserved.", IOUtils.contentEquals(
172                getClass().getClassLoader().getResourceAsStream("small-mountains.jpg"),
173                new ByteArrayInputStream(getResult().cachedDsVersionBinaries.get(4))));
174        Assert.assertTrue(ds2.getFile().isPresent());
175    }
176
177    @Test
178    public void testDS3RedirectParsing() throws IOException {
179        final DatastreamVersion ds3 = getResult().dsVersions.get(5);
180        Assert.assertEquals("DS3", ds3.getDatastreamInfo().getDatastreamId());
181        Assert.assertEquals("A", ds3.getDatastreamInfo().getState());
182        Assert.assertEquals("R", ds3.getDatastreamInfo().getControlGroup());
183        Assert.assertTrue(ds3.getDatastreamInfo().getVersionable());
184        Assert.assertEquals("DS3.0", ds3.getVersionId());
185        Assert.assertEquals("Example Redirect \u007Fdatastream.", ds3.getLabel());
186        Assert.assertEquals("2015-01-27T19:14:05.948Z", ds3.getCreated());
187        Assert.assertEquals("image/jpeg", ds3.getMimeType());
188        Assert.assertEquals(-1, ds3.getSize());
189        ds3.getContent().close();
190        Assert.assertEquals("http://" + SimpleObjectSource.LOCAL_FEDORA_SERVER + "/fedora/get/example:1/DS2",
191                getFetcher().getLastUrl().toExternalForm());
192        Assert.assertTrue(ds3.getFile().isEmpty());
193    }
194
195    @Test
196    public void testDS4ExternalParsing() throws IOException {
197        final DatastreamVersion ds4 = getResult().dsVersions.get(6);
198        Assert.assertEquals("DS4", ds4.getDatastreamInfo().getDatastreamId());
199        Assert.assertEquals("A", ds4.getDatastreamInfo().getState());
200        Assert.assertEquals("E", ds4.getDatastreamInfo().getControlGroup());
201        Assert.assertTrue(ds4.getDatastreamInfo().getVersionable());
202        Assert.assertEquals("DS4.0", ds4.getVersionId());
203        Assert.assertEquals("Example External datastream.", ds4.getLabel());
204        Assert.assertEquals("2015-01-27T19:14:38.999Z", ds4.getCreated());
205        Assert.assertEquals("image/jpeg", ds4.getMimeType());
206        Assert.assertEquals(-1, ds4.getSize());
207        ds4.getContent().close();
208        Assert.assertEquals("http://" + SimpleObjectSource.LOCAL_FEDORA_SERVER
209                        + "/fedora/objects/example:1/datastreams/DS2/content",
210                getFetcher().getLastUrl().toExternalForm());
211        Assert.assertTrue(ds4.getFile().isEmpty());
212    }
213
214    public static class SimpleObjectSource implements ObjectSource {
215
216        private static final String LOCAL_FEDORA_SERVER = "replaced-local-fedora-server";
217
218        private FedoraObjectProcessor p;
219
220        public SimpleObjectSource(final String path, final URLFetcher f,
221                final InternalIDResolver resolver) throws XMLStreamException {
222            try {
223                p = new FoxmlInputStreamFedoraObjectProcessor(new File(path),
224                        f, resolver, LOCAL_FEDORA_SERVER);
225            } catch (FileNotFoundException e) {
226                throw new RuntimeException(e);
227            }
228        }
229
230        @Override
231        public Iterator<FedoraObjectProcessor> iterator() {
232            return Collections.singletonList(p).iterator();
233        }
234    }
235
236    public static class DummyHandler implements StreamingFedoraObjectHandler {
237
238        ObjectInfo objectInfo;
239        ObjectProperties properties;
240        List<DatastreamVersion> dsVersions = new ArrayList<DatastreamVersion>();
241        List<byte[]> cachedDsVersionBinaries = new ArrayList<byte[]>();
242
243        @Override
244        public void beginObject(final ObjectInfo object) {
245            this.objectInfo = object;
246        }
247
248        @Override
249        public void processObjectProperties(final ObjectProperties properties) {
250            this.properties = properties;
251        }
252
253        @Override
254        public void processDatastreamVersion(final DatastreamVersion dsVersion) {
255            dsVersions.add(dsVersion);
256            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
257            try (InputStream content = dsVersion.getContent()) {
258                IOUtils.copy(content, baos);
259                cachedDsVersionBinaries.add(baos.toByteArray());
260            } catch (final IOException e) {
261                throw new RuntimeException(e);
262            }
263
264
265        }
266
267        @Override
268        public void completeObject(final ObjectInfo object) {
269
270        }
271
272        @Override
273        public void abortObject(final ObjectInfo object) {
274
275        }
276    }
277
278    public static class DummyURLFetcher implements URLFetcher {
279
280        private URL lastUrl;
281
282        public URL getLastUrl() {
283            return lastUrl;
284        }
285
286        @Override
287        public InputStream getContentAtUrl(final URL url) throws IOException {
288            lastUrl = url;
289            return new ByteArrayInputStream("DummyURLFetcher".getBytes("UTF-8"));
290        }
291    }
292
293    public static class DummyIDResolver implements InternalIDResolver {
294        @Override
295        public CachedContent resolveInternalID(final String id) {
296            return null;
297        }
298
299        @Override
300        public void close() throws IOException { };
301    }
302
303}