/* * Copyright (C) 2013 Glencoe Software, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package integration.chgrp; import integration.AbstractServerTest; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import org.apache.commons.lang.RandomStringUtils; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import static org.testng.AssertJUnit.*; import ome.specification.XMLMockObjects; import ome.specification.XMLWriter; import ome.xml.model.OME; import omero.RString; import omero.api.IContainerPrx; import omero.api.IMetadataPrx; import omero.api.IUpdatePrx; import omero.cmd.Chgrp2; import omero.cmd.Delete2; import omero.cmd.OK; import omero.cmd.Request; import omero.cmd.Response; import omero.gateway.util.Requests; import omero.model.Arc; import omero.model.Channel; import omero.model.Dataset; import omero.model.DatasetI; import omero.model.DatasetImageLink; import omero.model.DatasetImageLinkI; import omero.model.Detector; import omero.model.ExperimenterGroup; import omero.model.ExperimenterGroupI; import omero.model.Filament; import omero.model.Fileset; import omero.model.FilesetI; import omero.model.Filter; import omero.model.FilterSet; import omero.model.IObject; import omero.model.Image; import omero.model.ImageI; import omero.model.Instrument; import omero.model.Laser; import omero.model.LightSource; import omero.model.LogicalChannel; import omero.model.OTF; import omero.model.Objective; import omero.model.Pixels; import omero.sys.EventContext; import omero.sys.Parameters; import omero.sys.ParametersI; import omero.util.TempFileManager; import omero.gateway.model.ChannelAcquisitionData; import omero.gateway.model.ImageData; import omero.gateway.model.InstrumentData; import omero.gateway.model.LightSourceData; /** */ public class MultiImageFilesetMoveTest extends AbstractServerTest { ExperimenterGroup secondGroup; private IMetadataPrx iMetadata; @BeforeClass public void setupSecondGroup() throws Exception { EventContext ec = iAdmin.getEventContext(); secondGroup = newGroupAddUser("rwrw--", ec.userId); iAdmin.getEventContext(); // Refresh. } static class Fixture { final List<Dataset> datasets; final List<Image> images; Fixture(List<Dataset> datasets, List<Image> images) { this.datasets = datasets; this.images = images; } DatasetImageLink link(IUpdatePrx iUpdate, int datasetIndex, int imageIndex) throws Exception { DatasetImageLink link = new DatasetImageLinkI(); link.setParent((Dataset) datasets.get(datasetIndex).proxy()); link.setChild((Image) images.get(imageIndex).proxy()); link = (DatasetImageLink) iUpdate.saveAndReturnObject(link); return link; } } protected List<Image> importMIF(int seriesCount) throws Throwable { File fake = TempFileManager.create_path("importMIF", String.format("&series=%d.fake", seriesCount)); List<Pixels> pixels = importFile(importer, fake, null, false, null); assertEquals(seriesCount, pixels.size()); List<Image> images = new ArrayList<Image>(); for (Pixels pixel : pixels) { images.add(pixel.getImage()); } return images; } /** * Creates a list of the given number of {@link Dataset} instances with * names of the form "name [1]", "name [2]", etc. and * returns them in a list. * * @param count * @param baseName * @return * @throws Throwable */ @SuppressWarnings({ "unchecked", "rawtypes" }) protected List<Dataset> createDatasets(int count, String baseName) throws Throwable { List<IObject> rv = new ArrayList<IObject>(); for (int i = 0; i < count; i++) { Dataset dataset = new DatasetI(); String suffix = " [" + (i + 1) + "]"; RString name = omero.rtypes.rstring(baseName + suffix); dataset.setName(name); rv.add(dataset); } return (List) iUpdate.saveAndReturnArray(rv); } protected Fixture createFixture(int datasetCount, int imageCount) throws Throwable { List<Dataset> datasets = createDatasets(datasetCount, "MIF"); List<Image> images = importMIF(imageCount); return new Fixture(datasets, images); } /** * Simplest example of the MIF chgrp edge case: a single fileset containing * 2 images is split among 2 datasets. Each sibling CANNOT be moved * independently of the other. */ @Test(groups = {"fs", "integration"}) public void testBasicProblem() throws Throwable { Fixture f = createFixture(2, 2); f.link(iUpdate, 0, 0); f.link(iUpdate, 1, 1); long img0 = f.images.get(0).getId().getValue(); long img1 = f.images.get(1).getId().getValue(); long fs0 = f.images.get(0).getFileset().getId().getValue(); long fs1 = f.images.get(1).getFileset().getId().getValue(); assertEquals(fs0, fs1); final Chgrp2 mv = Requests.chgrp("Image", img0, secondGroup.getId().getValue()); Response rsp = doChange(client, factory, mv, false); // Don't pass // However, it should still be possible to delete the 2 images // and have the fileset cleaned up. List<Long> ids = new ArrayList<Long>(); ids.add(img0); ids.add(img1); Delete2 dc = Requests.delete("Image", ids); callback(true, client, dc); assertDoesNotExist(new FilesetI(fs0, false)); } /** * Creates a MIF images. Moves the fileset. */ @Test(groups = {"fs", "integration"}) public void testMoveFilesetAsRoot() throws Throwable { int imageCount = 2; List<Image> images = importMIF(imageCount); long fs0 = images.get(0).getFileset().getId().getValue(); final Chgrp2 mv = Requests.chgrp("Fileset", fs0, secondGroup.getId().getValue()); Response rsp = doChange(client, factory, mv, true); OK err = (OK) rsp; assertNotNull(err); } /** * Creates a MIF images with acquisition data. Moves the fileSet */ @Test(groups = {"fs", "integration"}) public void testMoveMIFWithAcquisitionData() throws Throwable { int imageCount = 1; Fileset set = new FilesetI(); set.setTemplatePrefix(omero.rtypes.rstring("fake")); List<Long> ids = new ArrayList<Long>(); for (int i = 0; i < imageCount; i++) { File f = File.createTempFile( RandomStringUtils.random(100, false, true),".ome.xml"); f.deleteOnExit(); XMLMockObjects xml = new XMLMockObjects(); XMLWriter writer = new XMLWriter(); OME ome = xml.createImageWithAcquisitionData(); writer.writeFile(f, ome, true); List<Pixels> pixels = null; try { pixels = importFile(f, "ome.xml"); } catch (Throwable e) { throw new Exception("cannot import image", e); } Pixels p = pixels.get(0); ids.add(p.getImage().getId().getValue()); } //Load the image IContainerPrx iContainer = factory.getContainerService(); List<Image> images = iContainer.getImages(Image.class.getName(), ids, new Parameters()); Iterator<Image> j = images.iterator(); while (j.hasNext()) { set.addImage(j.next()); } set = (Fileset) iUpdate.saveAndReturnObject(set); final Chgrp2 mv = Requests.chgrp("Fileset", set.getId().getValue(), secondGroup.getId().getValue()); Response rsp = doChange(client, factory, mv, true); OK err = (OK) rsp; assertNotNull(err); // Reconnect in second group to check group.id for all objects in graph long gid2 = secondGroup.getId().getValue(); loginUser(new ExperimenterGroupI(secondGroup.getId().getValue(), false)); iContainer = factory.getContainerService(); images = iContainer.getImages(Image.class.getName(), ids, new Parameters()); //for each image Iterator<Image> i = images.iterator(); while (i.hasNext()) { Image img = i.next(); assertEquals(img.getDetails().getGroup().getId().getValue(), gid2); Pixels pixels = img.getPrimaryPixels(); long pixId = pixels.getId().getValue(); //method already tested in PixelsServiceTest //make sure objects are loaded. pixels = factory.getPixelsService().retrievePixDescription(pixId); List<Long> lcIds = new ArrayList<Long>(); LogicalChannel lc; Channel channel; for (int i1 = 0; i1 < pixels.getSizeC().getValue(); i1++) { channel = pixels.getChannel(i1); lc = channel.getLogicalChannel(); lcIds.add(lc.getId().getValue()); } iMetadata = factory.getMetadataService(); List<LogicalChannel> channels = iMetadata.loadChannelAcquisitionData( lcIds); assertEquals(channels.size(), pixels.getSizeC().getValue()); LogicalChannel loaded; Iterator<LogicalChannel> lci = channels.iterator(); LightSourceData l; while (lci.hasNext()) { loaded = lci.next(); assertNotNull(loaded); assertEquals(loaded.getDetails().getGroup().getId().getValue(), gid2); ChannelAcquisitionData data = new ChannelAcquisitionData(loaded); assertEquals(data.getDetector().asIObject().getDetails().getGroup().getId().getValue(), gid2); // assertEquals(data.getFilterSet().asIObject().getDetails().getGroup().getId().getValue(), gid2); // getFilterSet() is null l = (LightSourceData) data.getLightSource(); assertEquals(l.asIObject().getDetails().getGroup().getId().getValue(), gid2); assertEquals(loaded.getDetectorSettings().getDetails().getGroup().getId().getValue(), gid2); assertEquals(loaded.getLightSourceSettings().getDetails().getGroup().getId().getValue(), gid2); assertNotNull(loaded.getDetectorSettings().getBinning()); // No Group on Binning assertEquals(loaded.getDetectorSettings().getDetector().getDetails().getGroup().getId().getValue(), gid2); assertNotNull(loaded.getDetectorSettings().getDetector().getType()); assertEquals(loaded.getLightPath().getDetails().getGroup().getId().getValue(), gid2); assertEquals(data.getLightPath().getDichroic().asIObject().getDetails().getGroup().getId().getValue(), gid2); assertNotNull(data.getContrastMethod()); assertNotNull(data.getIllumination()); assertNotNull(data.getMode()); // //OTF support // assertNotNull(loaded.getOtf()); // null // assertNotNull(loaded.getOtf().getFilterSet()); // assertEquals(loaded.getOtf().getObjective().getDetails().getGroup().getId().getValue(), gid2); // assertEquals(loaded.getOtf().getFilterSet().getDetails().getGroup().getId().getValue(), gid2); // assertNotNull(loaded.getOtf().getPixelsType()); } Instrument instrument = iMetadata.loadInstrument( img.getInstrument().getId().getValue()); InstrumentData data = new InstrumentData(instrument); assertEquals(data.asIObject().getDetails().getGroup().getId().getValue(), gid2); assertTrue(instrument.sizeOfDetector() > 0); assertTrue(instrument.sizeOfDichroic() > 0); assertTrue(instrument.sizeOfFilter() > 0); assertTrue(instrument.sizeOfFilterSet() > 0); assertEquals(instrument.sizeOfLightSource(), 5); assertTrue(instrument.sizeOfObjective() > 0); // assertTrue(instrument.sizeOfOtf() > 0); assertEquals(instrument.sizeOfDetector(), data.getDetectors().size()); assertEquals(instrument.sizeOfDichroic(), data.getDichroics().size()); assertEquals(instrument.sizeOfFilter(), data.getFilters().size()); assertEquals(instrument.sizeOfFilterSet(), data.getFilterSets().size()); assertEquals(instrument.sizeOfLightSource(), data.getLightSources().size()); assertEquals(instrument.sizeOfObjective(), data.getObjectives().size()); assertEquals(instrument.sizeOfOtf(), data.getOTF().size()); List<Detector> detectors; List<Filter> filters; List<FilterSet> filterSets; List<Objective> objectives; List<LightSource> lights; List<OTF> otfs; Detector detector; Filter filter; FilterSet fs; Objective objective; OTF otf; LightSource light; Laser laser; Iterator j1; detectors = instrument.copyDetector(); j1 = detectors.iterator(); while (j1.hasNext()) { detector = (Detector) j1.next(); assertEquals(detector.getDetails().getGroup().getId().getValue(), gid2); } filters = instrument.copyFilter(); j1 = filters.iterator(); while (j1.hasNext()) { filter = (Filter) j1.next(); assertEquals(filter.getTransmittanceRange().getDetails().getGroup().getId().getValue(), gid2); } filterSets = instrument.copyFilterSet(); j1 = filterSets.iterator(); while (j1.hasNext()) { fs = (FilterSet) j1.next(); assertEquals(fs.getDetails().getGroup().getId().getValue(), gid2); } objectives = instrument.copyObjective(); j1 = objectives.iterator(); while (j1.hasNext()) { objective = (Objective) j1.next(); assertEquals(objective.getDetails().getGroup().getId().getValue(), gid2); assertNotNull(objective.getCorrection()); assertNotNull(objective.getImmersion()); // assertEquals(objective.getImmersion().getDetails().getGroup().getId().getValue(), gid2); } // otfs = instrument.copyOtf(); // j1 = otfs.iterator(); // while (j1.hasNext()) { // otf = (OTF) j1.next(); // objective = otf.getObjective(); // assertNotNull(otf.getPixelsType()); // assertNotNull(otf.getFilterSet()); // assertNotNull(objective); // assertNotNull(objective.getCorrection()); // assertNotNull(objective.getImmersion()); // } lights = instrument.copyLightSource(); j1 = lights.iterator(); while (j1.hasNext()) { light = (LightSource) j1.next(); if (light instanceof Laser) { laser = (Laser) light; assertNotNull(laser.getType()); assertNotNull(laser.getLaserMedium()); // assertNotNull(laser.getPulse()); } } } } /** * Creates a MIF images and link to a dataset */ @Test(groups = {"fs", "integration"}) public void testMoveDatasetWithMIF() throws Throwable { int imageCount = 2; List<Image> images = importMIF(imageCount); Dataset dataset = new DatasetI(); dataset.setName(omero.rtypes.rstring("testMoveDatasetWithMIF")); dataset = (Dataset) iUpdate.saveAndReturnObject(dataset); Iterator<Image> i = images.iterator(); List<IObject> links = new ArrayList<IObject>(); while (i.hasNext()) { DatasetImageLink link = new DatasetImageLinkI(); link.setChild((Image) i.next().proxy()); link.setParent((Dataset) dataset.proxy()); links.add(link); } long filesetID = images.get(0).getFileset().getId().getValue(); iUpdate.saveAndReturnArray(links); final Chgrp2 dc = Requests.chgrp("Dataset", dataset.getId().getValue(), secondGroup.getId().getValue()); doAllChanges(client, factory, true, dc); loginUser(new ExperimenterGroupI(secondGroup.getId().getValue(), false)); //load the dataset IContainerPrx iContainer = factory.getContainerService(); ParametersI param = new ParametersI(); param.leaves(); List<IObject> values = iContainer.loadContainerHierarchy( Dataset.class.getName(), Arrays.asList(dataset.getId().getValue()), param); assertEquals(1, values.size()); dataset = (Dataset) values.get(0); assertEquals(imageCount, dataset.sizeOfImageLinks()); List<DatasetImageLink> imageLinks = dataset.copyImageLinks(); for (DatasetImageLink link : imageLinks) { Image img = link.getChild(); assertEquals(img.getFileset().getId().getValue(), filesetID); } } }