Java tutorial
/* * $Id$ * * Copyright 2006-2010 University of Dundee. All rights reserved. * Use is subject to license terms supplied in LICENSE.txt */ package integration; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Formatter; import java.util.Iterator; import java.util.List; import java.util.Map; import ome.formats.OMEROMetadataStoreClient; import ome.io.bioformats.BfPyramidPixelBuffer; import ome.io.nio.PixelsService; import omero.ApiUsageException; import omero.ResourceError; import omero.ServerError; import omero.api.RawFileStorePrx; import omero.api.ThumbnailStorePrx; import omero.api.delete.DeleteCommand; import omero.api.delete.DeleteReport; import omero.grid.RepositoryMap; import omero.grid.RepositoryPrx; import omero.model.Dataset; import omero.model.DatasetI; import omero.model.FileAnnotation; import omero.model.FileAnnotationI; import omero.model.IObject; import omero.model.Image; import omero.model.ImageAnnotationLink; import omero.model.ImageAnnotationLinkI; import omero.model.OriginalFile; import omero.model.Pixels; import omero.model.Plate; import omero.model.Well; import omero.sys.EventContext; import omero.sys.ParametersI; import org.apache.commons.io.FilenameUtils; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import pojos.FileAnnotationData; /** * Collections of tests for the <code>Delete</code> service. * * @author Jean-Marie Burel * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Donald MacDonald * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @author Colin Blackburn * <a href="mailto:c.blackburn@dundee.ac.uk">c.blackburn@dundee.ac.uk</a> * @version 3.0 * <small> * (<b>Internal version:</b> $Revision: $Date: $) * </small> * @since 3.0-Beta4 */ @Test(groups = { "delete", "integration" }) public class DeleteServiceFilesTest extends AbstractTest { /** Reference to the <code>Pixels</code> class. */ private static final String REF_PIXELS = "Pixels"; /** Reference to the <code>OriginalFile</code> class. */ private static final String REF_ORIGINAL_FILE = "OriginalFile"; /** Reference to the <code>Thumbnail</code> class. */ private static final String REF_THUMBNAIL = "Thumbnail"; /** Enum representing type of pyramid file */ enum PyramidFileType { PYRAMID, PYRAMID_LOCK, PYRAMID_TMP }; /** Reference to the standard directory. */ private String dataDir; /** * Creates an original file. * * @return See above. * @throws ServerError Thrown if an error occurred. * @throws Exception Thrown if an error occurred. */ private OriginalFile makeFile() throws ServerError, Exception { OriginalFile of = (OriginalFile) iUpdate.saveAndReturnObject(mmFactory.createOriginalFile()); long ofId = of.getId().getValue(); RawFileStorePrx rfPrx = factory.createRawFileStore(); try { rfPrx.setFileId(ofId); rfPrx.write(new byte[] { 1, 2, 3, 4 }, 0, 4); of = rfPrx.save(); } finally { rfPrx.close(); } return of; } /** * Makes an image with pixels files. * * @return See above. * @throws ServerError Thrown if an error occurred. * @throws Exception Thrown if an error occurred. * */ private Image makeImageWithPixelsFile() throws ServerError, Exception { Image img = (Image) iUpdate.saveAndReturnObject(mmFactory.createImage()); Pixels pix = img.getPrimaryPixels(); String path = getPath(REF_PIXELS, pix.getId().getValue()); RepositoryPrx legacy = getLegacyRepository(); legacy.create(path); return img; } /** * Makes an image with pixels files. * * @return See above. * @throws ServerError Thrown if an error occurred. * @throws Exception Thrown if an error occurred. * */ private Image makeImageWithPixelsFile(boolean pixels, boolean pyramid, boolean lock, boolean tmp) throws ServerError, Exception { String path; Image img = (Image) iUpdate.saveAndReturnObject(mmFactory.createImage()); Pixels pix = img.getPrimaryPixels(); RepositoryPrx legacy = getLegacyRepository(); if (pixels) { path = getPath(REF_PIXELS, pix.getId().getValue()); legacy.create(path); } if (pyramid) { path = getOtherPixelsPath(pix.getId().getValue(), PyramidFileType.PYRAMID); legacy.create(path); } if (lock) { path = getOtherPixelsPath(pix.getId().getValue(), PyramidFileType.PYRAMID_LOCK); legacy.create(path); } if (tmp) { path = getOtherPixelsPath(pix.getId().getValue(), PyramidFileType.PYRAMID_TMP); legacy.create(path); } return img; } /** * Checks if thumbnails, files and pixels have not been deleted. * * @param report The report from the delete operation */ private void assertNoUndeletedBinaries(DeleteReport report) { assertNoUndeletedThumbnails(report); assertNoUndeletedFiles(report); assertNoUndeletedPixels(report); } /** * Checks if the thumbnails have been deleted. * * @param report The report from the delete operation */ private void assertNoUndeletedThumbnails(DeleteReport report) { long[] tbIds = report.undeletedFiles.get(REF_THUMBNAIL); assertTrue(Arrays.toString(tbIds), tbIds == null || tbIds.length == 0); } /** * Checks if the files have been deleted. * * @param report The report from the delete operation */ private void assertNoUndeletedFiles(DeleteReport report) { long[] fileIds = report.undeletedFiles.get(REF_ORIGINAL_FILE); assertTrue(Arrays.toString(fileIds), fileIds == null || fileIds.length == 0); } /** * Checks if the pixels have been deleted. * * @param report The report from the delete operation */ private void assertNoUndeletedPixels(DeleteReport report) { long[] pixIds = report.undeletedFiles.get(REF_PIXELS); assertTrue(Arrays.toString(pixIds), pixIds == null || pixIds.length == 0); } /** * Set the data directory for the tests. This is needed to find the * correct repository to test whether deletes have been successful. */ @BeforeClass public void setDataDir() throws Exception { dataDir = root.getSession().getConfigService().getConfigValue("omero.data.dir"); } /** * Since so many tests rely on counting the number of objects present * globally, we're going to start each method with a new user in a new * group. */ @BeforeMethod public void createNewUser() throws Exception { newUserAndGroup("rw----"); iDelete = factory.getDeleteService(); } /** * Since we are creating a new client on each invocation, we should also * clean it up. Note: {@link #newUserAndGroup(String)} also closes, but * not the very last invocation. */ @AfterMethod public void close() throws Exception { if (client == null) { client.__del__(); client = null; } } /** * Basic asynchronous delete command. Used in order to reduce the number * of places that we do the same thing in case the API changes. * * @param dc The SINGLE command to handle. * @throws ApiUsageException * @throws ServerError * @throws InterruptedException */ private DeleteReport deleteWithReport(DeleteCommand dc) throws ApiUsageException, ServerError, InterruptedException { return singleDeleteWithReport(iDelete, client, dc); } /** * Forms a path depending on the type of file to be deleted * and its id. * * @param dataDir The path to the directory * @param klass The type of object to handle. * @param id The identifier of the object. */ private String getPath(String klass, Long id) throws Exception { String suffix = ""; String prefix = ""; Long remaining = id; Long dirno = 0L; if (id == null) { throw new NullPointerException("Expecting a not-null id."); } if (klass.equals(REF_ORIGINAL_FILE)) { prefix = FilenameUtils.concat(dataDir, "Files"); } else if (klass.equals(REF_PIXELS)) { prefix = FilenameUtils.concat(dataDir, "Pixels"); } else if (klass.equals(REF_THUMBNAIL)) { prefix = FilenameUtils.concat(dataDir, "Thumbnails"); } else { throw new Exception("Unknown class: " + klass); } while (remaining > 999) { remaining /= 1000; if (remaining > 0) { Formatter formatter = new Formatter(); dirno = remaining % 1000; suffix = formatter.format("Dir-%03d", dirno).out().toString() + File.separator + suffix; } } String path = FilenameUtils.concat(prefix, suffix + id); return path; } /** * Helper to resolve file names for pyramid-related files */ String getOtherPixelsPath(Long id, PyramidFileType kind) throws Exception { String path = getPath(REF_PIXELS, id); if (kind.equals(PyramidFileType.PYRAMID)) { path += PixelsService.PYRAMID_SUFFIX; } else if (kind.equals(PyramidFileType.PYRAMID_LOCK)) { File file = new File(path); File dir = file.getParentFile(); File lockFile = new File(dir, "." + id + PixelsService.PYRAMID_SUFFIX + BfPyramidPixelBuffer.PYR_LOCK_EXT); path = lockFile.getAbsolutePath(); } else if (kind.equals(PyramidFileType.PYRAMID_TMP)) { File file = new File(path); File dir = file.getParentFile(); File tmpFile = new File(dir, "." + id + PixelsService.PYRAMID_SUFFIX + "1234567890.tmp"); path = tmpFile.getAbsolutePath(); } else { throw new Exception("Unknown kind: " + kind); } return path; } /** * Gets a public repository on the OMERO data directory if one exists. * * @return See above. * @throws Exception Thrown if an error occurred. */ RepositoryPrx getLegacyRepository() throws Exception { RepositoryPrx legacy = null; RepositoryMap rm = factory.sharedResources().repositories(); int repoCount = 0; String s = dataDir; for (OriginalFile desc : rm.descriptions) { String repoPath = desc.getPath().getValue() + desc.getName().getValue(); s += "\nFound repository:" + desc.getPath().getValue() + desc.getName().getValue(); if (FilenameUtils.equals(FilenameUtils.normalizeNoEndSeparator(dataDir), FilenameUtils.normalizeNoEndSeparator(repoPath))) { legacy = rm.proxies.get(repoCount); break; } repoCount++; } if (legacy == null) { throw new Exception("Unable to find legacy repository: " + s); } return legacy; } /** * Makes sure that the OMERO file exists of the given type and id * * @param id The object id corresponding to the filename. * @param klass The class (table name) of the object. * @throws Exception Thrown if an error occurred. */ void assertFileExists(Long id, String klass) throws Exception { String path = getPath(klass, id); RepositoryPrx legacy = getLegacyRepository(); assertTrue(path + " does not exist!", legacy.fileExists(path)); } /** * Makes sure that the OMERO file exists of the given type and id * * @param id The object id corresponding to the filename. * @param klass The class (table name) of the object. * @throws Exception Thrown if an error occurred. */ void assertOtherPixelsFileExists(Long id, PyramidFileType kind) throws Exception { String path = getOtherPixelsPath(id, kind); RepositoryPrx legacy = getLegacyRepository(); assertTrue(path + " does not exist!", legacy.fileExists(path)); } /** * Forcibly delete a file. * * @param id * @param klass * @throws Exception * @see ticket:3140 */ void removeFile(Long id, String klass) throws Exception { String path = getPath(klass, id); RepositoryPrx legacy = getLegacyRepository(); legacy.delete(path); } /** * Makes sure that the OMERO file exists of the given type and id * * @param id The object id corresponding to the filename. * @param klass The class (table name) of the object. * @throws Exception Thrown if an error occurred. */ void assertFileDoesNotExist(Long id, String klass) throws Exception { String path = getPath(klass, id); RepositoryPrx legacy = getLegacyRepository(); assertFalse(path + " exists!", legacy.fileExists(path)); } /** * Makes sure that the OMERO file exists of the given type and id * * @param id The object id corresponding to the filename. * @param klass The class (table name) of the object. * @throws Exception Thrown if an error occurred. */ void assertOtherPixelsFileDoesNotExist(Long id, PyramidFileType kind) throws Exception { String path = getOtherPixelsPath(id, kind); RepositoryPrx legacy = getLegacyRepository(); assertFalse(path, legacy.fileExists(path)); } /** * Test to delete an image and make sure pixels file is deleted. * @throws Exception Thrown if an error occurred. */ @Test(groups = "ticket:2880") public void testDeleteImageWithPixelsOnDisk() throws Exception { Image img = makeImageWithPixelsFile(); Pixels pix = img.getPrimaryPixels(); //Now check that the files have been created and then deleted. assertFileExists(pix.getId().getValue(), REF_PIXELS); DeleteReport report = deleteWithReport( new DeleteCommand(DeleteServiceTest.REF_IMAGE, img.getId().getValue(), null)); assertFileDoesNotExist(pix.getId().getValue(), REF_PIXELS); assertTrue(report.undeletedFiles.get(REF_PIXELS).length == 0); } /** * Test to delete an image and make sure pyramid file is deleted. * @throws Exception Thrown if an error occurred. */ @Test public void testDeleteImageWithPyramidOnDisk() throws Exception { Image img = makeImageWithPixelsFile(false, true, false, false); Pixels pix = img.getPrimaryPixels(); //Now check that the files have been created and then deleted. assertOtherPixelsFileExists(pix.getId().getValue(), PyramidFileType.PYRAMID); DeleteReport report = deleteWithReport( new DeleteCommand(DeleteServiceTest.REF_IMAGE, img.getId().getValue(), null)); assertOtherPixelsFileDoesNotExist(pix.getId().getValue(), PyramidFileType.PYRAMID); assertTrue(report.undeletedFiles.get(REF_PIXELS).length == 0); } /** * Test to delete an image and make sure pixels and pyramid files are deleted. * @throws Exception Thrown if an error occurred. */ @Test public void testDeleteImageWithPixelsAndPyramidOnDisk() throws Exception { Image img = makeImageWithPixelsFile(true, true, false, false); Pixels pix = img.getPrimaryPixels(); //Now check that the files have been created and then deleted. assertFileExists(pix.getId().getValue(), REF_PIXELS); assertOtherPixelsFileExists(pix.getId().getValue(), PyramidFileType.PYRAMID); DeleteReport report = deleteWithReport( new DeleteCommand(DeleteServiceTest.REF_IMAGE, img.getId().getValue(), null)); assertFileDoesNotExist(pix.getId().getValue(), REF_PIXELS); assertOtherPixelsFileDoesNotExist(pix.getId().getValue(), PyramidFileType.PYRAMID); assertTrue(report.undeletedFiles.get(REF_PIXELS).length == 0); } /** * Test to delete an image and make sure pixels and pyramid files are deleted. * @throws Exception Thrown if an error occurred. */ @Test public void testDeleteImageWithAllPyramidOnDisk() throws Exception { Image img = makeImageWithPixelsFile(false, true, true, true); Pixels pix = img.getPrimaryPixels(); //Now check that the files have been created and then deleted. assertOtherPixelsFileExists(pix.getId().getValue(), PyramidFileType.PYRAMID); assertOtherPixelsFileExists(pix.getId().getValue(), PyramidFileType.PYRAMID_LOCK); assertOtherPixelsFileExists(pix.getId().getValue(), PyramidFileType.PYRAMID_TMP); DeleteReport report = deleteWithReport( new DeleteCommand(DeleteServiceTest.REF_IMAGE, img.getId().getValue(), null)); assertOtherPixelsFileDoesNotExist(pix.getId().getValue(), PyramidFileType.PYRAMID); assertOtherPixelsFileDoesNotExist(pix.getId().getValue(), PyramidFileType.PYRAMID_LOCK); assertOtherPixelsFileDoesNotExist(pix.getId().getValue(), PyramidFileType.PYRAMID_TMP); assertTrue(report.undeletedFiles.get(REF_PIXELS).length == 0); } /** * Test to delete an image and make sure the companion file is deleted. * @throws Exception Thrown if an error occurred. */ @Test(groups = "ticket:2880") public void testDeleteImageWithOriginalFileOnDisk() throws Exception { Image img = (Image) iUpdate.saveAndReturnObject(mmFactory.createImage()); // This creates an attached OriginalFle and a subsequent Files file. // Is there a more concise way to achieve the same thing? cgb OriginalFile of = (OriginalFile) iUpdate.saveAndReturnObject(mmFactory.createOriginalFile()); FileAnnotation fa = new FileAnnotationI(); fa.setNs(omero.rtypes.rstring(FileAnnotationData.COMPANION_FILE_NS)); fa.setFile(of); fa = (FileAnnotation) iUpdate.saveAndReturnObject(fa); ImageAnnotationLink l = new ImageAnnotationLinkI(); l.setChild(fa); l.setParent(img); iUpdate.saveAndReturnObject(l); long ofId = of.getId().getValue(); RawFileStorePrx rfPrx = factory.createRawFileStore(); try { rfPrx.setFileId(ofId); rfPrx.write(new byte[] { 1, 2, 3, 4 }, 0, 4); } finally { rfPrx.close(); } //Now check that the files have been created and then deleted. assertFileExists(ofId, REF_ORIGINAL_FILE); DeleteReport report = deleteWithReport( new DeleteCommand(DeleteServiceTest.REF_IMAGE, img.getId().getValue(), null)); assertFileDoesNotExist(ofId, REF_ORIGINAL_FILE); assertNoUndeletedBinaries(report); } /** * Test to delete an image with no files associated. * No exceptions should arise if the files don't exist. * @throws Exception Thrown if an error occurred. */ @Test(groups = "ticket:2880") public void testDeleteImageWithoutFilesOnDisk() throws Exception { Image img = (Image) iUpdate.saveAndReturnObject(mmFactory.createImage()); Pixels pixels = img.getPrimaryPixels(); long pixId = pixels.getId().getValue(); OriginalFile of = (OriginalFile) iUpdate.saveAndReturnObject(mmFactory.createOriginalFile()); FileAnnotation fa = new FileAnnotationI(); fa.setNs(omero.rtypes.rstring(FileAnnotationData.COMPANION_FILE_NS)); fa.setFile(of); fa = (FileAnnotation) iUpdate.saveAndReturnObject(fa); ImageAnnotationLink l = new ImageAnnotationLinkI(); l.setChild(fa); l.setParent(img); iUpdate.saveAndReturnObject(l); long ofId = of.getId().getValue(); //Now check that the files have NOT been created and then deleted. assertFileDoesNotExist(pixId, REF_PIXELS); assertFileDoesNotExist(ofId, REF_ORIGINAL_FILE); DeleteReport report = deleteWithReport( new DeleteCommand(DeleteServiceTest.REF_IMAGE, img.getId().getValue(), null)); assertNoUndeletedBinaries(report); } /** * Test to delete an image and make sure the thumbnail on disk is deleted. * @throws Exception Thrown if an error occurred. */ @Test(groups = "ticket:2880") public void testDeleteImageWithThumbnailOnDisk() throws Exception { File f = File.createTempFile("testDeleteImageWithThumbnailOnDisk" + ModelMockFactory.FORMATS[0], "." + ModelMockFactory.FORMATS[0]); mmFactory.createImageFile(f, ModelMockFactory.FORMATS[0]); OMEROMetadataStoreClient importer = new OMEROMetadataStoreClient(); importer.initialize(factory); List<Pixels> list; try { list = importFile(importer, f, ModelMockFactory.FORMATS[0], false); } catch (Throwable e) { throw new Exception("cannot import image", e); } Pixels pixels = list.get(0); long id = pixels.getId().getValue(); List<Long> ids = new ArrayList<Long>(); ids.add(id); long imageID = pixels.getImage().getId().getValue(); ThumbnailStorePrx svc = factory.createThumbnailStore(); //make sure we have a thumbnail on disk //request a different size to make sure all thumbnails are deleted. Map<Long, byte[]> thumbnails = svc.getThumbnailSet(omero.rtypes.rint(40), omero.rtypes.rint(40), ids); byte[] values = thumbnails.get(id); assertNotNull(values); assertTrue(values.length > 0); String sql = "select i from Thumbnail i where i.pixels.id = :id"; ParametersI param = new ParametersI(); param.addId(id); List<IObject> objects = iQuery.findAllByQuery(sql, param); assertNotNull(objects); assertTrue(objects.size() > 0); List<Long> thumbIds = new ArrayList<Long>(); Iterator<IObject> i = objects.iterator(); long thumbId; while (i.hasNext()) { thumbId = i.next().getId().getValue(); assertFileExists(thumbId, REF_THUMBNAIL); } //delete the image. DeleteReport report = deleteWithReport(new DeleteCommand(DeleteServiceTest.REF_IMAGE, imageID, null)); assertNoUndeletedBinaries(report); assertFileDoesNotExist(id, "Pixels"); Iterator<Long> j = thumbIds.iterator(); while (j.hasNext()) { assertFileDoesNotExist(j.next(), REF_THUMBNAIL); } } /** * Test to delete an image and make sure the thumbnail on disk is deleted. * The image has been viewed another member of the group. * * @throws Exception Thrown if an error occurred. */ @Test public void testDeleteImageViewedByOtherWithThumbnailOnDiskRWRW() throws Exception { EventContext ownerCtx = newUserAndGroup("rwrw--"); File f = File.createTempFile("testDeleteImageWithThumbnailOnDisk" + ModelMockFactory.FORMATS[0], "." + ModelMockFactory.FORMATS[0]); mmFactory.createImageFile(f, ModelMockFactory.FORMATS[0]); OMEROMetadataStoreClient importer = new OMEROMetadataStoreClient(); importer.initialize(factory); List<Pixels> list; try { list = importFile(importer, f, ModelMockFactory.FORMATS[0], false); } catch (Throwable e) { throw new Exception("cannot import image", e); } Pixels pixels = list.get(0); long id = pixels.getId().getValue(); List<Long> ids = new ArrayList<Long>(); ids.add(id); long imageID = pixels.getImage().getId().getValue(); ThumbnailStorePrx svc = factory.createThumbnailStore(); //make sure we have a thumbnail on disk //request a different size to make sure all thumbnails are deleted. int sizeX = 96; int sizeY = 96; Map<Long, byte[]> thumbnails = svc.getThumbnailSet(omero.rtypes.rint(sizeX), omero.rtypes.rint(sizeY), ids); assertNotNull(thumbnails.get(id)); String sql = "select i from Thumbnail i where i.pixels.id = :id"; ParametersI param = new ParametersI(); param.addId(id); List<IObject> objects = iQuery.findAllByQuery(sql, param); assertNotNull(objects); assertTrue(objects.size() > 0); List<Long> thumbIds = new ArrayList<Long>(); Iterator<IObject> i = objects.iterator(); while (i.hasNext()) { thumbIds.add(i.next().getId().getValue()); } newUserInGroup(ownerCtx); svc = factory.createThumbnailStore(); thumbnails = svc.getThumbnailSet(omero.rtypes.rint(sizeX), omero.rtypes.rint(sizeY), ids); assertNotNull(thumbnails.get(id)); objects = iQuery.findAllByQuery(sql, param); assertTrue(objects.size() > 0); i = objects.iterator(); long thumbId; while (i.hasNext()) { thumbId = i.next().getId().getValue(); if (!thumbIds.contains(thumbId)) thumbIds.add(thumbId); } disconnect(); loginUser(ownerCtx); //Now try to delete the image. DeleteReport report = deleteWithReport(new DeleteCommand(DeleteServiceTest.REF_IMAGE, imageID, null)); Iterator<Long> j = thumbIds.iterator(); while (j.hasNext()) { assertFileDoesNotExist(j.next(), REF_THUMBNAIL); } assertNoUndeletedBinaries(report); } /** * Test to delete a dataset containing and image that is * also in another dataset. The Image and its Pixels file * should NOT be deleted. * * @throws Exception Thrown if an error occurred. */ @Test(groups = "ticket:3031") public void testDeletingDatasetWithPixelsFiles() throws Exception { Dataset ds1 = new DatasetI(); ds1.setName(omero.rtypes.rstring("#3031.1")); Dataset ds2 = new DatasetI(); ds2.setName(omero.rtypes.rstring("#3031.2")); Image img = makeImageWithPixelsFile(); Pixels pix = img.getPrimaryPixels(); //Now check that the files have been created and then deleted. assertFileExists(pix.getId().getValue(), REF_PIXELS); ds1.linkImage(img); ds1 = (Dataset) iUpdate.saveAndReturnObject(ds1); ds2.linkImage(img); ds2 = (Dataset) iUpdate.saveAndReturnObject(ds2); delete(client, new DeleteCommand(DeleteServiceTest.REF_DATASET, ds2.getId().getValue(), null)); assertDoesNotExist(ds2); assertExists(ds1); assertExists(img); assertFileExists(pix.getId().getValue(), REF_PIXELS); } /** * Test to delete a dataset containing multiple images * all Pixels files should be deleted. * * @throws Exception Thrown if an error occurred. */ @Test(groups = "ticket:3130") public void testDeletingDatasetWithSeveralPixelsFiles() throws Exception { Dataset ds = new DatasetI(); ds.setName(omero.rtypes.rstring("#3130")); Image img1 = makeImageWithPixelsFile(); Pixels pix1 = img1.getPrimaryPixels(); // A second Image Image img2 = makeImageWithPixelsFile(); Pixels pix2 = img2.getPrimaryPixels(); // link to dataset ds.linkImage(img1); ds = (Dataset) iUpdate.saveAndReturnObject(ds); ds.linkImage(img2); ds = (Dataset) iUpdate.saveAndReturnObject(ds); //Now check that the files have been created and then deleted. assertFileExists(pix1.getId().getValue(), REF_PIXELS); assertFileExists(pix2.getId().getValue(), REF_PIXELS); DeleteReport report = deleteWithReport( new DeleteCommand(DeleteServiceTest.REF_DATASET, ds.getId().getValue(), null)); assertNoUndeletedBinaries(report); assertNoneExist(ds, img1, img2, pix1, pix2); assertFileDoesNotExist(pix1.getId().getValue(), REF_PIXELS); assertFileDoesNotExist(pix2.getId().getValue(), REF_PIXELS); } /** * Test to delete a dataset containing multiple images * all Pixels files should be deleted. * * @throws Exception Thrown if an error occurred. */ @Test(groups = "ticket:3148") public void testDeletingImageWithSeveralOriginalFiles() throws Exception { Image img = (Image) iUpdate.saveAndReturnObject(mmFactory.createImage()).proxy(); // This creates an attached OriginalFle and a subsequent Files file. // Is there a more concise way to achieve the same thing? cgb OriginalFile of1 = makeFile(); FileAnnotation fa = new FileAnnotationI(); fa.setNs(omero.rtypes.rstring(FileAnnotationData.COMPANION_FILE_NS)); fa.setFile(of1); fa = (FileAnnotation) iUpdate.saveAndReturnObject(fa); ImageAnnotationLink l = new ImageAnnotationLinkI(); l.setChild(fa); l.setParent(img); iUpdate.saveAndReturnObject(l); OriginalFile of2 = makeFile(); fa = new FileAnnotationI(); fa.setNs(omero.rtypes.rstring(FileAnnotationData.COMPANION_FILE_NS)); fa.setFile(of2); fa = (FileAnnotation) iUpdate.saveAndReturnObject(fa); l = new ImageAnnotationLinkI(); l.setChild(fa); l.setParent(img); iUpdate.saveAndReturnObject(l); //Now check that the files have been created and then deleted. assertFileExists(of1.getId().getValue(), REF_ORIGINAL_FILE); assertFileExists(of2.getId().getValue(), REF_ORIGINAL_FILE); DeleteReport report = deleteWithReport( new DeleteCommand(DeleteServiceTest.REF_IMAGE, img.getId().getValue(), null)); assertNoneExist(img, of1, of2); assertFileDoesNotExist(of1.getId().getValue(), REF_ORIGINAL_FILE); assertFileDoesNotExist(of2.getId().getValue(), REF_ORIGINAL_FILE); assertNoUndeletedBinaries(report); } /** * Test to delete a dataset containing and image that is * from a Well. The Image and its Pixels file * should NOT be deleted. * * @throws Exception Thrown if an error occurred. */ @Test(groups = "ticket:2946") public void testDeleteDatasetThatContainsImageFromAWell() throws Exception { Image img = makeImageWithPixelsFile(); Pixels pix = img.getPrimaryPixels(); Plate p = (Plate) iUpdate.saveAndReturnObject(mmFactory.createPlate(1, 1, 1, 0, false)); List<Well> wells = loadWells(p.getId().getValue(), false); wells.get(0).copyWellSamples().get(0).setImage(img); Well well = (Well) iUpdate.saveAndReturnObject(wells.get(0)); Dataset ds = new DatasetI(); ds.setName(omero.rtypes.rstring("#2946")); // link to dataset ds.linkImage(img); ds = (Dataset) iUpdate.saveAndReturnObject(ds); //Now check that the file has been created. assertFileExists(pix.getId().getValue(), REF_PIXELS); DeleteReport report = deleteWithReport( new DeleteCommand(DeleteServiceTest.REF_DATASET, ds.getId().getValue(), null)); //The dataset should be gone but nothing else. assertNoneExist(ds); assertAllExist(p, well, img, pix); assertFileExists(pix.getId().getValue(), REF_PIXELS); assertNoUndeletedBinaries(report); } /** * Test to try to delete an image owned by another user in a collaborative * group i.e. RWR--- * @throws Exception Thrown if an error occurred. */ @Test(groups = "ticket:2946") public void testDeleteImagePixelsFileOwnedByOtherRWR() throws Exception { // set up collaborative group and one user, "the owner" newUserAndGroup("rwr---"); Image img = makeImageWithPixelsFile(); Pixels pix = img.getPrimaryPixels(); //Now check that the file has been created. assertFileExists(pix.getId().getValue(), REF_PIXELS); // create another user and try to delete the image newUserInGroup(); DeleteReport report = deleteWithReport( new DeleteCommand(DeleteServiceTest.REF_IMAGE, img.getId().getValue(), null)); // check the image exists as the owner assertExists(img); //Now check that the file has not been deleted. assertFileExists(pix.getId().getValue(), REF_PIXELS); assertNoUndeletedBinaries(report); } /** * Test to remove a file and try to save it using the RawFileStore. * @throws Exception Thrown if an error occurred. */ @Test(groups = "ticket:3140", expectedExceptions = ResourceError.class) public void testSaveThrowsResourceErrorIfDeleted() throws Exception { OriginalFile of = makeFile(); RawFileStorePrx rfs = factory.createRawFileStore(); try { rfs.setFileId(of.getId().getValue()); rfs.write(new byte[1], 0, 1); removeFile(of.getId().getValue(), "OriginalFile"); rfs.save(); fail("Should not reach here."); } finally { rfs.close(); } } /** * Test to check the <code>close</code> method of the RawFileStore * after the file has been deleted. * @throws Exception Thrown if an error occurred. */ @Test(groups = "ticket:3140", expectedExceptions = ResourceError.class) public void testCloseThrowsResourceErrorIfDeleted() throws Exception { OriginalFile of = makeFile(); RawFileStorePrx rfs = factory.createRawFileStore(); try { rfs.setFileId(of.getId().getValue()); rfs.write(new byte[1], 0, 1); removeFile(of.getId().getValue(), "OriginalFile"); fail("Should not reach here."); } finally { rfs.close(); } } }