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}