From 5a5599ba8365482ccc5c4c2e3f41169ed4c81fff Mon Sep 17 00:00:00 2001
From: Sinisa Veseli <sveseli@aps.anl.gov>
Date: Wed, 4 Nov 2015 13:28:51 +0000
Subject: [PATCH] introduced interface for notifying ds service to update
 experiment users; fix bug in linux experiment utility

---
 src/python/dm/common/utility/linuxUtility.py  |  2 +-
 .../ds_web_service/api/experimentRestApi.py   |  9 +++++
 .../ds_web_service/cli/updateExperimentCli.py | 36 +++++++++++++++++++
 .../service/experimentRouteDescriptor.py      |  9 +++++
 .../service/experimentSessionController.py    | 12 +++++++
 .../service/impl/experimentManager.py         | 10 ++++--
 .../impl/experimentSessionControllerImpl.py   |  7 ++++
 7 files changed, 82 insertions(+), 3 deletions(-)
 create mode 100755 src/python/dm/ds_web_service/cli/updateExperimentCli.py

diff --git a/src/python/dm/common/utility/linuxUtility.py b/src/python/dm/common/utility/linuxUtility.py
index b76ecab3..5eab107e 100755
--- a/src/python/dm/common/utility/linuxUtility.py
+++ b/src/python/dm/common/utility/linuxUtility.py
@@ -50,7 +50,7 @@ class LinuxUtility:
     def setGroupUsers(cls, groupName, usernameList):
         """ Set list of users for a given group. """
         logger = cls.getLogger()
-        logger.debug('Setting group %s users to: %s' % (groupName, username))
+        logger.debug('Setting group %s users to: %s' % (groupName, usernameList))
         cmd = '%s -M "%s" %s' % (cls.GPASSWD_CMD, ','.join(usernameList), groupName)
         cls.executeSudoCommand(cmd)
 
diff --git a/src/python/dm/ds_web_service/api/experimentRestApi.py b/src/python/dm/ds_web_service/api/experimentRestApi.py
index 155a679e..e27fe46a 100755
--- a/src/python/dm/ds_web_service/api/experimentRestApi.py
+++ b/src/python/dm/ds_web_service/api/experimentRestApi.py
@@ -51,6 +51,15 @@ class ExperimentRestApi(DsRestApi):
         responseDict = self.sendSessionRequest(url=url, method='PUT')
         return Experiment(responseDict)
 
+    @DsRestApi.execute
+    def updateExperiment(self, name):
+        url = '%s/experiments/update' % (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())
diff --git a/src/python/dm/ds_web_service/cli/updateExperimentCli.py b/src/python/dm/ds_web_service/cli/updateExperimentCli.py
new file mode 100755
index 00000000..e162d69f
--- /dev/null
+++ b/src/python/dm/ds_web_service/cli/updateExperimentCli.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 UpdateExperimentCli(DsWebServiceSessionCli):
+    def __init__(self):
+        DsWebServiceSessionCli.__init__(self)
+        self.addOption('', '--experiment', dest='experimentName', help='Experiment name.')
+
+    def checkArgs(self):
+        if self.options.experimentName is None:
+            raise InvalidRequest('Experiment name must be provided.')
+
+    def getExperimentName(self):
+        return self.options.experimentName
+
+    def runCommand(self):
+        self.parseArgs(usage="""
+    dm-update-experiment --experiment=EXPERIMENTNAME
+
+Description:
+    Updates experiment group users.
+        """)
+        self.checkArgs()
+        api = ExperimentRestApi(self.getLoginUsername(), self.getLoginPassword(), self.getServiceHost(), self.getServicePort(), self.getServiceProtocol())
+        experiment = api.updateExperiment(self.getExperimentName())
+        print experiment.getDisplayString(self.getDisplayKeys(), self.getDisplayFormat())
+
+#######################################################################
+# Run command.
+if __name__ == '__main__':
+    cli = UpdateExperimentCli()
+    cli.run()
+
diff --git a/src/python/dm/ds_web_service/service/experimentRouteDescriptor.py b/src/python/dm/ds_web_service/service/experimentRouteDescriptor.py
index 18a27d81..b599c4a6 100755
--- a/src/python/dm/ds_web_service/service/experimentRouteDescriptor.py
+++ b/src/python/dm/ds_web_service/service/experimentRouteDescriptor.py
@@ -73,6 +73,15 @@ class ExperimentRouteDescriptor:
                 'method' : ['PUT']
             },
 
