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; 032import java.io.BufferedReader; 033import java.io.InputStreamReader; 034import java.nio.charset.StandardCharsets; 035import java.util.stream.Collectors; 036import static org.junit.Assert.assertEquals; 037import static org.junit.Assert.assertTrue; 038import static org.junit.Assert.fail; 039 040/** 041 * @author pwinckles 042 */ 043public class InlineXmlIT { 044 045 private static final String OBJECT_ID = "info:fedora/1711.dl:CModelAudioStream"; 046 private static final String AUDIT_ID = OBJECT_ID + "/AUDIT"; 047 private static final String DC_ID = OBJECT_ID + "/DC"; 048 private static final String DS_COMPOSITE_MODEL_ID = OBJECT_ID + "/DS-COMPOSITE-MODEL"; 049 private static final String RELS_EXT_ID = OBJECT_ID + "/RELS-EXT"; 050 051 private static final Map<String, String> EXPECTED_DIGESTS = Map.of( 052 AUDIT_ID, "c5aa5d74afc74aaf769b685e08d32cbc", 053 DC_ID, "9b3cb6287c11be2eddd3ff0a66805103", 054 DS_COMPOSITE_MODEL_ID, "84184d2d8ee6eae9dbcc5f02eaff681c", 055 RELS_EXT_ID, "c30c3df0877b8f113f8f4f844bdfe3e6" 056 ); 057 058 private ConfigurableApplicationContext context; 059 private Migrator migrator; 060 private OcflObjectSessionFactory sessionFactory; 061 062 @After 063 public void tearDown() { 064 if (context != null) { 065 context.close(); 066 } 067 } 068 069 private void setup(final String name) throws Exception { 070 // Create directories expected in this test (based on `spring/ocfl-user-it-setup.xml`) 071 final var storage = Paths.get(String.format("target/test/ocfl/%s/storage", name)); 072 final var staging = Paths.get(String.format("target/test/ocfl/%s/staging", name)); 073 074 if (Files.exists(storage)) { 075 FileUtils.forceDelete(storage.toFile()); 076 } 077 if (Files.exists(staging)) { 078 FileUtils.forceDelete(staging.toFile()); 079 } 080 081 Files.createDirectories(storage); 082 Files.createDirectories(staging); 083 084 context = new ClassPathXmlApplicationContext(String.format("spring/%s-setup.xml", name)); 085 migrator = (Migrator) context.getBean("migrator"); 086 sessionFactory = (OcflObjectSessionFactory) context.getBean("ocflSessionFactory"); 087 } 088 089 @Test 090 public void testDcProperties() throws Exception { 091 setup("inline-it"); 092 migrator.run(); 093 final var session = sessionFactory.newSession("info:fedora/fedora-system:ContentModel-3.0"); 094 final var content = session.readContent("info:fedora/fedora-system:ContentModel-3.0"); 095 final String contentText = new BufferedReader( 096 new InputStreamReader(content.getContentStream().get(), StandardCharsets.UTF_8)) 097 .lines() 098 .collect(Collectors.joining("\n")); 099 assertTrue(contentText.contains("<info:fedora/fedora-system:ContentModel-3.0> " + 100 "<http://purl.org/dc/elements/1.1/identifier> \"fedora-system:ContentModel-3.0\"")); 101 } 102 103 @Test 104 public void testMigrateObjectWithInlineXml() throws Exception { 105 setup("inline-it"); 106 107 migrator.run(); 108 109 final var session = sessionFactory.newSession(OBJECT_ID); 110 111 EXPECTED_DIGESTS.forEach((id, expected) -> { 112 final var content = session.readContent(id); 113 try { 114 final var actual = DigestUtils.md5Hex(content.getContentStream().get()); 115 assertEquals(id, expected, actual); 116 } catch (IOException e) { 117 throw new UncheckedIOException(e); 118 } 119 }); 120 } 121 122 @Test 123 public void failMigrationWhenInlineXmlDoesNotMatchDigest() throws Exception { 124 setup("inline-invalid-it"); 125 126 try { 127 migrator.run(); 128 fail("Expected migrator to fail"); 129 } catch (RuntimeException e) { 130 assertTrue(e.getMessage() 131 .contains("DC failed checksum validation. Expected MD5: 4e2a6140aa1369de6dd9736dfa8ab946")); 132 } 133 } 134 135 136}