From 5ceac6896106f91a7a1aa40d71c791418af3984d Mon Sep 17 00:00:00 2001 From: Sinisa Veseli <sveseli@aps.anl.gov> Date: Mon, 13 Apr 2015 13:30:54 +0000 Subject: [PATCH] add first functional DS web service with user, experiment and auth controllers that allow retrieving user and experiment information from the db, start/stop experiment, and principal authorization; added corresponding API and CLI classes; added storage manager skeleton --- src/python/dm/ds_web_service/__init__.py | 0 src/python/dm/ds_web_service/api/__init__.py | 0 .../dm/ds_web_service/api/authRestApi.py | 35 ++++++++ src/python/dm/ds_web_service/api/dsRestApi.py | 21 +++++ .../dm/ds_web_service/api/dsRestApiFactory.py | 57 ++++++++++++ .../ds_web_service/api/experimentRestApi.py | 83 +++++++++++++++++ .../dm/ds_web_service/api/userRestApi.py | 46 ++++++++++ src/python/dm/ds_web_service/cli/__init__.py | 0 .../dm/ds_web_service/cli/addExperimentCli.py | 48 ++++++++++ .../dm/ds_web_service/cli/dsWebServiceCli.py | 17 ++++ .../cli/dsWebServiceSessionCli.py | 21 +++++ .../dm/ds_web_service/cli/getExperimentCli.py | 43 +++++++++ .../cli/getExperimentTypesCli.py | 27 ++++++ .../ds_web_service/cli/getExperimentsCli.py | 27 ++++++ .../dm/ds_web_service/cli/getUserCli.py | 42 +++++++++ .../dm/ds_web_service/cli/getUsersCli.py | 27 ++++++ .../ds_web_service/cli/startExperimentCli.py | 36 ++++++++ .../ds_web_service/cli/stopExperimentCli.py | 36 ++++++++ .../dm/ds_web_service/service/__init__.py | 0 .../ds_web_service/service/auth/__init__.py | 0 .../service/auth/dsAuthPrincipalRetriever.py | 24 +++++ .../service/authRouteDescriptor.py | 32 +++++++ .../service/authSessionController.py | 22 +++++ .../dm/ds_web_service/service/dsWebService.py | 42 +++++++++ .../service/dsWebServiceRouteMapper.py | 40 +++++++++ .../service/experimentRouteDescriptor.py | 89 +++++++++++++++++++ .../service/experimentSessionController.py | 87 ++++++++++++++++++ .../ds_web_service/service/impl/__init__.py | 0 .../service/impl/authSessionControllerImpl.py | 29 ++++++ .../impl/experimentSessionControllerImpl.py | 49 ++++++++++ .../service/impl/fileSystemControllerImpl.py | 32 +++++++ .../service/impl/storageManager.py | 73 +++++++++++++++ .../impl/userInfoSessionControllerImpl.py | 26 ++++++ .../service/userInfoSessionController.py | 38 ++++++++ .../service/userRouteDescriptor.py | 53 +++++++++++ 35 files changed, 1202 insertions(+) create mode 100644 src/python/dm/ds_web_service/__init__.py create mode 100644 src/python/dm/ds_web_service/api/__init__.py create mode 100755 src/python/dm/ds_web_service/api/authRestApi.py create mode 100755 src/python/dm/ds_web_service/api/dsRestApi.py create mode 100755 src/python/dm/ds_web_service/api/dsRestApiFactory.py create mode 100755 src/python/dm/ds_web_service/api/experimentRestApi.py create mode 100755 src/python/dm/ds_web_service/api/userRestApi.py create mode 100644 src/python/dm/ds_web_service/cli/__init__.py create mode 100755 src/python/dm/ds_web_service/cli/addExperimentCli.py create mode 100755 src/python/dm/ds_web_service/cli/dsWebServiceCli.py create mode 100755 src/python/dm/ds_web_service/cli/dsWebServiceSessionCli.py create mode 100755 src/python/dm/ds_web_service/cli/getExperimentCli.py create mode 100755 src/python/dm/ds_web_service/cli/getExperimentTypesCli.py create mode 100755 src/python/dm/ds_web_service/cli/getExperimentsCli.py create mode 100755 src/python/dm/ds_web_service/cli/getUserCli.py create mode 100755 src/python/dm/ds_web_service/cli/getUsersCli.py create mode 100755 src/python/dm/ds_web_service/cli/startExperimentCli.py create mode 100755 src/python/dm/ds_web_service/cli/stopExperimentCli.py create mode 100644 src/python/dm/ds_web_service/service/__init__.py create mode 100644 src/python/dm/ds_web_service/service/auth/__init__.py create mode 100755 src/python/dm/ds_web_service/service/auth/dsAuthPrincipalRetriever.py create mode 100755 src/python/dm/ds_web_service/service/authRouteDescriptor.py create mode 100755 src/python/dm/ds_web_service/service/authSessionController.py create mode 100755 src/python/dm/ds_web_service/service/dsWebService.py create mode 100755 src/python/dm/ds_web_service/service/dsWebServiceRouteMapper.py create mode 100755 src/python/dm/ds_web_service/service/experimentRouteDescriptor.py create mode 100755 src/python/dm/ds_web_service/service/experimentSessionController.py create mode 100644 src/python/dm/ds_web_service/service/impl/__init__.py create mode 100755 src/python/dm/ds_web_service/service/impl/authSessionControllerImpl.py create mode 100755 src/python/dm/ds_web_service/service/impl/experimentSessionControllerImpl.py create mode 100755 src/python/dm/ds_web_service/service/impl/fileSystemControllerImpl.py create mode 100755 src/python/dm/ds_web_service/service/impl/storageManager.py create mode 100755 src/python/dm/ds_web_service/service/impl/userInfoSessionControllerImpl.py create mode 100755 src/python/dm/ds_web_service/service/userInfoSessionController.py create mode 100755 src/python/dm/ds_web_service/service/userRouteDescriptor.py diff --git a/src/python/dm/ds_web_service/__init__.py b/src/python/dm/ds_web_service/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/python/dm/ds_web_service/api/__init__.py b/src/python/dm/ds_web_service/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/python/dm/ds_web_service/api/authRestApi.py b/src/python/dm/ds_web_service/api/authRestApi.py new file mode 100755 index 00000000..571f9f31 --- /dev/null +++ b/src/python/dm/ds_web_service/api/authRestApi.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +import os +import urllib + +from dm.common.utility.encoder import Encoder +from dm.common.exceptions.dmException import DmException +from dm.common.exceptions.invalidRequest import InvalidRequest +from dm.common.objects.authorizationPrincipal import AuthorizationPrincipal +from dsRestApi import DsRestApi + +class AuthRestApi(DsRestApi): + + def __init__(self, username=None, password=None, host=None, port=None, protocol=None): + DsRestApi.__init__(self, username, password, host, port, protocol) + + @DsRestApi.execute + def getAuthorizationPrincipal(self, username): + if username is None: + raise InvalidRequest('Username must be provided.') + url = '%s/authorizationPrincipals/%s' % (self.getContextRoot(), username) + self.logger.debug('Retrieving principal for user %s' % (username)) + responseData = self.sendSessionRequest(url=url, method='GET') + return AuthorizationPrincipal(responseData) + +####################################################################### +# Testing. + +if __name__ == '__main__': + api = AuthRestApi('dm', 'dm', 'zagreb.svdev.net', 22236, 'http') + print api.authenticateUser('sveseli', 'sv') + + + + diff --git a/src/python/dm/ds_web_service/api/dsRestApi.py b/src/python/dm/ds_web_service/api/dsRestApi.py new file mode 100755 index 00000000..0465538a --- /dev/null +++ b/src/python/dm/ds_web_service/api/dsRestApi.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +from dm.common.api.dmRestApi import DmRestApi + +class DsRestApi(DmRestApi): + """ Base DS DM REST api class. """ + + def __init__(self, username=None, password=None, host=None, port=None, protocol=None): + if host == None: + host = self.configurationManager.getDsWebServiceHost() + if port == None: + port = self.configurationManager.getDsWebServicePort() + DmRestApi.__init__(self, username, password, host, port, protocol) + +####################################################################### +# Testing. + +if __name__ == '__main__': + pass + + diff --git a/src/python/dm/ds_web_service/api/dsRestApiFactory.py b/src/python/dm/ds_web_service/api/dsRestApiFactory.py new file mode 100755 index 00000000..07bc253d --- /dev/null +++ b/src/python/dm/ds_web_service/api/dsRestApiFactory.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +from dm.common.utility.loggingManager import LoggingManager +from dm.common.utility.configurationManager import ConfigurationManager + +class DsRestApiFactory: + + CONFIG_SECTION_NAME = 'DsRestApiFactory' + USERNAME_KEY = 'username' + PASSWORD_FILE_KEY = 'passwordfile' + HOST_KEY = 'host' + PORT_KEY = 'port' + PROTOCOL_KEY = 'protocol' + + __logger = None + __username = None + __password = None + __host = None + __port = None + __protocol = None + + @classmethod + def getLogger(cls): + if cls.__logger is None: + cls.__logger = LoggingManager.getInstance().getLogger(cls.__name__) + return cls.__logger + + @classmethod + def __getConfiguration(cls): + if cls.__username is None: + cls.__username = ConfigurationManager.getInstance().getConfigOption(cls.CONFIG_SECTION_NAME, cls.USERNAME_KEY) + cls.__password = open(ConfigurationManager.getInstance().getConfigOption(cls.CONFIG_SECTION_NAME, cls.PASSWORD_FILE_KEY)).read().strip() + cls.__host = ConfigurationManager.getInstance().getConfigOption(cls.CONFIG_SECTION_NAME, cls.HOST_KEY) + cls.__port = ConfigurationManager.getInstance().getConfigOption(cls.CONFIG_SECTION_NAME, cls.PORT_KEY) + cls.__protocol = ConfigurationManager.getInstance().getConfigOption(cls.CONFIG_SECTION_NAME, cls.PROTOCOL_KEY) + return (cls.__username, cls.__password, cls.__host, cls.__port, cls.__protocol) + + @classmethod + def getUserRestApi(cls): + from userRestApi import UserRestApi + (username, password, host, port, protocol) = cls.__getConfiguration() + api = UserRestApi(username, password, host, port, protocol) + return api + + @classmethod + def getAuthRestApi(cls): + from authRestApi import AuthRestApi + (username, password, host, port, protocol) = cls.__getConfiguration() + api = AuthRestApi(username, password, host, port, protocol) + return api + +#################################################################### +# Testing + +if __name__ == '__main__': + pass + diff --git a/src/python/dm/ds_web_service/api/experimentRestApi.py b/src/python/dm/ds_web_service/api/experimentRestApi.py new file mode 100755 index 00000000..b2438352 --- /dev/null +++ b/src/python/dm/ds_web_service/api/experimentRestApi.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python + +import os +import urllib + +from dm.common.utility.encoder import Encoder +from dm.common.exceptions.dmException import DmException +from dm.common.objects.experiment import Experiment +from dm.common.objects.experimentType import ExperimentType +from dsRestApi import DsRestApi + +class ExperimentRestApi(DsRestApi): + + def __init__(self, username=None, password=None, host=None, port=None, protocol=None): + DsRestApi.__init__(self, username, password, host, port, protocol) + + @DsRestApi.execute + def getExperimentTypes(self): + url = '%s/experimentTypes' % (self.getContextRoot()) + responseData = self.sendSessionRequest(url=url, method='GET') + return self.toDmObjectList(responseData, ExperimentType) + + @DsRestApi.execute + def getExperiments(self): + url = '%s/experiments' % (self.getContextRoot()) + responseData = self.sendSessionRequest(url=url, method='GET') + return self.toDmObjectList(responseData, Experiment) + + @DsRestApi.execute + def getExperimentByName(self, name): + url = '%s/experimentsByName/%s' % (self.getContextRoot(), name) + if name is None or not len(name): + raise InvalidRequest('Experiment name must be provided.') + responseDict = self.sendSessionRequest(url=url, method='GET') + return Experiment(responseDict) + + @DsRestApi.execute + def getExperimentById(self, id): + url = '%s/experiments/%s' % (self.getContextRoot(), id) + if id is None: + raise InvalidRequest('Experiment id must be provided.') + responseDict = self.sendSessionRequest(url=url, method='GET') + return Experiment(responseDict) + + @DsRestApi.execute + def startExperiment(self, name): + url = '%s/experiments/start' % (self.getContextRoot()) + if name is None or not len(name): + raise InvalidRequest('Experiment name must be provided.') + url += '?name=%s' % Encoder.encode(name) + responseDict = self.sendSessionRequest(url=url, method='PUT') + return Experiment(responseDict) + + @DsRestApi.execute + def stopExperiment(self, name): + url = '%s/experiments/stop' % (self.getContextRoot()) + if name is None or not len(name): + raise InvalidRequest('Experiment name must be provided.') + url += '?name=%s' % Encoder.encode(name) + responseDict = self.sendSessionRequest(url=url, method='PUT') + return Experiment(responseDict) + + @DsRestApi.execute + def addExperiment(self, name, experimentTypeId, description): + url = '%s/experiments' % (self.getContextRoot()) + if name is None or not len(name): + raise InvalidRequest('Experiment name must be provided.') + url += '?name=%s' % Encoder.encode(name) + if experimentTypeId is None: + raise InvalidRequest('Experiment type id must be provided.') + url += '&experimentTypeId=%s' % experimentTypeId + if description is not None: + url += '&description=%s' % Encoder.encode(description) + responseDict = self.sendSessionRequest(url=url, method='POST') + return Experiment(responseDict) + +####################################################################### +# Testing. + +if __name__ == '__main__': + api = ExperimentRestApi('sveseli', 'sveseli', 'zagreb.svdev.net', 33336, 'http') + print api.startExperiment('experiment1') + diff --git a/src/python/dm/ds_web_service/api/userRestApi.py b/src/python/dm/ds_web_service/api/userRestApi.py new file mode 100755 index 00000000..ee43ab21 --- /dev/null +++ b/src/python/dm/ds_web_service/api/userRestApi.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +import os +import urllib + +from dm.common.utility.encoder import Encoder +from dm.common.exceptions.dmException import DmException +from dm.common.exceptions.invalidRequest import InvalidRequest +from dm.common.objects.userInfo import UserInfo +from dsRestApi import DsRestApi + +class UserRestApi(DsRestApi): + + def __init__(self, username=None, password=None, host=None, port=None, protocol=None): + DsRestApi.__init__(self, username, password, host, port, protocol) + + @DsRestApi.execute + def getUsers(self): + url = '%s/users' % (self.getContextRoot()) + responseData = self.sendSessionRequest(url=url, method='GET') + return self.toDmObjectList(responseData, UserInfo) + + @DsRestApi.execute + def getUserById(self, id): + if id is None: + raise InvalidRequest('User id must be provided.') + url = '%s/users/%s' % (self.getContextRoot(), id) + responseData = self.sendSessionRequest(url=url, method='GET') + return UserInfo(responseData) + + @DsRestApi.execute + def getUserByUsername(self, username): + if username is None: + raise InvalidRequest('Username must be provided.') + url = '%s/usersByUsername/%s' % (self.getContextRoot(), username) + responseData = self.sendSessionRequest(url=url, method='GET') + return UserInfo(responseData) + +####################################################################### +# Testing. + +if __name__ == '__main__': + pass + + + diff --git a/src/python/dm/ds_web_service/cli/__init__.py b/src/python/dm/ds_web_service/cli/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/python/dm/ds_web_service/cli/addExperimentCli.py b/src/python/dm/ds_web_service/cli/addExperimentCli.py new file mode 100755 index 00000000..aecd43cd --- /dev/null +++ b/src/python/dm/ds_web_service/cli/addExperimentCli.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +from dm.ds_web_service.api.experimentRestApi import ExperimentRestApi +from dm.common.exceptions.invalidRequest import InvalidRequest +from dsWebServiceSessionCli import DsWebServiceSessionCli + +class AddExperimentCli(DsWebServiceSessionCli): + def __init__(self): + DsWebServiceSessionCli.__init__(self) + self.addOption('', '--name', dest='name', help='Experiment name.') + self.addOption('', '--type-id', dest='typeId', help='Experiment type id.') + self.addOption('', '--description', dest='description', help='Experiment description.') + + def checkArgs(self): + if self.options.name is None: + raise InvalidRequest('Experiment name must be provided.') + if self.options.typeId is None: + raise InvalidRequest('Experiment type id must be provided.') + + + def getName(self): + return self.options.name + + def getTypeId(self): + return self.options.typeId + + def getDescription(self): + return self.options.description + + def runCommand(self): + self.parseArgs(usage=""" + dm-get-experiment --name=NAME --type-id=TYPEID + [--description=DESCRIPTION] + +Description: + Add new experiment to the DM database. + """) + self.checkArgs() + api = ExperimentRestApi(self.getLoginUsername(), self.getLoginPassword(), self.getServiceHost(), self.getServicePort(), self.getServiceProtocol()) + experiment = api.addExperiment(self.getName(), self.getTypeId(), self.getDescription()) + print experiment.getDisplayString(self.getDisplayKeys(), self.getDisplayFormat()) + +####################################################################### +# Run command. +if __name__ == '__main__': + cli = AddExperimentCli() + cli.run() + diff --git a/src/python/dm/ds_web_service/cli/dsWebServiceCli.py b/src/python/dm/ds_web_service/cli/dsWebServiceCli.py new file mode 100755 index 00000000..84bb15b6 --- /dev/null +++ b/src/python/dm/ds_web_service/cli/dsWebServiceCli.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +from dm.common.cli.dmRestCli import DmRestCli +from dm.common.utility.configurationManager import ConfigurationManager + +class DsWebServiceCli(DmRestCli): + """ DM DS web service cli class. """ + + def __init__(self, validArgCount=0): + DmRestCli.__init__(self, validArgCount) + + def getDefaultServiceHost(self): + return ConfigurationManager.getInstance().getDsWebServiceHost() + + def getDefaultServicePort(self): + return ConfigurationManager.getInstance().getDsWebServicePort() + ` diff --git a/src/python/dm/ds_web_service/cli/dsWebServiceSessionCli.py b/src/python/dm/ds_web_service/cli/dsWebServiceSessionCli.py new file mode 100755 index 00000000..c0770110 --- /dev/null +++ b/src/python/dm/ds_web_service/cli/dsWebServiceSessionCli.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +from dm.common.cli.dmRestSessionCli import DmRestSessionCli +from dm.common.utility.osUtility import OsUtility +from dm.common.utility.configurationManager import ConfigurationManager + +class DsWebServiceSessionCli(DmRestSessionCli): + """ DM DS web service session cli class. """ + + DEFAULT_SESSION_CACHE_FILE = OsUtility.getUserHomeDir() + '/.dm/.ds.session.cache' + + def __init__(self, validArgCount=0): + DmRestSessionCli.__init__(self, validArgCount) + ConfigurationManager.getInstance().setSessionCacheFile(DsWebServiceSessionCli.DEFAULT_SESSION_CACHE_FILE) + + def getDefaultServiceHost(self): + return ConfigurationManager.getInstance().getDsWebServiceHost() + + def getDefaultServicePort(self): + return ConfigurationManager.getInstance().getDsWebServicePort() + diff --git a/src/python/dm/ds_web_service/cli/getExperimentCli.py b/src/python/dm/ds_web_service/cli/getExperimentCli.py new file mode 100755 index 00000000..40a80722 --- /dev/null +++ b/src/python/dm/ds_web_service/cli/getExperimentCli.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +from dm.common.exceptions.invalidRequest import InvalidRequest +from dm.ds_web_service.api.userRestApi import ExperimentRestApi +from dsWebServiceSessionCli import DsWebServiceSessionCli + +class GetExperimentCli(DsWebServiceSessionCli): + def __init__(self): + DsWebServiceSessionCli.__init__(self) + self.addOption('', '--id', dest='id', help='Experiment id. Either id or name must be provided. If both are provided, id takes precedence.') + self.addOption('', '--name', dest='name', help='Experiment name. Either id or name must be provided. If both are provided, id takes precedence.') + + def checkArgs(self): + if self.options.id is None and self.options.username is None: + raise InvalidRequest('Either user id or username must be provided.') + + def getId(self): + return self.options.id + + def getName(self): + return self.options.name + + def runCommand(self): + self.parseArgs(usage=""" + dm-get-user --id=ID|--name=NAME + +Description: + Retrieves experiment information. + """) + self.checkArgs() + api = ExperimentRestApi(self.getLoginUsername(), self.getLoginPassword(), self.getServiceHost(), self.getServicePort(), self.getServiceProtocol()) + if self.getId() is not None: + experiment = api.getExperimentById(self.getId()) + else: + experiment = api.getExperimentByName(self.getName()) + print experiment.getDisplayString(self.getDisplayKeys(), self.getDisplayFormat()) + +####################################################################### +# Run command. +if __name__ == '__main__': + cli = GetExperimentCli() + cli.run() + diff --git a/src/python/dm/ds_web_service/cli/getExperimentTypesCli.py b/src/python/dm/ds_web_service/cli/getExperimentTypesCli.py new file mode 100755 index 00000000..55313950 --- /dev/null +++ b/src/python/dm/ds_web_service/cli/getExperimentTypesCli.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +from dm.ds_web_service.api.experimentRestApi import ExperimentRestApi +from dsWebServiceSessionCli import DsWebServiceSessionCli + +class GetExperimentTypesCli(DsWebServiceSessionCli): + def __init__(self): + DsWebServiceSessionCli.__init__(self) + + def runCommand(self): + self.parseArgs(usage=""" + dm-get-experiment-types + +Description: + Retrieves list of known experiment types. + """) + api = ExperimentRestApi(self.getLoginUsername(), self.getLoginPassword(), self.getServiceHost(), self.getServicePort(), self.getServiceProtocol()) + experimentTypes = api.getExperimentTypes() + for experimentType in experimentTypes: + print experimentType.getDisplayString(self.getDisplayKeys(), self.getDisplayFormat()) + + +####################################################################### +# Run command. +if __name__ == '__main__': + cli = GetExperimentTypesCli() + cli.run() diff --git a/src/python/dm/ds_web_service/cli/getExperimentsCli.py b/src/python/dm/ds_web_service/cli/getExperimentsCli.py new file mode 100755 index 00000000..d46f5b73 --- /dev/null +++ b/src/python/dm/ds_web_service/cli/getExperimentsCli.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +from dm.ds_web_service.api.experimentRestApi import ExperimentRestApi +from dsWebServiceSessionCli import DsWebServiceSessionCli + +class GetExperimentsCli(DsWebServiceSessionCli): + def __init__(self): + DsWebServiceSessionCli.__init__(self) + + def runCommand(self): + self.parseArgs(usage=""" + dm-get-experiments + +Description: + Retrieves list of known experiments. + """) + api = ExperimentRestApi(self.getLoginUsername(), self.getLoginPassword(), self.getServiceHost(), self.getServicePort(), self.getServiceProtocol()) + experiments = api.getExperiments() + for experiment in experiments: + print experiment.getDisplayString(self.getDisplayKeys(), self.getDisplayFormat()) + + +####################################################################### +# Run command. +if __name__ == '__main__': + cli = GetExperimentsCli() + cli.run() diff --git a/src/python/dm/ds_web_service/cli/getUserCli.py b/src/python/dm/ds_web_service/cli/getUserCli.py new file mode 100755 index 00000000..b45c34b5 --- /dev/null +++ b/src/python/dm/ds_web_service/cli/getUserCli.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +from dm.common.exceptions.invalidRequest import InvalidRequest +from dm.ds_web_service.api.userRestApi import UserRestApi +from dsWebServiceSessionCli import DsWebServiceSessionCli + +class GetUserCli(DsWebServiceSessionCli): + def __init__(self): + DsWebServiceSessionCli.__init__(self) + self.addOption('', '--id', dest='id', help='User id. Either id or username must be provided. If both are provided, id takes precedence.') + self.addOption('', '--username', dest='username', help='User username. Either id or username must be provided. If both are provided, id takes precedence.') + + def checkArgs(self): + if self.options.id is None and self.options.username is None: + raise InvalidRequest('Either user id or username must be provided.') + + def getId(self): + return self.options.id + + def getUsername(self): + return self.options.username + + def runCommand(self): + self.parseArgs(usage=""" + dm-get-user --id=ID|--username=USERNAME + +Description: + Retrieves user information. + """) + self.checkArgs() + api = UserRestApi(self.getLoginUsername(), self.getLoginPassword(), self.getServiceHost(), self.getServicePort(), self.getServiceProtocol()) + if self.getId() is not None: + userInfo = api.getUserById(self.getId()) + else: + userInfo = api.getUserByUsername(self.getUsername()) + print userInfo.getDisplayString(self.getDisplayKeys(), self.getDisplayFormat()) + +####################################################################### +# Run command. +if __name__ == '__main__': + cli = GetUserCli() + cli.run() diff --git a/src/python/dm/ds_web_service/cli/getUsersCli.py b/src/python/dm/ds_web_service/cli/getUsersCli.py new file mode 100755 index 00000000..8119fe0e --- /dev/null +++ b/src/python/dm/ds_web_service/cli/getUsersCli.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +from dm.ds_web_service.api.userRestApi import UserRestApi +from dsWebServiceSessionCli import DsWebServiceSessionCli + +class GetUsersCli(DsWebServiceSessionCli): + def __init__(self): + DsWebServiceSessionCli.__init__(self) + + def runCommand(self): + self.parseArgs(usage=""" + dm-get-users + +Description: + Retrieves list of registered users. + """) + api = UserRestApi(self.getLoginUsername(), self.getLoginPassword(), self.getServiceHost(), self.getServicePort(), self.getServiceProtocol()) + users = api.getUsers() + for user in users: + print user.getDisplayString(self.getDisplayKeys(), self.getDisplayFormat()) + + +####################################################################### +# Run command. +if __name__ == '__main__': + cli = GetUsersCli() + cli.run() diff --git a/src/python/dm/ds_web_service/cli/startExperimentCli.py b/src/python/dm/ds_web_service/cli/startExperimentCli.py new file mode 100755 index 00000000..ed307d58 --- /dev/null +++ b/src/python/dm/ds_web_service/cli/startExperimentCli.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python + +from dm.ds_web_service.api.experimentRestApi import ExperimentRestApi +from dm.common.exceptions.invalidRequest import InvalidRequest +from dsWebServiceSessionCli import DsWebServiceSessionCli + +class StartExperimentCli(DsWebServiceSessionCli): + def __init__(self): + DsWebServiceSessionCli.__init__(self) + self.addOption('', '--name', dest='name', help='Experiment name.') + + def checkArgs(self): + if self.options.name is None: + raise InvalidRequest('Experiment name must be provided.') + + def getName(self): + return self.options.name + + def runCommand(self): + self.parseArgs(usage=""" + dm-start-experiment --name=NAME + +Description: + Updates experiment start time in the DM database and prepares experiment data directory. + """) + self.checkArgs() + api = ExperimentRestApi(self.getLoginUsername(), self.getLoginPassword(), self.getServiceHost(), self.getServicePort(), self.getServiceProtocol()) + experiment = api.startExperiment(self.getName()) + print experiment.getDisplayString(self.getDisplayKeys(), self.getDisplayFormat()) + +####################################################################### +# Run command. +if __name__ == '__main__': + cli = StartExperimentCli() + cli.run() + diff --git a/src/python/dm/ds_web_service/cli/stopExperimentCli.py b/src/python/dm/ds_web_service/cli/stopExperimentCli.py new file mode 100755 index 00000000..7715a01d --- /dev/null +++ b/src/python/dm/ds_web_service/cli/stopExperimentCli.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python + +from dm.ds_web_service.api.experimentRestApi import ExperimentRestApi +from dm.common.exceptions.invalidRequest import InvalidRequest +from dsWebServiceSessionCli import DsWebServiceSessionCli + +class StopExperimentCli(DsWebServiceSessionCli): + def __init__(self): + DsWebServiceSessionCli.__init__(self) + self.addOption('', '--name', dest='name', help='Experiment name.') + + def checkArgs(self): + if self.options.name is None: + raise InvalidRequest('Experiment name must be provided.') + + def getName(self): + return self.options.name + + def runCommand(self): + self.parseArgs(usage=""" + dm-stop-experiment --name=NAME + +Description: + Updates experiment end date in the DM database and checks experiment data permissions. + """) + self.checkArgs() + api = ExperimentRestApi(self.getLoginUsername(), self.getLoginPassword(), self.getServiceHost(), self.getServicePort(), self.getServiceProtocol()) + experiment = api.stopExperiment(self.getName()) + print experiment.getDisplayString(self.getDisplayKeys(), self.getDisplayFormat()) + +####################################################################### +# Run command. +if __name__ == '__main__': + cli = StopExperimentCli() + cli.run() + diff --git a/src/python/dm/ds_web_service/service/__init__.py b/src/python/dm/ds_web_service/service/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/python/dm/ds_web_service/service/auth/__init__.py b/src/python/dm/ds_web_service/service/auth/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/python/dm/ds_web_service/service/auth/dsAuthPrincipalRetriever.py b/src/python/dm/ds_web_service/service/auth/dsAuthPrincipalRetriever.py new file mode 100755 index 00000000..9be90da8 --- /dev/null +++ b/src/python/dm/ds_web_service/service/auth/dsAuthPrincipalRetriever.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +from dm.common.constants import dmRole +from dm.common.objects.authorizationPrincipal import AuthorizationPrincipal +from dm.common.db.api.userDbApi import UserDbApi +from dm.common.service.auth.authorizationPrincipalRetriever import AuthorizationPrincipalRetriever +from dm.ds_web_service.api.dsRestApiFactory import DsRestApiFactory + + +class DsAuthPrincipalRetriever(AuthorizationPrincipalRetriever): + + def __init__(self): + AuthorizationPrincipalRetriever.__init__(self, self.__class__.__name__) + self.authApi = DsRestApiFactory.getAuthRestApi() + + def getAuthorizationPrincipal(self, username): + principal = self.authApi.getAuthorizationPrincipal(username) + return principal + +####################################################################### +# Testing. +if __name__ == '__main__': + pass + diff --git a/src/python/dm/ds_web_service/service/authRouteDescriptor.py b/src/python/dm/ds_web_service/service/authRouteDescriptor.py new file mode 100755 index 00000000..9cc34dc9 --- /dev/null +++ b/src/python/dm/ds_web_service/service/authRouteDescriptor.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +# +# Auth route descriptor. +# + +from dm.common.utility.configurationManager import ConfigurationManager +from authSessionController import AuthSessionController + +class AuthRouteDescriptor: + + @classmethod + def getRoutes(cls): + contextRoot = ConfigurationManager.getInstance().getContextRoot() + authSessionController = AuthSessionController() + + routes = [ + + # Get authorization principal + { + 'name' : 'getAuthorizationPrincipal', + 'path' : '%s/authorizationPrincipals/:(username)' % contextRoot, + 'controller' : authSessionController, + 'action' : 'getAuthorizationPrincipal', + 'method' : [ 'GET' ] + }, + + ] + + return routes + + diff --git a/src/python/dm/ds_web_service/service/authSessionController.py b/src/python/dm/ds_web_service/service/authSessionController.py new file mode 100755 index 00000000..6582f742 --- /dev/null +++ b/src/python/dm/ds_web_service/service/authSessionController.py @@ -0,0 +1,22 @@ +#authenticateUser!/usr/bin/env python + +import cherrypy +from dm.common.service.dmSessionController import DmSessionController +from dm.ds_web_service.service.impl.authSessionControllerImpl import AuthSessionControllerImpl + +class AuthSessionController(DmSessionController): + + def __init__(self): + DmSessionController.__init__(self) + self.authSessionControllerImpl = AuthSessionControllerImpl() + + @cherrypy.expose + @DmSessionController.require(DmSessionController.isLoggedIn()) + @DmSessionController.execute + def getAuthorizationPrincipal(self, username, **kwargs): + if not len(username): + raise InvalidRequest('Invalid username provided.') + response = self.authSessionControllerImpl.getAuthorizationPrincipal(username).getFullJsonRep() + self.logger.debug('Returning authorization principal for %s' % (username)) + return response + diff --git a/src/python/dm/ds_web_service/service/dsWebService.py b/src/python/dm/ds_web_service/service/dsWebService.py new file mode 100755 index 00000000..acf8654b --- /dev/null +++ b/src/python/dm/ds_web_service/service/dsWebService.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +# +# DM DS Web Service +# + +#################################################################### + +from dm.common.service.dmRestWebServiceBase import DmRestWebServiceBase +from dm.common.utility.dmModuleManager import DmModuleManager +from dm.common.utility.configurationManager import ConfigurationManager +from dm.ds_web_service.service.impl.storageManager import StorageManager +from dsWebServiceRouteMapper import DsWebServiceRouteMapper + +#################################################################### + +class DsWebService(DmRestWebServiceBase): + + def __init__(self): + DmRestWebServiceBase.__init__(self, DsWebServiceRouteMapper) + + def initDmModules(self): + self.logger.debug('Initializing dm modules') + + # Add modules that will be started. + moduleManager = DmModuleManager.getInstance() + moduleManager.addModule(StorageManager.getInstance()) + self.logger.debug('Initialized dm modules') + + def getDefaultServerHost(self): + return ConfigurationManager.getInstance().getServiceHost() + + def getDefaultServerPort(self): + return ConfigurationManager.getInstance().getServicePort() + +#################################################################### +# Run service + +if __name__ == '__main__': + ConfigurationManager.getInstance().setServiceName('ds-web-service') + service = DsWebService(); + service.run() diff --git a/src/python/dm/ds_web_service/service/dsWebServiceRouteMapper.py b/src/python/dm/ds_web_service/service/dsWebServiceRouteMapper.py new file mode 100755 index 00000000..ba377b8b --- /dev/null +++ b/src/python/dm/ds_web_service/service/dsWebServiceRouteMapper.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python + +# +# Route mapper for DM DS web service. +# + +import sys +import os + +import cherrypy +from dm.common.utility.loggingManager import LoggingManager +from dm.common.utility.configurationManager import ConfigurationManager +from dm.common.service.loginRouteDescriptor import LoginRouteDescriptor +from userRouteDescriptor import UserRouteDescriptor +from experimentRouteDescriptor import ExperimentRouteDescriptor +from authRouteDescriptor import AuthRouteDescriptor + +class DsWebServiceRouteMapper: + + @classmethod + def setupRoutes(cls): + """ Setup RESTFul routes. """ + logger = LoggingManager.getInstance().getLogger(cls.__name__) + contextRoot = ConfigurationManager.getInstance().getContextRoot() + logger.debug('Using context root: %s' % contextRoot) + + # Get routes. + routes = LoginRouteDescriptor.getRoutes() + routes += AuthRouteDescriptor.getRoutes() + routes += UserRouteDescriptor.getRoutes() + routes += ExperimentRouteDescriptor.getRoutes() + + # Add routes to dispatcher. + d = cherrypy.dispatch.RoutesDispatcher() + for route in routes: + logger.debug('Connecting route: %s' % route) + d.connect(route['name'], route['path'], action=route['action'], controller=route['controller'], conditions=dict(method=route['method'])) + return d + + diff --git a/src/python/dm/ds_web_service/service/experimentRouteDescriptor.py b/src/python/dm/ds_web_service/service/experimentRouteDescriptor.py new file mode 100755 index 00000000..736795fb --- /dev/null +++ b/src/python/dm/ds_web_service/service/experimentRouteDescriptor.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python + +# +# User route descriptor. +# + +from dm.common.utility.configurationManager import ConfigurationManager +from experimentSessionController import ExperimentSessionController + +class ExperimentRouteDescriptor: + + @classmethod + def getRoutes(cls): + contextRoot = ConfigurationManager.getInstance().getContextRoot() + + # Static instances shared between different routes + experimentSessionController = ExperimentSessionController() + + # Define routes. + routes = [ + + # Get experiment types + { + 'name' : 'getExperimentTypes', + 'path' : '%s/experimentTypes' % contextRoot, + 'controller' : experimentSessionController, + 'action' : 'getExperimentTypes', + 'method' : ['GET'] + }, + + # Get experiments + { + 'name' : 'getExperiments', + 'path' : '%s/experiments' % contextRoot, + 'controller' : experimentSessionController, + 'action' : 'getExperiments', + 'method' : ['GET'] + }, + + # Get experiment + { + 'name' : 'getExperimentById', + 'path' : '%s/experiments/:(id)' % contextRoot, + 'controller' : experimentSessionController, + 'action' : 'getExperimentById', + 'method' : ['GET'] + }, + + # Get experiment + { + 'name' : 'getExperimentByName', + 'path' : '%s/experimentsByName/:(name)' % contextRoot, + 'controller' : experimentSessionController, + 'action' : 'getExperimentByName', + 'method' : ['GET'] + }, + + # Add experiment + { + 'name' : 'addExperiment', + 'path' : '%s/experiments' % contextRoot, + 'controller' : experimentSessionController, + 'action' : 'addExperiment', + 'method' : ['POST'] + }, + + # Start experiment + { + 'name' : 'startExperiment', + 'path' : '%s/experiments/start' % contextRoot, + 'controller' : experimentSessionController, + 'action' : 'startExperiment', + 'method' : ['PUT'] + }, + + # Stop experiment + { + 'name' : 'stopExperiment', + 'path' : '%s/experiments/stop' % contextRoot, + 'controller' : experimentSessionController, + 'action' : 'stopExperiment', + 'method' : ['PUT'] + }, + + ] + + return routes + + diff --git a/src/python/dm/ds_web_service/service/experimentSessionController.py b/src/python/dm/ds_web_service/service/experimentSessionController.py new file mode 100755 index 00000000..c9c583b2 --- /dev/null +++ b/src/python/dm/ds_web_service/service/experimentSessionController.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python + +import cherrypy + +from dm.common.service.dmSessionController import DmSessionController +from dm.common.exceptions.invalidRequest import InvalidRequest +from dm.common.utility.encoder import Encoder + +from dm.ds_web_service.service.impl.experimentSessionControllerImpl import ExperimentSessionControllerImpl + + +class ExperimentSessionController(DmSessionController): + + def __init__(self): + DmSessionController.__init__(self) + self.experimentSessionControllerImpl = ExperimentSessionControllerImpl() + + @cherrypy.expose + @DmSessionController.require(DmSessionController.isLoggedIn()) + @DmSessionController.execute + def getExperimentTypes(self, **kwargs): + return self.listToJson(self.experimentSessionControllerImpl.getExperimentTypes()) + + @cherrypy.expose + @DmSessionController.require(DmSessionController.isLoggedIn()) + @DmSessionController.execute + def getExperiments(self, **kwargs): + return self.listToJson(self.experimentSessionControllerImpl.getExperiments()) + + @cherrypy.expose + @DmSessionController.require(DmSessionController.isLoggedIn()) + @DmSessionController.execute + def getExperimentByName(self, name, **kwargs): + response = self.experimentSessionControllerImpl.getExperimentByName(name).getFullJsonRep() + self.logger.debug('Returning: %s' % response) + return response + + @cherrypy.expose + @DmSessionController.require(DmSessionController.isLoggedIn()) + @DmSessionController.execute + def getExperimentById(self, id, **kwargs): + response = self.experimentSessionControllerImpl.getExperimentByid(id).getFullJsonRep() + self.logger.debug('Returning: %s' % response) + return response + + @cherrypy.expose + @DmSessionController.require(DmSessionController.isLoggedIn()) + @DmSessionController.execute + def addExperiment(self, **kwargs): + name = kwargs.get('name') + if name is None or not len(name): + raise InvalidRequest('Missing experiment name.') + name = Encoder.decode(name) + experimentTypeId = kwargs.get('experimentTypeId') + if experimentTypeId is None: + raise InvalidRequest('Missing experiment type id.') + description = kwargs.get('description') + if description is not None: + description = Encoder.decode(description) + response = self.experimentSessionControllerImpl.addExperiment(name, experimentTypeId, description).getFullJsonRep() + self.logger.debug('Returning: %s' % response) + return response + + @cherrypy.expose + @DmSessionController.require(DmSessionController.isLoggedIn()) + @DmSessionController.execute + def startExperiment(self, **kwargs): + name = kwargs.get('name') + if name is None or not len(name): + raise InvalidRequest('Missing experiment name.') + name = Encoder.decode(name) + response = self.experimentSessionControllerImpl.startExperiment(name).getFullJsonRep() + self.logger.debug('Returning: %s' % response) + return response + + @cherrypy.expose + @DmSessionController.require(DmSessionController.isLoggedIn()) + @DmSessionController.execute + def stopExperiment(self, **kwargs): + name = kwargs.get('name') + if name is None or not len(name): + raise InvalidRequest('Missing experiment name.') + name = Encoder.decode(name) + response = self.experimentSessionControllerImpl.stopExperiment(name).getFullJsonRep() + self.logger.debug('Returning: %s' % response) + return response + diff --git a/src/python/dm/ds_web_service/service/impl/__init__.py b/src/python/dm/ds_web_service/service/impl/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/python/dm/ds_web_service/service/impl/authSessionControllerImpl.py b/src/python/dm/ds_web_service/service/impl/authSessionControllerImpl.py new file mode 100755 index 00000000..12ac9cd0 --- /dev/null +++ b/src/python/dm/ds_web_service/service/impl/authSessionControllerImpl.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python + +# +# Implementation for user info controller. +# + +from dm.common.constants import dmRole +from dm.common.objects.authorizationPrincipal import AuthorizationPrincipal +from dm.common.objects.dmObjectManager import DmObjectManager +from dm.common.db.api.userDbApi import UserDbApi + +class AuthSessionControllerImpl(DmObjectManager): + """ User info controller implementation class. """ + + def __init__(self): + DmObjectManager.__init__(self) + self.userDbApi = UserDbApi() + + def getAuthorizationPrincipal(self, username): + user = self.userDbApi.getUserWithPasswordByUsername(username) + principal = AuthorizationPrincipal(name=username, token=user.get('password')) + principal.setRole(dmRole.DM_USER_ROLE) + principal.setUserInfo(user) + for userSystemRoleName in user.get('userSystemRoleNameList', []): + if userSystemRoleName == dmRole.DM_ADMIN_ROLE: + principal.setRole(dmRole.DM_ADMIN_ROLE) + return principal + + diff --git a/src/python/dm/ds_web_service/service/impl/experimentSessionControllerImpl.py b/src/python/dm/ds_web_service/service/impl/experimentSessionControllerImpl.py new file mode 100755 index 00000000..f41021dc --- /dev/null +++ b/src/python/dm/ds_web_service/service/impl/experimentSessionControllerImpl.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +# +# Implementation for experiment session controller. +# + +import time + +from dm.common.objects.experiment import Experiment +from dm.common.objects.dmObjectManager import DmObjectManager +from dm.common.exceptions.invalidRequest import InvalidRequest +from dm.common.db.api.experimentDbApi import ExperimentDbApi +from dm.ds_web_service.service.impl.storageManager import StorageManager + +class ExperimentSessionControllerImpl(DmObjectManager): + """ Experiment session controller implementation class. """ + + def __init__(self): + DmObjectManager.__init__(self) + self.experimentDbApi = ExperimentDbApi() + + def getExperimentTypes(self): + experimentTypeList = self.experimentDbApi.getExperimentTypes() + return experimentTypeList + + def getExperiments(self): + experimentList = self.experimentDbApi.getExperiments() + return experimentList + + def getExperimentByName(self, name): + experiment = self.experimentDbApi.getExperimentByName(name) + return experiment + + def getExperimentById(self, id): + experiment = self.experimentDbApi.getExperimentById(id) + return experiment + + def addExperiment(self, name, experimentTypeId, description): + experiment = self.experimentDbApi.addExperiment(name, experimentTypeId, description) + return experiment + + def startExperiment(self, name): + experiment = self.experimentDbApi.setExperimentStartDateToNow(name) + StorageManager.getInstance().createExperimentDataDirectory(experiment) + return experiment + + def stopExperiment(self, name): + experiment = self.experimentDbApi.setExperimentEndDateToNow(name) + return experiment diff --git a/src/python/dm/ds_web_service/service/impl/fileSystemControllerImpl.py b/src/python/dm/ds_web_service/service/impl/fileSystemControllerImpl.py new file mode 100755 index 00000000..b3e27a94 --- /dev/null +++ b/src/python/dm/ds_web_service/service/impl/fileSystemControllerImpl.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +# +# Implementation for file system controller. +# + +####################################################################### + +import threading + +from dm.common.objects.dmObject import DmObject +from dm.common.objects.dmObjectManager import DmObjectManager +from dm.common.utility.dmSubprocess import DmSubprocess + +####################################################################### + +class FileSystemControllerImpl(DmObjectManager): + """ FS controller implementation class. """ + + def __init__(self): + DmObjectManager.__init__(self) + + def getDirectoryList(self, path): + p = DmSubprocess('ls -l %s' % path) + p.run() + return DmObject({'path' : path, 'directoryList' : p.getStdOut()}) + + def writeFile(self, path, content): + f = open(path, 'w') + f.write('%s\n' % content) + f.close() + return DmObject({'path' : path}) diff --git a/src/python/dm/ds_web_service/service/impl/storageManager.py b/src/python/dm/ds_web_service/service/impl/storageManager.py new file mode 100755 index 00000000..e12565f3 --- /dev/null +++ b/src/python/dm/ds_web_service/service/impl/storageManager.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python + +import threading +import time + +from dm.common.utility.loggingManager import LoggingManager +from dm.common.utility.configurationManager import ConfigurationManager +from dm.common.utility.singleton import Singleton + + +class StorageManager(Singleton): + + CONFIG_SECTION_NAME = 'StorageManager' + STORAGE_DIRECTORY_KEY = 'storagedirectory' + + # Singleton. + __instanceLock = threading.RLock() + __instance = None + + def __init__(self): + StorageManager.__instanceLock.acquire() + try: + if StorageManager.__instance: + return + StorageManager.__instance = self + self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__) + + self.logger.debug('Initializing') + self.lock = threading.RLock() + self.__configure() + self.logger.debug('Initialization complete') + finally: + StorageManager.__instanceLock.release() + + def __configure(self): + cm = ConfigurationManager.getInstance() + configItems = cm.getConfigItems(StorageManager.CONFIG_SECTION_NAME) + self.logger.debug('Got config items: %s' % configItems) + self.storageDirectory = cm.getConfigOption(StorageManager.CONFIG_SECTION_NAME, StorageManager.STORAGE_DIRECTORY_KEY) + + def createExperimentDataDirectory(self, experiment): + self.lock.acquire() + try: + experimentTypeName = experiment.get('experimentType').get('rootDataPath') + experimentName = experiment.get('name') + dataDirectory = '%s/%s/%s' % (self.storageDirectory, experimentTypeName, experimentName) + dataDirectory = dataDirectory.replace('//', '/') + self.logger.debug('Creating data directory for experiment %s: %s' % (experimentName, dataDirectory)) + experiment['dataDirectory'] = dataDirectory + finally: + self.lock.release() + + def start(self): + self.lock.acquire() + try: + self.logger.debug('Started storage manager') + finally: + self.lock.release() + + def stop(self): + self.lock.acquire() + try: + self.logger.debug('Stopped storage manager') + finally: + self.lock.release() + +#################################################################### +# Testing + +if __name__ == '__main__': + sm = StorageManager.getInstance() + print sm + diff --git a/src/python/dm/ds_web_service/service/impl/userInfoSessionControllerImpl.py b/src/python/dm/ds_web_service/service/impl/userInfoSessionControllerImpl.py new file mode 100755 index 00000000..2fbeb83a --- /dev/null +++ b/src/python/dm/ds_web_service/service/impl/userInfoSessionControllerImpl.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python + +# +# Implementation for user info controller. +# + +from dm.common.objects.dmObject import DmObject +from dm.common.objects.dmObjectManager import DmObjectManager +from dm.common.db.api.userDbApi import UserDbApi + +class UserInfoSessionControllerImpl(DmObjectManager): + """ User info controller implementation class. """ + + def __init__(self): + DmObjectManager.__init__(self) + self.userDbApi = UserDbApi() + + def getUsers(self): + return self.userDbApi.getUsers() + + def getUserById(self, id): + return self.userDbApi.getUserById(id) + + def getUserByUsername(self, username): + return self.userDbApi.getUserByUsername(username) + diff --git a/src/python/dm/ds_web_service/service/userInfoSessionController.py b/src/python/dm/ds_web_service/service/userInfoSessionController.py new file mode 100755 index 00000000..984e5ba7 --- /dev/null +++ b/src/python/dm/ds_web_service/service/userInfoSessionController.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +import cherrypy +from dm.common.service.dmSessionController import DmSessionController +from dm.ds_web_service.service.impl.userInfoSessionControllerImpl import UserInfoSessionControllerImpl + +class UserInfoSessionController(DmSessionController): + + def __init__(self): + DmSessionController.__init__(self) + self.userInfoSessionControllerImpl = UserInfoSessionControllerImpl() + + @cherrypy.expose + @DmSessionController.require(DmSessionController.isLoggedIn()) + @DmSessionController.execute + def getUsers(self, **kwargs): + return self.listToJson(self.userInfoSessionControllerImpl.getUsers()) + + @cherrypy.expose + @DmSessionController.require(DmSessionController.isLoggedIn()) + @DmSessionController.execute + def getUserById(self, id, **kwargs): + if not id: + raise InvalidRequest('Invalid id provided.') + response = self.userInfoSessionControllerImpl.getUserById(id).getFullJsonRep() + self.logger.debug('Returning user info for %s: %s' % (id,response)) + return response + + @cherrypy.expose + @DmSessionController.require(DmSessionController.isLoggedIn()) + @DmSessionController.execute + def getUserByUsername(self, username, **kwargs): + if not len(username): + raise InvalidRequest('Invalid username provided.') + response = self.userInfoSessionControllerImpl.getUserByUsername(username).getFullJsonRep() + self.logger.debug('Returning user info for %s: %s' % (username,response)) + return response + diff --git a/src/python/dm/ds_web_service/service/userRouteDescriptor.py b/src/python/dm/ds_web_service/service/userRouteDescriptor.py new file mode 100755 index 00000000..651727f1 --- /dev/null +++ b/src/python/dm/ds_web_service/service/userRouteDescriptor.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +# +# User route descriptor. +# + +from dm.common.utility.configurationManager import ConfigurationManager +from userInfoSessionController import UserInfoSessionController + +class UserRouteDescriptor: + + @classmethod + def getRoutes(cls): + contextRoot = ConfigurationManager.getInstance().getContextRoot() + + # Static instances shared between different routes + userInfoSessionController = UserInfoSessionController() + + # Define routes. + routes = [ + + # Get user info list + { + 'name' : 'getUsers', + 'path' : '%s/users' % contextRoot, + 'controller' : userInfoSessionController, + 'action' : 'getUsers', + 'method' : ['GET'] + }, + + # Get user by id + { + 'name' : 'getUserById', + 'path' : '%s/users/:(id)' % contextRoot, + 'controller' : userInfoSessionController, + 'action' : 'getUserById', + 'method' : ['GET'] + }, + + # Get user by username + { + 'name' : 'getUserByUsername', + 'path' : '%s/usersByUsername/:(username)' % contextRoot, + 'controller' : userInfoSessionController, + 'action' : 'getUserByUsername', + 'method' : ['GET'] + }, + + ] + + return routes + + -- GitLab