+            # Update experiment
+            {
+                'name' : 'updateExperiment',
+                'path' : '%s/experiments/update' % contextRoot,
+                'controller' : experimentSessionController,
+                'action' : 'updateExperiment',
+                'method' : ['PUT']
+            },
+
             # Stop experiment
             {
                 'name' : 'stopExperiment',
diff --git a/src/python/dm/ds_web_service/service/experimentSessionController.py b/src/python/dm/ds_web_service/service/experimentSessionController.py
index a1d664ab..5192b3f7 100755
--- a/src/python/dm/ds_web_service/service/experimentSessionController.py
+++ b/src/python/dm/ds_web_service/service/experimentSessionController.py
@@ -79,6 +79,18 @@ class ExperimentSessionController(DmSessionController):
         self.logger.debug('Returning: %s' % response)
         return response
 
+    @cherrypy.expose
+    @DmSessionController.require(DmSessionController.isAdministrator())
+    @DmSessionController.execute
+    def updateExperiment(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.updateExperiment(name).getFullJsonRep()
+        self.logger.debug('Returning: %s' % response)
+        return response
+
     @cherrypy.expose
     @DmSessionController.require(DmSessionController.isAdministrator())
     @DmSessionController.execute
diff --git a/src/python/dm/ds_web_service/service/impl/experimentManager.py b/src/python/dm/ds_web_service/service/impl/experimentManager.py
index 1649e744..55ada380 100755
--- a/src/python/dm/ds_web_service/service/impl/experimentManager.py
+++ b/src/python/dm/ds_web_service/service/impl/experimentManager.py
@@ -97,9 +97,15 @@ class ExperimentManager(Singleton):
         # Add users to group
         experimentUsers = experiment.get('experimentUsernameList', [])
         self.logger.debug('Found experiment users: %s', experimentUsers)
-        for username in experimentUsers:
-            self.platformUtility.addUserToGroup(username, experimentName)
+        self.platformUtility.setGroupUsers(experimentName, experimentUsers)
+        #for username in experimentUsers:
+        #    self.platformUtility.addUserToGroup(username, experimentName)
       
+    def updateExperimentGroupUsers(self, experiment):
+        experimentName = experiment.get('name')
+        experimentUsers = experiment.get('experimentUsernameList', [])
+        self.platformUtility.setGroupUsers(experimentName, experimentUsers)
+
     @ThreadingUtility.synchronize
     def createExperimentDataDirectory(self, experiment):
         experimentName = experiment.get('name')
diff --git a/src/python/dm/ds_web_service/service/impl/experimentSessionControllerImpl.py b/src/python/dm/ds_web_service/service/impl/experimentSessionControllerImpl.py
index 561b4d31..7958faa7 100755
--- a/src/python/dm/ds_web_service/service/impl/experimentSessionControllerImpl.py
+++ b/src/python/dm/ds_web_service/service/impl/experimentSessionControllerImpl.py
@@ -49,6 +49,13 @@ class ExperimentSessionControllerImpl(DmObjectManager):
         ExperimentManager.getInstance().createExperimentDataDirectory(experiment)
         return experiment
 
+    def updateExperiment(self, name):
+        experiment = self.experimentDbApi.getExperimentWithUsers(name)
+        if experiment.get('startDate') is None:
+            raise InvalidRequest('Experiment %s has not been started.' % name)
+        ExperimentManager.getInstance().updateExperimentGroupUsers(experiment)
+        return experiment
+
     def stopExperiment(self, name):
         experiment = self.experimentDbApi.getExperimentByName(name)
         if experiment.get('endDate') is None:
-- 
GitLab