/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is part of dcm4che, an implementation of DICOM(TM) in * Java(TM), hosted at https://github.com/gunterze/dcm4che. * * The Initial Developer of the Original Code is * Agfa Healthcare. * Portions created by the Initial Developer are Copyright (C) 2011 * the Initial Developer. All Rights Reserved. * * Contributor(s): * See @authors listed below * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.dcm4chee.archive.hsm; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.util.Arrays; import java.util.List; import javax.inject.Inject; import org.dcm4chee.archive.entity.Instance; import org.dcm4chee.archive.entity.Location; import org.dcm4chee.archive.hsm.impl.LocationCopyServiceEJB; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; /** * @author Franz Willer <franz.willer@gmail.com> * */ @RunWith(Arquillian.class) public class HsmMoveIT extends HsmITBase { @Inject private LocationCopyServiceEJB ejb; @Deployment public static WebArchive createDeployment() { return createDeployment(HsmMoveIT.class); } @Test public void testMoveStudyOneSeries() throws Exception { store(RESOURCES_STUDY_2_1SERIES, arcAEExt); List<Location> locations = getLocations(FIRST_INSTANCE_STUDY_2); List<Location> onlineRefs = getLocationsOnStorageGroup(TEST_ONLINE); assertEquals("Number of Locations for "+FIRST_INSTANCE_STUDY_2, 1, locations.size()); moveStudy(STUDY_INSTANCE_UID_2, TEST_ONLINE, TEST_NEARLINE_ZIP); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_2, RESOURCES_STUDY_2_1SERIES.length, 1), true, TEST_NEARLINE_ZIP); checkLocationsDeleted(onlineRefs, false); } @Test public void testMoveStudyTwoSeries() throws Exception { store(RESOURCES_STUDY_1_2SERIES, arcAEExt); List<Location> onlineRefs = getLocationsOnStorageGroup(TEST_ONLINE); moveStudy(STUDY_INSTANCE_UID_1, TEST_ONLINE, TEST_NEARLINE_ZIP); waitForFinishedTasks(2, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_1, RESOURCES_STUDY_1_2SERIES.length, 1), true, TEST_NEARLINE_ZIP); checkLocationsDeleted(onlineRefs, true); } @Test public void testMoveStudyOneSeriesToTar() throws Exception { store(RESOURCES_STUDY_2_1SERIES, arcAEExt); List<Location> onlineRefs = getLocationsOnStorageGroup(TEST_ONLINE); moveStudy(STUDY_INSTANCE_UID_2, TEST_ONLINE, TEST_NEARLINE_TAR); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_2, RESOURCES_STUDY_2_1SERIES.length, 1), true, TEST_NEARLINE_TAR); checkLocationsDeleted(onlineRefs, true); } @Test public void testMoveStudyTwoSeriesToFlat() throws Exception { store(RESOURCES_STUDY_1_2SERIES, arcAEExt); List<Location> onlineRefs = getLocationsOnStorageGroup(TEST_ONLINE); moveStudy(STUDY_INSTANCE_UID_1, TEST_ONLINE, TEST_NEARLINE_FLAT); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_1, RESOURCES_STUDY_1_2SERIES.length, 1), true, TEST_NEARLINE_FLAT); checkLocationsDeleted(onlineRefs, true); } @Test public void testMoveStudyTwoSeriesAfterEachSeries() throws Exception { store(Arrays.copyOfRange(RESOURCES_STUDY_1_2SERIES, 0, 3), arcAEExt); List<Location> onlineRefs = getLocationsOnStorageGroup(TEST_ONLINE); moveStudy(STUDY_INSTANCE_UID_1, TEST_ONLINE, TEST_NEARLINE_ZIP); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_1, 3, 1), true, TEST_NEARLINE_ZIP); checkLocationsDeleted(onlineRefs, true); store(Arrays.copyOfRange(RESOURCES_STUDY_1_2SERIES, 3, 5), arcAEExt); checkStorageSystemGroups(checkLocationsOfSeries(SERIES_INSTANCE_UID_1_1, 3, 1), true, TEST_NEARLINE_ZIP); checkStorageSystemGroups(checkLocationsOfSeries(SERIES_INSTANCE_UID_1_2, 2, 1), true, TEST_ONLINE); onlineRefs = getLocationsOnStorageGroup(TEST_ONLINE); moveStudy(STUDY_INSTANCE_UID_1, TEST_ONLINE, TEST_NEARLINE_ZIP); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_1, RESOURCES_STUDY_1_2SERIES.length, 1), true, TEST_NEARLINE_ZIP); checkLocationsDeleted(onlineRefs, true); } @Test public void testMoveStudyTwoSeriesFromZipToFlat() throws Exception { store(RESOURCES_STUDY_1_2SERIES, arcAEExt); List<Location> onlineRefs = getLocationsOnStorageGroup(TEST_ONLINE); assertEquals("ONLINE Refs", 5, onlineRefs.size()); moveStudy(STUDY_INSTANCE_UID_1, TEST_ONLINE, TEST_NEARLINE_ZIP); waitForFinishedTasks(2, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_1, RESOURCES_STUDY_1_2SERIES.length, 1), true, TEST_NEARLINE_ZIP); checkLocationsDeleted(onlineRefs, true); List<Location> zipRefs = getLocationsOnStorageGroup(TEST_NEARLINE_ZIP); moveStudy(STUDY_INSTANCE_UID_1, TEST_NEARLINE_ZIP, TEST_NEARLINE_FLAT); waitForFinishedTasks(2, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_1, RESOURCES_STUDY_1_2SERIES.length, 1), true, TEST_NEARLINE_FLAT); checkLocationsDeleted(zipRefs, true); } @Test public void testMoveStudyKeepSourceContainer() throws Exception { store(RESOURCES_STUDY_2_1SERIES, arcAEExt); List<Location> onlineRefs = getLocationsOnStorageGroup(TEST_ONLINE); assertEquals("ONLINE Refs", 4, onlineRefs.size()); moveStudy(STUDY_INSTANCE_UID_2, TEST_ONLINE, TEST_NEARLINE_ZIP); waitForFinishedTasks(2, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_2, RESOURCES_STUDY_2_1SERIES.length, 1), true, TEST_NEARLINE_ZIP); checkLocationsDeleted(onlineRefs, true); List<Location> zipRefs = getLocationsOnStorageGroup(TEST_NEARLINE_ZIP); String targetName = zipRefs.get(0).getStoragePath()+"_inst"; List<Instance> instances = getInstancesOfStudy(STUDY_INSTANCE_UID_2); LocationCopyContext ctx = new LocationCopyContext(); ctx.setSourceStorageSystemGroupID(TEST_NEARLINE_ZIP); ctx.setTargetStorageSystemGroupID(TEST_NEARLINE_FLAT); ctx.setDeleteSourceLocation(true); ejb.scheduleInstances(ctx, instances.subList(0, 2), targetName, 0); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER); this.checkLocationsOfInstances(instances, 1);//check if sources are still available (container not deleted) moveStudy(STUDY_INSTANCE_UID_2, TEST_NEARLINE_ZIP, TEST_NEARLINE_FLAT); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_2, RESOURCES_STUDY_2_1SERIES.length, 1), true, TEST_NEARLINE_FLAT); checkLocationsDeleted(zipRefs, true); } @Test public void testMoveMovedStudy() throws Exception { store(RESOURCES_STUDY_2_1SERIES, arcAEExt); List<Location> onlineRefs = getLocationsOnStorageGroup(TEST_ONLINE); assertEquals("ONLINE Refs", 4, onlineRefs.size()); moveStudy(STUDY_INSTANCE_UID_2, TEST_ONLINE, TEST_NEARLINE_ZIP); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER+10000); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_2, RESOURCES_STUDY_2_1SERIES.length, 1), true, TEST_NEARLINE_ZIP); checkLocationsDeleted(onlineRefs, true); List<Location> zipRefs = getLocationsOnStorageGroup(TEST_NEARLINE_ZIP); moveStudy(STUDY_INSTANCE_UID_2, TEST_ONLINE, TEST_NEARLINE_ZIP); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER+2000); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_2, RESOURCES_STUDY_2_1SERIES.length, 1), true, TEST_NEARLINE_ZIP); List<Location> zipRefsAfter = getLocationsOnStorageGroup(TEST_NEARLINE_ZIP); assertEquals("ZIP Refs after 2nd move.", zipRefs.size(), zipRefsAfter.size()); loop: for (Location l1 : zipRefsAfter) { for (Location l2: zipRefs) { if (l1.getPk() == l2.getPk()) continue loop; } fail("Locations after 2nd move are different! new Location:"+l1); } } @Test public void testStoreCopyMoveStudy() throws Exception { store(RESOURCES_STUDY_2_1SERIES, arcAEExt); List<Location> onlineRefs = getLocationsOnStorageGroup(TEST_ONLINE); assertEquals("ONLINE Refs", 4, onlineRefs.size()); copyStudy(STUDY_INSTANCE_UID_2, TEST_ONLINE, TEST_NEARLINE_ZIP); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER+10000); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_2, RESOURCES_STUDY_2_1SERIES.length, 2), true, TEST_ONLINE, TEST_NEARLINE_ZIP); List<Location> zipRefs = getLocationsOnStorageGroup(TEST_NEARLINE_ZIP); moveStudy(STUDY_INSTANCE_UID_2, TEST_ONLINE, TEST_NEARLINE_ZIP); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER+2000); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_2, RESOURCES_STUDY_2_1SERIES.length, 1), true, TEST_NEARLINE_ZIP); List<Location> zipRefsAfter = getLocationsOnStorageGroup(TEST_NEARLINE_ZIP); assertEquals("ZIP Refs after move.", zipRefs.size(), zipRefsAfter.size()); loop: for (Location l1 : zipRefsAfter) { for (Location l2: zipRefs) { if (l1.getPk() == l2.getPk()) continue loop; } fail("Locations after move are different! new Location:"+l1); } onlineRefs = getLocationsOnStorageGroup(TEST_ONLINE); assertEquals("ONLINE Refs after move", 0, onlineRefs.size()); } @Test public void testMoveStudyLocationWithTwoInstances() throws Exception { store(RESOURCES_STUDY_2_1SERIES, arcAEExt); List<Location> onlineRefs = getStudyLocationsOnStorageGroup(STUDY_INSTANCE_UID_2, TEST_ONLINE); assertEquals("ONLINE Refs Study 2", RESOURCES_STUDY_2_1SERIES.length, onlineRefs.size()); store(RESOURCES_STUDY_1_2SERIES, arcAEExt); List<Instance> instancesStudy1 = getInstancesOfStudy(STUDY_INSTANCE_UID_1); assertEquals("Instances Study 1", RESOURCES_STUDY_1_2SERIES.length, instancesStudy1.size()); List<Location> onlineRefsTot = getLocationsOnStorageGroup(TEST_ONLINE); assertEquals("ONLINE Refs Study 1 & 2", RESOURCES_STUDY_2_1SERIES.length+RESOURCES_STUDY_1_2SERIES.length, onlineRefsTot.size()); utx.begin(); onlineRefs.get(0).addInstance(instancesStudy1.get(0)); em.merge(onlineRefs.get(0)); em.flush(); utx.commit(); moveStudy(STUDY_INSTANCE_UID_2, TEST_ONLINE, TEST_NEARLINE_ZIP); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER+2000); checkStorageSystemGroups(checkLocationsOfStudy(STUDY_INSTANCE_UID_2, RESOURCES_STUDY_2_1SERIES.length, 1), true, TEST_NEARLINE_ZIP); List<Location> zipRefs = getStudyLocationsOnStorageGroup(STUDY_INSTANCE_UID_2, TEST_NEARLINE_ZIP); assertEquals("ZIP Refs after move.", RESOURCES_STUDY_2_1SERIES.length, zipRefs.size()); List<Location>onlineRefsAfter = getLocationsOnStorageGroup(TEST_ONLINE); assertEquals("ONLINE Refs after move (study 2 + 1 additional Location of first instance of Study 1)", RESOURCES_STUDY_1_2SERIES.length + 1, onlineRefsAfter.size()); } @Test public void testMoveOneOfTwoSeries() throws Exception { store(RESOURCES_STUDY_1_2SERIES, arcAEExt); moveSeries(SERIES_INSTANCE_UID_1_1, TEST_ONLINE, TEST_NEARLINE_ZIP); waitForFinishedTasks(1, DEFAULT_TASK_TIMEOUT, 5, DEFAULT_WAIT_AFTER); checkStorageSystemGroups(checkLocationsOfSeries(SERIES_INSTANCE_UID_1_1, 3, 1), true, TEST_NEARLINE_ZIP); checkStorageSystemGroups(checkLocationsOfSeries(SERIES_INSTANCE_UID_1_2, 2, 1), true, TEST_ONLINE); } }