Code cleanup. Setting resource state through specific functions
[nepi.git] / src / nepi / resources / omf / omf_api.py
index 1223ed4..dc03b93 100644 (file)
@@ -1,73 +1,80 @@
-"""
-    NEPI, a framework to manage network experiments
-    Copyright (C) 2013 INRIA
+#
+#    NEPI, a framework to manage network experiments
+#    Copyright (C) 2013 INRIA
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+#         Julien Tribino <julien.tribino@inria.fr>
 
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-
-import datetime
-import logging
 import ssl
 import sys
 import time
 import hashlib
-import nepi
 import threading
 
+from nepi.util.logger import Logger
+
 from nepi.resources.omf.omf_client import OMFClient
 from nepi.resources.omf.messages_5_4 import MessageHandler
 
-class OMFAPI(object):
+from nepi.util.timefuncs import tsformat 
+
+class OMFAPI(Logger):
     """
     .. class:: Class Args :
       
         :param slice: Xmpp Slice
-        :type slice: Str
+        :type slice: str
         :param host: Xmpp Server
-        :type host: Str
+        :type host: str
         :param port: Xmpp Port
-        :type port: Str
+        :type port: str
         :param password: Xmpp password
-        :type password: Str
+        :type password: str
         :param xmpp_root: Root of the Xmpp Topic Architecture
-        :type xmpp_root: Str
+        :type xmpp_root: str
 
     .. note::
 
-       This class is the implementation of an OMF 5.4 API. Since the version 5.4.1, the Topic Architecture start with OMF_5.4 instead of OMF used for OMF5.3
+       This class is the implementation of an OMF 5.4 API. 
+       Since the version 5.4.1, the Topic Architecture start with OMF_5.4 
+       instead of OMF used for OMF5.3
 
     """
-    def __init__(self, slice, host, port, password, xmpp_root = None):
+    def __init__(self, slice, host, port, password, xmpp_root = None, 
+            exp_id = None):
         """
     
         :param slice: Xmpp Slice
-        :type slice: Str
+        :type slice: str
         :param host: Xmpp Server
-        :type host: Str
+        :type host: str
         :param port: Xmpp Port
-        :type port: Str
+        :type port: str
         :param password: Xmpp password
-        :type password: Str
+        :type password: str
         :param xmpp_root: Root of the Xmpp Topic Architecture
-        :type xmpp_root: Str
+        :type xmpp_root: str
 
         """
-        date = datetime.datetime.now().strftime("%Y-%m-%dt%H.%M.%S")
+        super(OMFAPI, self).__init__("OMFAPI")
+        date = tsformat()
         tz = -time.altzone if time.daylight != 0 else -time.timezone
         date += "%+06.2f" % (tz / 3600) # timezone difference is in seconds
-        self._user = "%s-%s" % (slice, date)
+        self._exp_id = exp_id or date
+        self._user = "%s-%s" % (slice, self._exp_id)
         self._slice = slice
         self._host = host
         self._port = port
@@ -75,11 +82,9 @@ class OMFAPI(object):
         self._hostnames = []
         self._xmpp_root = xmpp_root or "OMF_5.4"
 
-        self._logger = logging.getLogger("nepi.omf.omfApi    ")
-        self._logger.setLevel(nepi.LOGLEVEL)
-
         # OMF xmpp client
         self._client = None
+
         # message handler
         self._message = None
 
@@ -114,7 +119,7 @@ class OMFAPI(object):
             self._message = MessageHandler(self._slice, self._user)
         else:
             msg = "Unable to connect to the XMPP server."
-            self._logger.error(msg)
+            self.error(msg)
             raise RuntimeError(msg)
 
     def _enroll_experiment(self):
@@ -132,7 +137,8 @@ class OMFAPI(object):
         """ Publish New Experiment Message
 
         """
-        address = "/%s/%s/%s/%s" % (self._host, self._xmpp_root, self._slice, self._user)
+        address = "/%s/%s/%s/%s" % (self._host, self._xmpp_root, self._slice,
+                self._user)
         #print address
         payload = self._message.newexp_function(self._user, address)
         slice_sid = "/%s/%s" % (self._xmpp_root, self._slice)
@@ -159,7 +165,8 @@ class OMFAPI(object):
         :type hostname: str
 
         """
