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 */
016
017package org.fcrepo.migration;
018
019import org.apache.commons.codec.digest.DigestUtils;
020import org.apache.commons.io.FileUtils;
021import org.fcrepo.storage.ocfl.OcflObjectSessionFactory;
022import org.junit.After;
023import org.junit.Test;
024import org.springframework.context.ConfigurableApplicationContext;
025import org.springframework.context.support.ClassPathXmlApplicationContext;
026
027import java.io.IOException;
028import java.io.UncheckedIOException;
029import java.nio.file.Files;
030import java.nio.file.Paths;
031import java.util.Map;
032
033import static org.junit.Assert.assertEquals;
034import static org.junit.Assert.assertTrue;
035import static org.junit.Assert.fail;
036
037/**
038 * @author pwinckles
039 */
040public class InlineXmlIT {
041
042    private static final String OBJECT_ID = "info:fedora/1711.dl:CModelAudioStream";
043    private static final String AUDIT_ID = OBJECT_ID + "/AUDIT";
044    private static final String DC_ID = OBJECT_ID + "/DC";
045    private static final String DS_COMPOSITE_MODEL_ID = OBJECT_ID + "/DS-COMPOSITE-MODEL";
046    private static final String RELS_EXT_ID = OBJECT_ID + "/RELS-EXT";
047
048    private static final Map<String, String> EXPECTED_DIGESTS = Map.of(
049            AUDIT_ID, "c5aa5d74afc74aaf769b685e08d32cbc",
050            DC_ID, "9b3cb6287c11be2eddd3ff0a66805103",
051            DS_COMPOSITE_MODEL_ID, "84184d2d8ee6eae9dbcc5f02eaff681c",
052            RELS_EXT_ID, "c30c3df0877b8f113f8f4f844bdfe3e6"
053    );
054
055    private ConfigurableApplicationContext context;
056    private Migrator migrator;
057    private OcflObjectSessionFactory sessionFactory;
058
059    @After
060    public void tearDown() {
061        if (context != null) {
062            context.close();
063        }
064    }
065
066    private void setup(final String name) throws Exception {
067        // Create directories expected in this test (based on `spring/ocfl-user-it-setup.xml`)
068        final var storage = Paths.get(String.format("target/test/ocfl/%s/storage", name));
069        final var staging = Paths.get(String.format("target/test/ocfl/%s/staging", name));
070
071        if (Files.exists(storage)) {
072            FileUtils.forceDelete(storage.toFile());
073        }
074        if (Files.exists(staging)) {
075            FileUtils.forceDelete(staging.toFile());
076        }
077
078        Files.createDirectories(storage);
079        Files.createDirectories(staging);
080
081        context = new ClassPathXmlApplicationContext(String.format("spring/%s-setup.xml", name));
082        migrator = (Migrator) context.getBean("migrator");
083        sessionFactory = (OcflObjectSessionFactory) context.getBean("ocflSessionFactory");
084    }
085
086    @Test
087    public void testMigrateObjectWithInlineXml() throws Exception {
088        setup("inline-it");
089
090        migrator.run();
091
092        final var session = sessionFactory.newSession(OBJECT_ID);
093
094        EXPECTED_DIGESTS.forEach((id, expected) -> {
095            final var content = session.readContent(id);
096            try {
097                final var actual = DigestUtils.md5Hex(content.getContentStream().get());
098                assertEquals(id, expected, actual);
099            } catch (IOException e) {
100                throw new UncheckedIOException(e);
101            }
102        });
103    }
104
105    @Test
106    public void failMigrationWhenInlineXmlDoesNotMatchDigest() throws Exception {
107        setup("inline-invalid-it");
108
109        try {
110            migrator.run();
111            fail("Expected migrator to fail");
112        } catch (RuntimeException e) {
113            assertTrue(e.getMessage()
114                    .contains("DC failed checksum validation. Expected MD5: 4e2a6140aa1369de6dd9736dfa8ab946"));
115        }
116    }
117
118}