diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java index 6432556f4ad93d7b9ec4cec718c04b45d82bd234..41048b849a40b370cf9b5a2adda2629eed4799f4 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java @@ -164,6 +164,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifierFactory; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.translator.DataSetTranslator; @@ -1576,6 +1577,8 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements List<NewSample> newSamples = operationDetails.getSampleRegistrations(); List<NewSample> containerSamples = new ArrayList<NewSample>(); List<NewSample> containedSamples = new ArrayList<NewSample>(); + List<NewSample> instanceSamples = new ArrayList<NewSample>(); + List<NewSample> spaceSamples = new ArrayList<NewSample>(); int index = 0; for (NewSample newSample : newSamples) { @@ -1586,9 +1589,19 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements { containedSamples.add(newSample); } + SampleIdentifier sampleIdentifier = SampleIdentifierFactory.parse(newSample); + if (sampleIdentifier.isDatabaseInstanceLevel()) + { + instanceSamples.add(newSample); + } else + { + spaceSamples.add(newSample); + } progress.update("createSamples", newSamples.size(), ++index); } + assertInstanceSampleCreationAllowed(session, instanceSamples); + assertSpaceSampleCreationAllowed(session, spaceSamples); String userIdOrNull = operationDetails.tryUserIdOrNull(); ArrayList<SamplePE> samplePEsCreated = new ArrayList<SamplePE>(); // in the first pass register samples without container to avoid dependency inversion @@ -1600,6 +1613,23 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements return SampleTranslator.translate(samplePEsCreated, session.getBaseIndexURL()); } + private void assertInstanceSampleCreationAllowed(Session session, + List<NewSample> instanceSamples) + { + if (instanceSamples.isEmpty() == false) + { + entityOperationChecker.assertInstanceSampleCreationAllowed(session, instanceSamples); + } + } + + private void assertSpaceSampleCreationAllowed(Session session, List<NewSample> spaceSamples) + { + if (spaceSamples.isEmpty() == false) + { + entityOperationChecker.assertSpaceSampleCreationAllowed(session, spaceSamples); + } + } + private List<Sample> updateSamples(Session session, AtomicEntityOperationDetails operationDetails, IProgressListener progress) { @@ -1608,12 +1638,44 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements { return Collections.emptyList(); } + List<SampleUpdatesDTO> instanceSamples = new ArrayList<SampleUpdatesDTO>(); + List<SampleUpdatesDTO> spaceSamples = new ArrayList<SampleUpdatesDTO>(); + for (SampleUpdatesDTO sampleUpdate : sampleUpdates) + { + SampleIdentifier sampleIdentifier = sampleUpdate.getSampleIdentifier(); + if (sampleIdentifier.isDatabaseInstanceLevel()) + { + instanceSamples.add(sampleUpdate); + } else + { + spaceSamples.add(sampleUpdate); + } + } + assertInstanceSampleUpdateAllowed(session, instanceSamples); + assertSpaceSampleUpdateAllowed(session, spaceSamples); ISampleTable sampleTable = businessObjectFactory.createSampleTable(session); BatchOperationExecutor.executeInBatches(new SampleUpdate(sampleTable, sampleUpdates), progress, "updateSamples"); return SampleTranslator.translate(sampleTable.getSamples(), session.getBaseIndexURL()); } + private void assertInstanceSampleUpdateAllowed(Session session, + List<SampleUpdatesDTO> instanceSamples) + { + if (instanceSamples.isEmpty() == false) + { + entityOperationChecker.assertInstanceSampleUpdateAllowed(session, instanceSamples); + } + } + + private void assertSpaceSampleUpdateAllowed(Session session, List<SampleUpdatesDTO> spaceSamples) + { + if (spaceSamples.isEmpty() == false) + { + entityOperationChecker.assertSpaceSampleUpdateAllowed(session, spaceSamples); + } + } + /** * This method topologically sorts the data sets to be created and creates them in the necessary * order @@ -1624,7 +1686,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements ArrayList<DataPE> dataSetsCreated = new ArrayList<DataPE>(); List<? extends NewExternalData> dataSetRegistrations = operationDetails.getDataSetRegistrations(); - + assertDataSetCreationAllowed(session, dataSetRegistrations); NewExternalDataDAG dag = new NewExternalDataDAG(dataSetRegistrations); List<? extends NewExternalData> orderedRegistrations = dag.getOrderedRegistrations(); @@ -1637,6 +1699,15 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements return DataSetTranslator.translate(dataSetsCreated, "", session.getBaseIndexURL()); } + protected void assertDataSetCreationAllowed(Session session, + List<? extends NewExternalData> dataSets) + { + if (dataSets != null && dataSets.isEmpty() == false) + { + entityOperationChecker.assertDataSetCreationAllowed(session, dataSets); + } + } + private List<ExternalData> updateDataSets(Session session, AtomicEntityOperationDetails operationDetails, IProgressListener progress) { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/EntityOperationChecker.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/EntityOperationChecker.java index 9dfbace7bab91899b67a06854342cb33bf556f28..7a866848daf341d41ac496faaeda7857f355a8f1 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/EntityOperationChecker.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/EntityOperationChecker.java @@ -22,9 +22,11 @@ import java.util.Map; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewProject; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSpace; import ch.systemsx.cisd.openbis.generic.shared.dto.IAuthSession; -import ch.systemsx.cisd.openbis.generic.shared.dto.Session; +import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; +import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO; /** * Implementation of {@link IEntityOperationChecker} which does nothing because checking is done by @@ -47,12 +49,42 @@ public class EntityOperationChecker implements IEntityOperationChecker } @Override - public void assertProjectCreationAllowed(Session session, List<NewProject> newProjects) + public void assertProjectCreationAllowed(IAuthSession session, List<NewProject> newProjects) { } @Override - public void assertExperimentCreationAllowed(Session session, List<NewExperiment> newExperiments) + public void assertExperimentCreationAllowed(IAuthSession session, + List<NewExperiment> newExperiments) + { + } + + @Override + public void assertInstanceSampleCreationAllowed(IAuthSession session, + List<NewSample> instanceSamples) + { + } + + @Override + public void assertSpaceSampleCreationAllowed(IAuthSession session, List<NewSample> spaceSamples) + { + } + + @Override + public void assertInstanceSampleUpdateAllowed(IAuthSession session, + List<SampleUpdatesDTO> instanceSamples) + { + } + + @Override + public void assertSpaceSampleUpdateAllowed(IAuthSession session, + List<SampleUpdatesDTO> spaceSamples) + { + } + + @Override + public void assertDataSetCreationAllowed(IAuthSession session, + List<? extends NewExternalData> dataSets) { } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IEntityOperationChecker.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IEntityOperationChecker.java index 3a0c228b74aecc7ea4f42a7752aaec9fc07f7182..ddf6f929d39bd585c9e89cab8d860fd73a0ae30b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IEntityOperationChecker.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IEntityOperationChecker.java @@ -23,14 +23,19 @@ import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.Authoriz import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.Capability; import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed; import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewExperimentPredicate; +import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewExternalDataPredicate; import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewProjectPredicate; +import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewSamplePredicate; +import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleUpdatesPredicate; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewProject; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSpace; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy; import ch.systemsx.cisd.openbis.generic.shared.dto.IAuthSession; -import ch.systemsx.cisd.openbis.generic.shared.dto.Session; +import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; +import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO; /** * Checking methods to be invoked to check authorization in context of @@ -51,14 +56,45 @@ public interface IEntityOperationChecker @RolesAllowed( { RoleWithHierarchy.SPACE_ADMIN, RoleWithHierarchy.SPACE_ETL_SERVER }) @Capability("CREATE_PROJECTS_VIA_DSS") - public void assertProjectCreationAllowed(Session session, + public void assertProjectCreationAllowed(IAuthSession session, @AuthorizationGuard(guardClass = NewProjectPredicate.class) List<NewProject> newProjects); @RolesAllowed( { RoleWithHierarchy.SPACE_ADMIN, RoleWithHierarchy.SPACE_ETL_SERVER }) - @Capability("CREATE_PROJECTS_VIA_DSS") - public void assertExperimentCreationAllowed(Session session, + @Capability("CREATE_EXPERIMENTS_VIA_DSS") + public void assertExperimentCreationAllowed(IAuthSession session, @AuthorizationGuard(guardClass = NewExperimentPredicate.class) List<NewExperiment> newExperiments); + + @RolesAllowed(RoleWithHierarchy.INSTANCE_ETL_SERVER) + public void assertInstanceSampleCreationAllowed(IAuthSession session, + @AuthorizationGuard(guardClass = NewSamplePredicate.class) + List<NewSample> instanceSamples); + + @RolesAllowed( + { RoleWithHierarchy.SPACE_USER, RoleWithHierarchy.SPACE_ETL_SERVER }) + @Capability("CREATE_SPACE_SAMPLES_VIA_DSS") + public void assertSpaceSampleCreationAllowed(IAuthSession session, + @AuthorizationGuard(guardClass = NewSamplePredicate.class) + List<NewSample> spaceSamples); + + @RolesAllowed(RoleWithHierarchy.INSTANCE_ETL_SERVER) + public void assertInstanceSampleUpdateAllowed(IAuthSession session, + @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class) + List<SampleUpdatesDTO> instanceSamples); + + @RolesAllowed( + { RoleWithHierarchy.SPACE_USER, RoleWithHierarchy.SPACE_ETL_SERVER }) + @Capability("UPDATE_SPACE_SAMPLES_VIA_DSS") + public void assertSpaceSampleUpdateAllowed(IAuthSession session, + @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class) + List<SampleUpdatesDTO> spaceSamples); + + @RolesAllowed( + { RoleWithHierarchy.SPACE_USER, RoleWithHierarchy.SPACE_ETL_SERVER }) + @Capability("CREATE_DATA_SET_VIA_DSS") + public void assertDataSetCreationAllowed(IAuthSession session, + @AuthorizationGuard(guardClass = NewExternalDataPredicate.class) + List<? extends NewExternalData> dataSets); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicate.java index 51c016ef0036db30cc6492c2dfe76cdb9105949d..b2a2f02bb16f7567113427f7778d2dfaa778b5c2 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicate.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicate.java @@ -37,8 +37,8 @@ public class DataSetCodePredicate extends AbstractSpacePredicate<String> } @Override - protected - Status doEvaluation(PersonPE person, List<RoleWithIdentifier> allowedRoles, String dataSetCode) + protected Status doEvaluation(PersonPE person, List<RoleWithIdentifier> allowedRoles, + String dataSetCode) { assert initialized : "Predicate has not been initialized"; @@ -48,10 +48,8 @@ public class DataSetCodePredicate extends AbstractSpacePredicate<String> { String dbInstanceUUID = accessData.getDatabaseInstanceUuid(); String dbInstanceCode = accessData.getDatabaseInstanceCode(); - String groupCode = accessData.getSpaceCode(); - Status result = - evaluate(person, allowedRoles, dbInstanceUUID, dbInstanceCode, groupCode); - return result; + String spaceCode = accessData.getSpaceCode(); + return evaluate(person, allowedRoles, dbInstanceUUID, dbInstanceCode, spaceCode); } return Status.OK; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/NewExternalDataPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/NewExternalDataPredicate.java new file mode 100644 index 0000000000000000000000000000000000000000..214854a5c21e5c2769ed8321de4ecc2552eb5de5 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/NewExternalDataPredicate.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.shared.authorization.predicate; + +import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; + +/** + * Predicate for {@link NewExternalData} instances. + * + * @author Franz-Josef Elmer + */ +public class NewExternalDataPredicate extends DelegatedPredicate<String, NewExternalData> +{ + public NewExternalDataPredicate() + { + super(new DataSetCodePredicate()); + } + + @Override + public String getCandidateDescription() + { + return "new data set"; + } + + @Override + public String tryConvert(NewExternalData value) + { + return value.getCode(); + } + +} diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/EntityOperationTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/EntityOperationTest.java index c662eb4f6716c86de68b7ea0b900f89e9b09794a..005a2cc465aeb59445284e175ad9608e32a4ad12 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/EntityOperationTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/EntityOperationTest.java @@ -30,6 +30,7 @@ import org.testng.annotations.Test; import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException; import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSet; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; @@ -39,14 +40,20 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewProject; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSpace; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.DataSetBuilder; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.DataStoreBuilder; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.ExperimentBuilder; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.MaterialBuilder; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.SampleBuilder; import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails; import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationResult; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUpdatesDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier; import ch.systemsx.cisd.openbis.generic.shared.translator.MaterialTranslator; @@ -87,7 +94,7 @@ public class EntityOperationTest extends SystemTestCase private final List<SampleUpdatesDTO> sampleUpdates = new ArrayList<SampleUpdatesDTO>(); - private final List<? extends NewExternalData> dataSets = new ArrayList<NewExternalData>(); + private final List<NewExternalData> dataSets = new ArrayList<NewExternalData>(); private final List<DataSetUpdatesDTO> dataSetUpdates = new ArrayList<DataSetUpdatesDTO>(); @@ -151,6 +158,45 @@ public class EntityOperationTest extends SystemTestCase return this; } + EntityOperationBuilder sample(Sample sample) + { + NewSample newSample = new NewSample(); + newSample.setIdentifier(sample.getIdentifier()); + newSample.setSampleType(sample.getSampleType()); + Experiment experiment = sample.getExperiment(); + if (experiment != null) + { + newSample.setExperimentIdentifier(experiment.getIdentifier()); + } + newSample.setProperties(sample.getProperties().toArray(new IEntityProperty[0])); + samples.add(newSample); + return this; + } + + EntityOperationBuilder sampleUpdate(Sample sample) + { + sampleUpdates.add(new SampleUpdatesDTO(new TechId(sample), sample.getProperties(), + null, null, sample.getModificationDate(), SampleIdentifierFactory.parse(sample + .getIdentifier()), null, null)); + return this; + } + + EntityOperationBuilder dataSet(DataSet dataSet) + { + NewExternalData newExternalData = new NewExternalData(); + newExternalData.setCode(dataSet.getCode()); + newExternalData.setDataSetType(dataSet.getDataSetType()); + newExternalData.setDataStoreCode(dataSet.getDataStore().getCode()); + Experiment experiment = dataSet.getExperiment(); + if (experiment != null) + { + newExternalData.setExperimentIdentifierOrNull(ExperimentIdentifierFactory + .parse(experiment.getIdentifier())); + } + dataSets.add(newExternalData); + return this; + } + AtomicEntityOperationDetails create() { return new AtomicEntityOperationDetails(registrationID, userID, spaces, projects, @@ -307,6 +353,163 @@ public class EntityOperationTest extends SystemTestCase + SPACE_ETL_SERVER_FOR_B + "' does not have enough privileges.\"."); } + @Test + public void testCreateInstanceSampleAsInstanceETLServerSuccessfully() + { + String sessionToken = authenticateAs(INSTANCE_ETL_SERVER); + AtomicEntityOperationDetails eo = + new EntityOperationBuilder().sample( + new SampleBuilder().identifier("/S1").type("MASTER_PLATE") + .property("$PLATE_GEOMETRY", "96_WELLS_8X12").getSample()).create(); + + AtomicEntityOperationResult result = etlService.performEntityOperations(sessionToken, eo); + + assertEquals("/S1", result.getSamplesCreated().get(0).getIdentifier()); + assertEquals("MASTER_PLATE", result.getSamplesCreated().get(0).getSampleType().getCode()); + assertEquals("[$PLATE_GEOMETRY: 96_WELLS_8X12]", result.getSamplesCreated().get(0) + .getProperties().toString()); + assertEquals(1, result.getSamplesCreated().size()); + } + + @Test + public void testCreateInstanceSampleAsSpaceETLServerThrowsAuthorizationFailure() + { + String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_A); + AtomicEntityOperationDetails eo = + new EntityOperationBuilder().sample( + new SampleBuilder().identifier("/S1").type("MASTER_PLATE") + .property("$PLATE_GEOMETRY", "96_WELLS_8X12").getSample()).create(); + + performFailungEntityOperations(sessionToken, eo, "Authorization failure: ERROR: \"User '" + + SPACE_ETL_SERVER_FOR_A + "' does not have enough privileges " + + "to modify database instance 'CISD'.\"."); + } + + @Test + public void testCreateSpaceSampleAsSpaceETLServerSuccessfully() + { + String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_A); + AtomicEntityOperationDetails eo = + new EntityOperationBuilder().sample( + new SampleBuilder() + .identifier("/CISD/S1") + .type("CELL_PLATE") + .property("COMMENT", "hello") + .experiment( + new ExperimentBuilder().identifier("/CISD/NEMO/EXP1") + .getExperiment()).getSample()).create(); + + AtomicEntityOperationResult result = etlService.performEntityOperations(sessionToken, eo); + + assertEquals("/CISD/S1", result.getSamplesCreated().get(0).getIdentifier()); + assertEquals("CELL_PLATE", result.getSamplesCreated().get(0).getSampleType().getCode()); + assertEquals("[COMMENT: hello]", result.getSamplesCreated().get(0).getProperties() + .toString()); + assertEquals("/CISD/NEMO/EXP1", result.getSamplesCreated().get(0).getExperiment() + .getIdentifier()); + assertEquals(1, result.getSamplesCreated().size()); + } + + @Test + public void testCreateSpaceSampleAsSpaceETLServerThrowsAuthorizationFailure() + { + String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_B); + AtomicEntityOperationDetails eo = + new EntityOperationBuilder().sample( + new SampleBuilder().identifier("/CISD/S1").type("CELL_PLATE").getSample()) + .create(); + + performFailungEntityOperations(sessionToken, eo, "Authorization failure: ERROR: \"User '" + + SPACE_ETL_SERVER_FOR_B + "' does not have enough privileges.\"."); + } + + @Test + public void testUpdateInstanceSampleAsInstanceETLServerSuccessfully() + { + String sessionToken = authenticateAs(INSTANCE_ETL_SERVER); + Sample sample = commonServer.getSampleInfo(systemSessionToken, new TechId(646)).getParent(); + List<IEntityProperty> properties = sample.getProperties(); + assertEquals("[$PLATE_GEOMETRY: 384_WELLS_16X24]", properties.toString()); + sample.setProperties(new SampleBuilder().property("$PLATE_GEOMETRY", "96_WELLS_8X12") + .getSample().getProperties()); + AtomicEntityOperationDetails eo = + new EntityOperationBuilder().sampleUpdate(sample).create(); + + AtomicEntityOperationResult result = etlService.performEntityOperations(sessionToken, eo); + + assertEquals(new Long(646), result.getSamplesUpdated().get(0).getId()); + assertEquals("/MP", result.getSamplesUpdated().get(0).getIdentifier()); + assertEquals("MASTER_PLATE", result.getSamplesUpdated().get(0).getSampleType().getCode()); + assertEquals("[$PLATE_GEOMETRY: 96_WELLS_8X12]", result.getSamplesUpdated().get(0) + .getProperties().toString()); + assertEquals(1, result.getSamplesUpdated().size()); + } + + @Test + public void testUpdateInstanceSampleAsSpaceETLServerThrowsAuthorizationFailure() + { + String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_A); + Sample sample = commonServer.getSampleInfo(systemSessionToken, new TechId(646)).getParent(); + AtomicEntityOperationDetails eo = + new EntityOperationBuilder().sampleUpdate(sample).create(); + + performFailungEntityOperations(sessionToken, eo, "Authorization failure: ERROR: " + + "\"None of method roles '[INSTANCE_ETL_SERVER, INSTANCE_ADMIN]' " + + "could be found in roles of user '" + SPACE_ETL_SERVER_FOR_A + "'.\"."); + } + + @Test + public void testUpdateSpaceSampleAsSpaceETLServerSuccessfully() + { + String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_A); + Sample sample = commonServer.getSampleInfo(systemSessionToken, new TechId(986)).getParent(); + List<IEntityProperty> properties = sample.getProperties(); + assertEquals("[]", properties.toString()); + sample.setProperties(new SampleBuilder().property("COMMENT", "hello").getSample() + .getProperties()); + AtomicEntityOperationDetails eo = + new EntityOperationBuilder().sampleUpdate(sample).create(); + + AtomicEntityOperationResult result = etlService.performEntityOperations(sessionToken, eo); + + assertEquals(new Long(986), result.getSamplesUpdated().get(0).getId()); + assertEquals("/CISD/3VCP5", result.getSamplesUpdated().get(0).getIdentifier()); + assertEquals("CELL_PLATE", result.getSamplesUpdated().get(0).getSampleType().getCode()); + assertEquals("[COMMENT: hello]", result.getSamplesUpdated().get(0).getProperties() + .toString()); + assertEquals(1, result.getSamplesUpdated().size()); + } + + @Test + public void testUpdateSpaceSampleAsSpaceETLServerThrowsAuthorizationFailure() + { + String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_B); + Sample sample = commonServer.getSampleInfo(systemSessionToken, new TechId(986)).getParent(); + AtomicEntityOperationDetails eo = + new EntityOperationBuilder().sampleUpdate(sample).create(); + + performFailungEntityOperations(sessionToken, eo, "Authorization failure: ERROR: \"User '" + + SPACE_ETL_SERVER_FOR_B + "' does not have enough privileges.\"."); + } + + @Test + public void testCreateDataSetAsSpaceETLServerThrowsAuthorizationFailure() + { + String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_B); + AtomicEntityOperationDetails eo = + new EntityOperationBuilder().dataSet( + new DataSetBuilder() + .code("DS-1") + .type("UNKNOWN") + .store(new DataStoreBuilder("STANDARD").getStore()) + .experiment( + new ExperimentBuilder().identifier("/CISD/NEMO/EXP1") + .getExperiment()).getDataSet()).create(); + + performFailungEntityOperations(sessionToken, eo, "Authorization failure: ERROR: \"User '" + + SPACE_ETL_SERVER_FOR_B + "' does not have enough privileges.\"."); + } + private void performFailungEntityOperations(String sessionToken, AtomicEntityOperationDetails eo, String expectedMessage) {