-        return "/%s/%s/%s/%s" % (self._xmpp_root, self._slice, self._user, hostname)
+        return "/%s/%s/%s/%s" % (self._xmpp_root, self._slice, self._user, 
+                hostname)
 
     def _host_resource_id(self, hostname):
         """ Return the Topic Name as /xmpp_root/slice/resources/hostname
@@ -200,7 +207,8 @@ class OMFAPI(object):
         self._client.delete(xmpp_node)
 
     def enroll_host(self, hostname):
-        """ Create and Subscribe to the session topic and the resources corresponding to the hostname
+        """ Create and Subscribe to the session topic and the resources
+            corresponding to the hostname
 
         :param hostname: Full hrn of the node
         :type hostname: str
@@ -226,7 +234,8 @@ class OMFAPI(object):
 
         :param hostname: Full hrn of the node
         :type hostname: str
-        :param attribute: Attribute that need to be configured (often written as /net/wX/attribute, with X the interface number)
+        :param attribute: Attribute that need to be configured (
+            often written as /net/wX/attribute, with X the interface number)
         :type attribute: str
         :param value: Value of the attribute
         :type value: str
@@ -241,7 +250,8 @@ class OMFAPI(object):
 
         :param hostname: Full hrn of the node
         :type hostname: str
-        :param app_id: Application Id (Any id that represents in a unique way the application)
+        :param app_id: Application Id (Any id that represents in a unique 
+            way the application)
         :type app_id: str
         :param arguments: Arguments of the application
         :type arguments: str
@@ -251,7 +261,8 @@ class OMFAPI(object):
         :type env: str
 
         """
-        payload = self._message.execute_function(hostname, app_id, arguments, path, env)
+        payload = self._message.execute_function(hostname, app_id, arguments, 
+                path, env)
         xmpp_node =  self._host_session_id(hostname)
         self._client.publish(payload, xmpp_node)
 
@@ -286,24 +297,26 @@ class OMFAPI(object):
         
         # Wait the send queue to be empty before disconnect
         self._client.disconnect(wait=True)
-        self._logger.debug(" Disconnected from XMPP Server")
+        msg = " Disconnected from XMPP Server"
+        self.debug(msg)
 
 
 class OMFAPIFactory(object):
     """ 
     .. note::
 
-        It allows the different RM to use the same xmpp client if they use the same credentials. 
-        For the moment, it is focused on Xmpp.
+        It allows the different RM to use the same xmpp client if they use 
+        the same credentials.  For the moment, it is focused on XMPP.
 
     """
-    # use lock to avoid concurrent access to the Api list at the same times by 2 different threads
+    # use lock to avoid concurrent access to the Api list at the same times by 2 
+    # different threads
     lock = threading.Lock()
     _apis = dict()
 
     @classmethod 
-    def get_api(cls, slice, host, port, password):
-        """ Get an Api
+    def get_api(cls, slice, host, port, password, exp_id = None):
+        """ Get an OMF Api
 
         :param slice: Xmpp Slice Name
         :type slice: str
@@ -316,21 +329,22 @@ class OMFAPIFactory(object):
 
         """
         if slice and host and port and password:
-            key = cls._make_key(slice, host, port, password)
+            key = cls._make_key(slice, host, port, password, exp_id)
             cls.lock.acquire()
             if key in cls._apis:
+                #print "Api Counter : " + str(cls._apis[key]['cnt'])
                 cls._apis[key]['cnt'] += 1
                 cls.lock.release()
                 return cls._apis[key]['api']
             else :
-                omf_api = cls.create_api(slice, host, port, password)
+                omf_api = cls.create_api(slice, host, port, password, exp_id)
                 cls.lock.release()
                 return omf_api
         return None
 
     @classmethod 
-    def create_api(cls, slice, host, port, password):
-        """ Create an API if this one doesn't exist yet with this credentials
+    def create_api(cls, slice, host, port, password, exp_id):
+        """ Create an OMF API if this one doesn't exist yet with this credentials
 
         :param slice: Xmpp Slice Name
         :type slice: str
@@ -342,16 +356,16 @@ class OMFAPIFactory(object):
         :type password: str
 
         """
-        omf_api = OMFAPI(slice, host, port, password)
-        key = cls._make_key(slice, host, port, password)
+        omf_api = OMFAPI(slice, host, port, password, exp_id = exp_id)
+        key = cls._make_key(slice, host, port, password, exp_id)
         cls._apis[key] = {}
         cls._apis[key]['api'] = omf_api
         cls._apis[key]['cnt'] = 1
         return omf_api
 
     @classmethod 
-    def release_api(cls, slice, host, port, password):
-        """ Release an API with this credentials
+    def release_api(cls, slice, host, port, password, exp_id = None):
+        """ Release an OMF API with this credentials
 
         :param slice: Xmpp Slice Name
         :type slice: str
@@ -364,7 +378,7 @@ class OMFAPIFactory(object):
 
         """
         if slice and host and port and password:
-            key = cls._make_key(slice, host, port, password)
+            key = cls._make_key(slice, host, port, password, exp_id)
             if key in cls._apis:
                 cls._apis[key]['cnt'] -= 1
                 #print "Api Counter : " + str(cls._apis[key]['cnt'])