diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/FacadeFactory.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/FacadeFactory.java index 12b08542ac0f6dc46435afc146119855597e3a16..0f119a3f0cdf1fa9df6db19ffddb890f7d3058e6 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/FacadeFactory.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/FacadeFactory.java @@ -17,30 +17,35 @@ package ch.systemsx.cisd.openbis.plugin.phosphonetx.client.api.v1; import ch.systemsx.cisd.common.api.client.ServiceFinder; -import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.api.v1.Constants; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService; import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.IRawDataService; /** * Factory of {@link IRawDataApiFacade}. - * + * * @author Franz-Josef Elmer */ public class FacadeFactory { - private static final ServiceFinder SERVICE_FINDER = new ServiceFinder("openbis", Constants.RAW_DATA_SERVER_URL); + private static final ServiceFinder SERVICE_FINDER = + new ServiceFinder("openbis", IRawDataService.SERVER_URL); + + private static final ServiceFinder GENERIC_INFO_SERVICE_FINDER = + new ServiceFinder("openbis", IGeneralInformationService.SERVICE_URL); /** * Creates a facade for specified server URL, user Id, and password. */ public static IRawDataApiFacade create(String serverURL, String userID, String password) { + IGeneralInformationService infoService = createGenericInfoService(serverURL); IRawDataService service = createService(serverURL); - String sessionToken = service.tryToAuthenticateAtRawDataServer(userID, password); + String sessionToken = infoService.tryToAuthenticateForAllServices(userID, password); if (sessionToken == null) { throw new IllegalArgumentException("User " + userID + " couldn't be authenticated"); } - return new RawDataApiFacade(service, sessionToken); + return new RawDataApiFacade(service, infoService, sessionToken); } /** @@ -48,12 +53,19 @@ public class FacadeFactory */ public static IRawDataApiFacade create(String serverURL, String sessionToken) { - return new RawDataApiFacade(createService(serverURL), sessionToken); + IRawDataService service = createService(serverURL); + IGeneralInformationService infoService = createGenericInfoService(serverURL); + return new RawDataApiFacade(service, infoService, sessionToken); } private static IRawDataService createService(String serverURL) { return SERVICE_FINDER.createService(IRawDataService.class, serverURL); } + + private static IGeneralInformationService createGenericInfoService(String serverURL) + { + return GENERIC_INFO_SERVICE_FINDER.createService(IGeneralInformationService.class, serverURL); + } } diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/IRawDataApiFacade.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/IRawDataApiFacade.java index 91f9a45ff8317c1c53f4c5d8da431366fec64860..b47e523e82afd437faf9259bff3f4e2b9e15cc89 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/IRawDataApiFacade.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/IRawDataApiFacade.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.plugin.phosphonetx.client.api.v1; import java.util.List; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project; import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.dto.DataStoreServerProcessingPluginInfo; import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.dto.MsInjectionDataInfo; @@ -51,6 +52,11 @@ public interface IRawDataApiFacade */ public void processingRawData(String userID, String dataSetProcessingKey, long[] rawDataSampleIDs, String dataSetType); + + /** + * Returns all projects where the specified user has USER access rights. + */ + public List<Project> listProjects(String userID); /** * Logs current user out. diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/RawDataApiFacade.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/RawDataApiFacade.java index 4ef94ccef81c294c87d02647cfb501c2525d425c..29b9631f2a24e29d5772e14df1c9788013632b0b 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/RawDataApiFacade.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/RawDataApiFacade.java @@ -16,8 +16,15 @@ package ch.systemsx.cisd.openbis.plugin.phosphonetx.client.api.v1; +import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Set; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Role; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SpaceWithProjectsAndRoleAssignments; import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.IRawDataService; import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.dto.DataStoreServerProcessingPluginInfo; import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.dto.MsInjectionDataInfo; @@ -29,12 +36,15 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.dto.MsInjection */ class RawDataApiFacade implements IRawDataApiFacade { + private static final String USER_ROLE_SET = "USER"; private final IRawDataService service; + private final IGeneralInformationService generalInfoService; private final String sessionToken; - RawDataApiFacade(IRawDataService service, String sessionToken) + RawDataApiFacade(IRawDataService service, IGeneralInformationService generalInfoService, String sessionToken) { this.service = service; + this.generalInfoService = generalInfoService; this.sessionToken = sessionToken; } @@ -60,9 +70,37 @@ class RawDataApiFacade implements IRawDataApiFacade dataSetType); } + public List<Project> listProjects(String userID) + { + Map<String, Set<Role>> namedRoleSets = generalInfoService.listNamedRoleSets(sessionToken); + Set<Role> allowedRoles = namedRoleSets.get(USER_ROLE_SET); + if (allowedRoles == null) + { + throw new IllegalStateException("Role set " + USER_ROLE_SET + " not known."); + } + + List<SpaceWithProjectsAndRoleAssignments> spaces = + generalInfoService.listSpacesWithProjectsAndRoleAssignments(sessionToken, null); + List<Project> projects = new ArrayList<Project>(); + for (SpaceWithProjectsAndRoleAssignments space : spaces) + { + Set<Role> roles = space.getRoles(userID); + roles.retainAll(allowedRoles); + if (roles.isEmpty() == false) + { + for (ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project project : space + .getProjects()) + { + projects.add(new Project(space.getCode(), project.getCode())); + } + } + } + return projects; + } + public void logout() { - service.logout(sessionToken); + generalInfoService.logout(sessionToken); } } diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/RawDataApiTest.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/RawDataApiTest.java index 8ac8fadc944e0c34fce6840146ce80e3c7321e8e..81ccf122bcc5689bbc4f2bc5f883e30d58963446 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/RawDataApiTest.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/RawDataApiTest.java @@ -20,6 +20,7 @@ import java.util.Date; import java.util.List; import java.util.Map; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project; import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.dto.DataStoreServerProcessingPluginInfo; import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.dto.MsInjectionDataInfo; @@ -65,6 +66,13 @@ public class RawDataApiTest System.out.println(" key:" + info.getKey() + ", label:'" + info.getLabel() + "', data set types:" + info.getDatasetTypeCodes()); } + + System.out.println("Projects:"); + List<Project> projects = facade.listProjects(userID); + for (Project project : projects) + { + System.out.println(project); + } facade.logout(); } } diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/Constants.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/Constants.java index afc228880b9ed429f14ee1de82855086abbad536..728de9189d9556bd6784d714f9c2998fe273719f 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/Constants.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/Constants.java @@ -23,7 +23,7 @@ package ch.systemsx.cisd.openbis.plugin.phosphonetx.server.api.v1; */ public class Constants { - public final static String RAW_DATA_SERVER_URL = "/rmi-phosphonetx-raw-data-v1"; + // Spring bean IDs public final static String PHOSPHONETX_RAW_DATA_SERVICE = "phosphonetx-raw-data-service"; public final static String PHOSPHONETX_RAW_DATA_SERVICE_INTERNAL = "phosphonetx-raw-data-service-internal"; diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/RawDataServiceServer.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/RawDataServiceServer.java index d3a1eb303e91612fdb09e892278a70723874324d..5f4def48cff631bbbd34de7ae8af2a018f361133 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/RawDataServiceServer.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/RawDataServiceServer.java @@ -35,7 +35,7 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.IRawDataService */ @Controller @RequestMapping( - { Constants.RAW_DATA_SERVER_URL, "/openbis" + Constants.RAW_DATA_SERVER_URL }) + { IRawDataService.SERVER_URL, "/openbis" + IRawDataService.SERVER_URL }) public class RawDataServiceServer extends HttpInvokerServiceExporter { @Resource(name = Constants.PHOSPHONETX_RAW_DATA_SERVICE) @@ -51,9 +51,11 @@ public class RawDataServiceServer extends HttpInvokerServiceExporter setService(service); setInterceptors(new Object[] { new ServiceExceptionTranslator() }); + int majorVersion = service.getMajorVersion(); + int minorVersion = service.getMinorVersion(); RpcServiceInterfaceVersionDTO ifaceVersion = - new RpcServiceInterfaceVersionDTO("phosphonetx-raw-data", - Constants.RAW_DATA_SERVER_URL, 1, 0); + new RpcServiceInterfaceVersionDTO(IRawDataService.SERVICE_NAME, + IRawDataService.SERVER_URL, majorVersion, minorVersion); nameServer.addSupportedInterfaceVersion(ifaceVersion); super.afterPropertiesSet(); } diff --git a/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/RawDataApiFacadeTest.java b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/RawDataApiFacadeTest.java new file mode 100644 index 0000000000000000000000000000000000000000..df0f329ec33dbefeaafe4d2a136d4d8565a19f18 --- /dev/null +++ b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/api/v1/RawDataApiFacadeTest.java @@ -0,0 +1,204 @@ +/* + * Copyright 2010 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.plugin.phosphonetx.client.api.v1; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.jmock.Expectations; +import org.jmock.Mockery; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Role; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SpaceWithProjectsAndRoleAssignments; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.IRawDataService; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.dto.DataStoreServerProcessingPluginInfo; +import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.dto.MsInjectionDataInfo; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class RawDataApiFacadeTest extends AssertJUnit +{ + private static final String SESSION_TOKEN = "Session-42"; + + private Mockery context; + private IRawDataService rawDataService; + private IGeneralInformationService generalInfoService; + private IRawDataApiFacade facade; + + @BeforeMethod + public void beforeMethod() + { + context = new Mockery(); + rawDataService = context.mock(IRawDataService.class); + generalInfoService = context.mock(IGeneralInformationService.class); + facade = new RawDataApiFacade(rawDataService, generalInfoService, SESSION_TOKEN); + } + + @AfterMethod + public void afterMethod() + { + context.assertIsSatisfied(); + } + + @Test + public void testGetSessionToken() + { + assertEquals(SESSION_TOKEN, facade.getSessionToken()); + + context.assertIsSatisfied(); + } + + @Test + public void testLogout() + { + context.checking(new Expectations() + { + { + one(generalInfoService).logout(SESSION_TOKEN); + } + }); + + facade.logout(); + + context.assertIsSatisfied(); + } + + @Test + public void testListDataStoreServerProcessingPluginInfos() + { + final List<DataStoreServerProcessingPluginInfo> result = + new LinkedList<DataStoreServerProcessingPluginInfo>(); + context.checking(new Expectations() + { + { + one(rawDataService).listDataStoreServerProcessingPluginInfos(SESSION_TOKEN); + will(returnValue(result)); + } + }); + + assertSame(result, facade.listDataStoreServerProcessingPluginInfos()); + context.assertIsSatisfied(); + } + + @Test + public void testListRawDataSamples() + { + final List<MsInjectionDataInfo> result = new LinkedList<MsInjectionDataInfo>(); + context.checking(new Expectations() + { + { + one(rawDataService).listRawDataSamples(SESSION_TOKEN, "user1"); + will(returnValue(result)); + } + }); + + assertSame(result, facade.listRawDataSamples("user1")); + context.assertIsSatisfied(); + } + + @Test + public void testProcessingRawData() + { + context.checking(new Expectations() + { + { + one(rawDataService).processingRawData(SESSION_TOKEN, "user1", "key", + new long[42], "type"); + } + }); + + facade.processingRawData("user1", "key", new long[42], "type"); + + context.assertIsSatisfied(); + } + + @Test + public void testListProjectsButNoUserRoles() + { + context.checking(new Expectations() + { + { + one(generalInfoService).listNamedRoleSets(SESSION_TOKEN); + will(returnValue(new HashMap<String, Set<Role>>())); + } + }); + + try + { + facade.listProjects("user1"); + fail("IllegalStateException expected"); + } catch (IllegalStateException ex) + { + assertEquals("Role set USER not known.", ex.getMessage()); + } + + context.assertIsSatisfied(); + } + + @Test + public void testListProjects() + { + context.checking(new Expectations() + { + { + one(generalInfoService).listNamedRoleSets(SESSION_TOKEN); + HashMap<String, Set<Role>> sets = new HashMap<String, Set<Role>>(); + HashSet<Role> set = new HashSet<Role>(); + set.add(new Role("R1", true)); + set.add(new Role("R2", false)); + sets.put("USER", set); + will(returnValue(sets)); + + one(generalInfoService).listSpacesWithProjectsAndRoleAssignments(SESSION_TOKEN, null); + SpaceWithProjectsAndRoleAssignments a = createSpace("A", "alpha", "beta"); + a.add("user1", new Role("R1", true)); + a.add("user1", new Role("R3", false)); + SpaceWithProjectsAndRoleAssignments b = createSpace("B", "gamma"); + b.add("user1", new Role("R2", true)); + will(returnValue(Arrays.asList(a, b))); + } + }); + + List<Project> projects = facade.listProjects("user1"); + + assertEquals("[/A/alpha, /A/beta]", projects.toString()); + context.assertIsSatisfied(); + } + + private SpaceWithProjectsAndRoleAssignments createSpace(String spaceCode, String... projects) + { + SpaceWithProjectsAndRoleAssignments space = new SpaceWithProjectsAndRoleAssignments(spaceCode); + for (String project : projects) + { + space.add(new Project(spaceCode, project)); + } + return space; + } +}