[asterisk-scf-commits] asterisk-scf/integration/configurator.git branch "retry_deux" created.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Thu Apr 12 09:35:54 CDT 2012


branch "retry_deux" has been created
        at  30e4d200128171712c9dbaab84a96c3c98bcba97 (commit)

- Log -----------------------------------------------------------------
commit 30e4d200128171712c9dbaab84a96c3c98bcba97
Author: Brent Eagles <beagles at digium.com>
Date:   Thu Apr 12 12:04:48 2012 -0230

    A very simple, straight modification for operation context... good enough
    to get going, but there may be a better way to do this. Not tested for all
    supported configuration operations (just setting so far).

diff --git a/Configurator.py b/Configurator.py
index a11a076..9a8862b 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -22,15 +22,18 @@ import sys
 
 sys.path.append('/opt/Ice-3.4/python')
 
-import ConfigParser, traceback, os, Ice, getopt
+import ConfigParser, traceback, os, Ice, getopt, uuid
 
 # Load and make the configuration interface available, we require it
-Ice.loadSlice("-I\"" + os.environ["ASTSCF_HOME"] + "\" -I\"" + Ice.getSliceDir() + "\" --all \"" + os.environ["ASTSCF_HOME"] + "/slice/slice/AsteriskSCF/System/Component/ConfigurationIf.ice\"")
-Ice.loadSlice("-I\"" + os.environ["ASTSCF_HOME"] + "\" -I\"" + Ice.getSliceDir() + "\" --all \"" + os.environ["ASTSCF_HOME"] + "/slice/slice/AsteriskSCF/Core/Discovery/ServiceLocatorIf.ice\"")
+Ice.loadSlice("-I\"" + os.environ["ASTSCF_HOME"] + "\" -I\"" + Ice.getSliceDir() + "\" --all \"" + os.environ["ASTSCF_HOME"] + "/AsteriskSCF/System/Component/ConfigurationIf.ice\"")
+Ice.loadSlice("-I\"" + os.environ["ASTSCF_HOME"] + "\" -I\"" + Ice.getSliceDir() + "\" --all \"" + os.environ["ASTSCF_HOME"] + "/AsteriskSCF/Core/Discovery/ServiceLocatorIf.ice\"")
 
 import AsteriskSCF.System.Configuration.V1
 import AsteriskSCF.Core.Discovery.V1
 
+def uuidstr():
+    return str(uuid.uuid1())
+
 # Exception class used within the configurator application
 class ConfiguratorError(Exception):
     def __init__(self, value):
@@ -207,8 +210,12 @@ class ConfiguratorApp(Ice.Application):
                 # There is a race condition here where another component could modify the groups present, but if two
                 # components are altering the configuration we are best effort to begin with
                 try:
+                    context = AsteriskSCF.System.V1.OperationContext()
+                    context.id = uuidstr()
+                    context.transactionId = context.id
+                    
                     groups = configurationService.getConfigurationGroups()
-                    configurationService.removeConfigurationGroups(groups)
+                    configurationService.removeConfigurationGroups(context, groups)
                 except:
                     print >> sys.stderr, "Configuration could not be wiped - Failed to contact component"
 		    traceback.print_exc()
@@ -218,7 +225,10 @@ class ConfiguratorApp(Ice.Application):
 
             try:
                 # print self.visitor.groups  # <- Handiest debug aid ever.
-                configurationService.setConfiguration(self.visitor.groups)
+                context = AsteriskSCF.System.V1.OperationContext()
+                context.id = uuidstr()
+                context.transactionId = context.id
+                configurationService.setConfiguration(context, self.visitor.groups)
                 print "Configuration applied"
             except:
 		print "Exception calling setConfiguration: ", sys.exc_info()[0]

commit ca857b6d911fe4defcfe25cbaec1957c14dcf17d
Author: Darren Sessions <dsessions at digium.com>
Date:   Fri Jan 13 13:47:06 2012 -0600

    Updated the Configurator python script to reflect new file paths and naming conventions. Added a quick system path append command for /opt/Ice-3.4/python to make the script work straight from the gitall/configurator directory. Added a README.txt file with a quick note about needing to set the ASTSCF_HOME env variable which is required within the script to find slice dependancies.

diff --git a/Configurator.py b/Configurator.py
index cf7c449..a11a076 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -18,11 +18,16 @@
 
 # Asterisk SCF Configurator Module
 
-import ConfigParser, traceback, os, Ice, getopt, sys
+import sys
+
+sys.path.append('/opt/Ice-3.4/python')
+
+import ConfigParser, traceback, os, Ice, getopt
 
 # Load and make the configuration interface available, we require it
-Ice.loadSlice("-I\"" + os.environ["ASTSCF_HOME"] + "\" -I\"" + Ice.getSliceDir() + "\" --all \"" + os.environ["ASTSCF_HOME"] + "/AsteriskSCF/System/Component/ConfigurationIf.ice\"")
-Ice.loadSlice("-I\"" + os.environ["ASTSCF_HOME"] + "\" -I\"" + Ice.getSliceDir() + "\" --all \"" + os.environ["ASTSCF_HOME"] + "/AsteriskSCF/Core/Discovery/ServiceLocatorIf.ice\"")
+Ice.loadSlice("-I\"" + os.environ["ASTSCF_HOME"] + "\" -I\"" + Ice.getSliceDir() + "\" --all \"" + os.environ["ASTSCF_HOME"] + "/slice/slice/AsteriskSCF/System/Component/ConfigurationIf.ice\"")
+Ice.loadSlice("-I\"" + os.environ["ASTSCF_HOME"] + "\" -I\"" + Ice.getSliceDir() + "\" --all \"" + os.environ["ASTSCF_HOME"] + "/slice/slice/AsteriskSCF/Core/Discovery/ServiceLocatorIf.ice\"")
+
 import AsteriskSCF.System.Configuration.V1
 import AsteriskSCF.Core.Discovery.V1
 
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..2f7d4ac
--- /dev/null
+++ b/README.txt
@@ -0,0 +1 @@
+Please set the 'ASTSCF_HOME' environment variable to the Asterisk SCF 'gitall' directory path.

commit 9c000ddde667e634c4bb393b190af2d20fd438d0
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Thu Sep 22 13:01:18 2011 -0500

    Make the script friendler when spaces are in the path.

diff --git a/Configurator.py b/Configurator.py
index c794980..cf7c449 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -21,8 +21,8 @@
 import ConfigParser, traceback, os, Ice, getopt, sys
 
 # Load and make the configuration interface available, we require it
-Ice.loadSlice("-I" + os.environ["ASTSCF_HOME"] + " -I" + Ice.getSliceDir() + " --all " + os.environ["ASTSCF_HOME"] + "/AsteriskSCF/System/Component/ConfigurationIf.ice")
-Ice.loadSlice("-I" + os.environ["ASTSCF_HOME"] + " -I" + Ice.getSliceDir() + " --all " + os.environ["ASTSCF_HOME"] + "/AsteriskSCF/Core/Discovery/ServiceLocatorIf.ice")
+Ice.loadSlice("-I\"" + os.environ["ASTSCF_HOME"] + "\" -I\"" + Ice.getSliceDir() + "\" --all \"" + os.environ["ASTSCF_HOME"] + "/AsteriskSCF/System/Component/ConfigurationIf.ice\"")
+Ice.loadSlice("-I\"" + os.environ["ASTSCF_HOME"] + "\" -I\"" + Ice.getSliceDir() + "\" --all \"" + os.environ["ASTSCF_HOME"] + "/AsteriskSCF/Core/Discovery/ServiceLocatorIf.ice\"")
 import AsteriskSCF.System.Configuration.V1
 import AsteriskSCF.Core.Discovery.V1
 
@@ -212,10 +212,11 @@ class ConfiguratorApp(Ice.Application):
             print "Applying configuration"
 
             try:
+                # print self.visitor.groups  # <- Handiest debug aid ever.
                 configurationService.setConfiguration(self.visitor.groups)
                 print "Configuration applied"
             except:
-                print "Configuration could not be applied - Failed to contact component"
+		print "Exception calling setConfiguration: ", sys.exc_info()[0]
 		traceback.print_exc()
 
         else:

commit 1a8be87a1573715a18281bddfbbd66148a7147e0
Author: Kevin P. Fleming <kpfleming at digium.com>
Date:   Tue Jun 21 06:59:50 2011 -0500

    Improve loading of API Slice files.
    
    * Use Ice.getSliceDir() to find the Ice-provided Slice files.
    
    * (for now) Allow an environment variable called ASTSCF_HOME to be set to
      to tell the script where to find the Asterisk SCF Slice files.

diff --git a/Configurator.py b/Configurator.py
index f379a0b..c794980 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -21,8 +21,8 @@
 import ConfigParser, traceback, os, Ice, getopt, sys
 
 # Load and make the configuration interface available, we require it
-Ice.loadSlice('-I. --all ConfigurationIf.ice')
-Ice.loadSlice('-I. -I/opt/Ice-3.4.1/slice --all ServiceLocatorIf.ice')
+Ice.loadSlice("-I" + os.environ["ASTSCF_HOME"] + " -I" + Ice.getSliceDir() + " --all " + os.environ["ASTSCF_HOME"] + "/AsteriskSCF/System/Component/ConfigurationIf.ice")
+Ice.loadSlice("-I" + os.environ["ASTSCF_HOME"] + " -I" + Ice.getSliceDir() + " --all " + os.environ["ASTSCF_HOME"] + "/AsteriskSCF/Core/Discovery/ServiceLocatorIf.ice")
 import AsteriskSCF.System.Configuration.V1
 import AsteriskSCF.Core.Discovery.V1
 

commit 277654d75b173d4b7c394f43e3ba6f66be33e4dc
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Thu May 26 10:47:47 2011 -0500

    Added traceback for the exceptions that we can't work around.

diff --git a/Configurator.py b/Configurator.py
index 831441f..f379a0b 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -18,7 +18,7 @@
 
 # Asterisk SCF Configurator Module
 
-import ConfigParser, os, Ice, getopt, sys
+import ConfigParser, traceback, os, Ice, getopt, sys
 
 # Load and make the configuration interface available, we require it
 Ice.loadSlice('-I. --all ConfigurationIf.ice')
@@ -206,6 +206,7 @@ class ConfiguratorApp(Ice.Application):
                     configurationService.removeConfigurationGroups(groups)
                 except:
                     print >> sys.stderr, "Configuration could not be wiped - Failed to contact component"
+		    traceback.print_exc()
                     return -1
 
             print "Applying configuration"
@@ -215,6 +216,7 @@ class ConfiguratorApp(Ice.Application):
                 print "Configuration applied"
             except:
                 print "Configuration could not be applied - Failed to contact component"
+		traceback.print_exc()
 
         else:
             print "No configuration to apply"

commit 5652963f45288888f1716b32d4784b89d208b8cc
Author: Joshua Colp <jcolp at digium.com>
Date:   Tue May 24 13:02:01 2011 -0300

    Output the filename of the script using the Configurator, not the Configurator filename itself.

diff --git a/Configurator.py b/Configurator.py
index 2b3f9a5..831441f 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -179,7 +179,7 @@ class ConfiguratorApp(Ice.Application):
             configurationService = AsteriskSCF.System.Configuration.V1.ConfigurationServicePrx.uncheckedCast(service)
 
         if configurationService == None:
-            print >> sys.stderr, "No configuration service to configure. For usage details please run " + __file__ + " --help"
+            print >> sys.stderr, "No configuration service to configure. For usage details please run " + sys.argv[0] + " --help"
             return -1
 
         print "Reading configuration from file " + configFile

commit 31ffb84646d9608f6ed38c088335be459244b7d3
Author: Joshua Colp <jcolp at digium.com>
Date:   Tue May 17 09:00:35 2011 -0300

    Add support for using the service locator to find a configuration service.

diff --git a/Configurator.py b/Configurator.py
index 718f16a..2b3f9a5 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -22,7 +22,9 @@ import ConfigParser, os, Ice, getopt, sys
 
 # Load and make the configuration interface available, we require it
 Ice.loadSlice('-I. --all ConfigurationIf.ice')
+Ice.loadSlice('-I. -I/opt/Ice-3.4.1/slice --all ServiceLocatorIf.ice')
 import AsteriskSCF.System.Configuration.V1
+import AsteriskSCF.Core.Discovery.V1
 
 # Exception class used within the configurator application
 class ConfiguratorError(Exception):
@@ -102,7 +104,7 @@ class OptionMapper():
 
 # Common configurator application logic
 class ConfiguratorApp(Ice.Application):
-    def __init__(self, defaultConfigFile, visitor, configurationService = None):
+    def __init__(self, defaultConfigFile, visitor, configurationService = None, serviceLocatorParams = None):
         """Common configuration utility class"""
 
         if defaultConfigFile == '':
@@ -111,6 +113,7 @@ class ConfiguratorApp(Ice.Application):
         self.defaultConfigFile = defaultConfigFile
         self.visitor = visitor
         self.configurationService = configurationService
+        self.serviceLocatorParams = serviceLocatorParams
 
     def usage(self):
         """Print usage information for the configuration utility"""
@@ -122,13 +125,15 @@ class ConfiguratorApp(Ice.Application):
         print "-h, --help              display help information"
         print "-c, --config=FILENAME   use specified configuration file instead of " + self.defaultConfigFile
         print "-p, --proxy=PROXY       use specified proxy instead of locating component"
+        print "-l, --locator=PROXY     use specified proxy for service locator"
+        print "-n, --name=NAME         use name when finding configuration service"
         print "-w, --wipe              remove existing configuration before applying new one"
 
     def run(self, args):
         """Parse options, read configuration file, produce configuration data, and submit it"""
 
         try:
-            opts, arguments = getopt.getopt(args[1:], "hc:p:w", ["help", "config=", "proxy=", "wipe"])
+            opts, arguments = getopt.getopt(args[1:], "hc:p:l:n:w", ["help", "config=", "proxy=", "locator=", "name=", "wipe"])
         except getopt.GetoptError, err:
             print str(err)
             self.usage()
@@ -137,6 +142,9 @@ class ConfiguratorApp(Ice.Application):
         configFile = self.defaultConfigFile
         configurationService = self.configurationService
         configurationWipe = False
+        configurationServiceName = ""
+        serviceLocator = None
+        serviceLocatorParams = self.serviceLocatorParams
 
         for o, a in opts:
             if o in ("-h", "--help"):
@@ -149,9 +157,27 @@ class ConfiguratorApp(Ice.Application):
             elif o in ("-p", "--proxy"):
                 configurationService = AsteriskSCF.System.Configuration.V1.ConfigurationServicePrx.checkedCast(self.communicator().stringToProxy(a))
 
+            elif o in ("-l", "--locator"):
+                serviceLocator = AsteriskSCF.Core.Discovery.V1.ServiceLocatorPrx.checkedCast(self.communicator().stringToProxy(a))
+
+            elif o in ("-n", "--name"):
+                configurationServiceName = a
+
             elif o in ("-w", "--wipe"):
                 configurationWipe = True
 
+        if serviceLocator:
+            # Populate params with the name
+            setattr(serviceLocatorParams, "name", configurationServiceName)
+
+            try:
+                service = serviceLocator.locate(serviceLocatorParams)
+            except AsteriskSCF.Core.Discovery.V1.ServiceNotFound:
+                print >> sys.stderr, "Configuration service could not be found in service locator."
+                return -1
+
+            configurationService = AsteriskSCF.System.Configuration.V1.ConfigurationServicePrx.uncheckedCast(service)
+
         if configurationService == None:
             print >> sys.stderr, "No configuration service to configure. For usage details please run " + __file__ + " --help"
             return -1

commit 3af0760b0e3d33267a7eaaf02c8e63a17bacc729
Author: Joshua Colp <jcolp at digium.com>
Date:   Mon Apr 11 14:47:48 2011 -0300

    Tweak message so that people can know to specify --help for usage details if nothing is specified.

diff --git a/Configurator.py b/Configurator.py
index 2b1c5da..718f16a 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -153,7 +153,7 @@ class ConfiguratorApp(Ice.Application):
                 configurationWipe = True
 
         if configurationService == None:
-            print >> sys.stderr, "No configuration service to configure."
+            print >> sys.stderr, "No configuration service to configure. For usage details please run " + __file__ + " --help"
             return -1
 
         print "Reading configuration from file " + configFile

commit 15138e4da8d4a3eb286a4d3bd60a564608d1349f
Author: Joshua Colp <jcolp at digium.com>
Date:   Sun Mar 20 11:16:47 2011 -0300

    I do believe we are in the year 2011 these days.

diff --git a/Configurator.py b/Configurator.py
index 4c3d2fc..2b1c5da 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -3,7 +3,7 @@
 #
 # Asterisk SCF -- An open-source communications framework.
 #
-# Copyright (C) 2010, Digium, Inc.
+# Copyright (C) 2011, Digium, Inc.
 #
 # See http://www.asterisk.org for more information about
 # the Asterisk SCF project. Please do not directly contact

commit 99764b169d9f01c407605797b7e1903a5007699c
Author: Joshua Colp <jcolp at digium.com>
Date:   Sun Mar 20 11:08:47 2011 -0300

    Incorporate even more code review feedback.

diff --git a/Configurator.py b/Configurator.py
index 84a45a4..4c3d2fc 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -1,5 +1,21 @@
 #!/usr/bin/env python
 
+#
+# Asterisk SCF -- An open-source communications framework.
+#
+# Copyright (C) 2010, Digium, Inc.
+#
+# See http://www.asterisk.org for more information about
+# the Asterisk SCF project. Please do not directly contact
+# any of the maintainers of this project for assistance;
+# the project provides a web site, mailing lists and IRC
+# channels for your use.
+#
+# This program is free software, distributed under the terms of
+# the GNU General Public License Version 2. See the LICENSE.txt file
+# at the top of the source tree.
+#
+
 # Asterisk SCF Configurator Module
 
 import ConfigParser, os, Ice, getopt, sys
@@ -45,18 +61,19 @@ class OptionMapper():
 
     def map(self, option, object, item, item_name, method, default = None):
         setattr(object, item, default)
-        self.options[option] = [ object, item, item_name, method, default ]
+        self.options[option] = { 'object': object, 'item': item, 'item_name': item_name, 'method': method, 'default': default }
 
     def execute(self, group, section, option):
         """Map options to configuration items based on options set"""
         try:
-            object = self.options[option][0]
+            object = self.options[option]['object']
         except:
             return
-        item = self.options[option][1]
-        item_name = self.options[option][2]
-        method = self.options[option][3]
-        default = self.options[option][4]
+
+        item = self.options[option]['item']
+        item_name = self.options[option]['item_name']
+        method = self.options[option]['method']
+        default = self.options[option]['default']
 
         try:
             setattr(object, item, method(section, option))
@@ -77,8 +94,8 @@ class OptionMapper():
     def finish(self, group):
         """Finish mapping options by finding ones that should have a value but do not"""
         for option in self.options:
-            item = self.options[option][1]
-            default = self.options[option][4]
+            item = self.options[option]['item']
+            default = self.options[option]['default']
             if default == None:
                 if item == None:
                     print "Option '" + option + "' requires a value to be set and no default value exists."

commit a9710935203651fdbe13bd2bd147bdc3c5df3a4f
Author: Joshua Colp <jcolp at digium.com>
Date:   Sun Mar 20 10:59:24 2011 -0300

    Incorporate feedback from code review.

diff --git a/Configurator.py b/Configurator.py
index 8bef119..84a45a4 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -2,7 +2,7 @@
 
 # Asterisk SCF Configurator Module
 
-import ConfigParser, os, Ice, getopt
+import ConfigParser, os, Ice, getopt, sys
 
 # Load and make the configuration interface available, we require it
 Ice.loadSlice('-I. --all ConfigurationIf.ice')
@@ -33,7 +33,7 @@ class SectionVisitors():
 
     def visit_unsupported(self, config, section):
         """Handle an unsupported configuration section"""
-        print "Unsupported configuration section " + section
+        print >> sys.stderr, "Unsupported configuration section " + section
 
 # Common option to item mapper implementation
 class OptionMapper():
@@ -136,8 +136,8 @@ class ConfiguratorApp(Ice.Application):
                 configurationWipe = True
 
         if configurationService == None:
-            print "No configuration service to configure."
-            return 0
+            print >> sys.stderr, "No configuration service to configure."
+            return -1
 
         print "Reading configuration from file " + configFile
         config = ConfigParser.ConfigParser()
@@ -146,8 +146,8 @@ class ConfiguratorApp(Ice.Application):
         try:
             config.readfp(open(configFile))
         except IOError:
-            print "Specified configuration file " + configFile + " could not be loaded."
-            return 0
+            print >> sys.stderr, "Specified configuration file " + configFile + " could not be loaded."
+            return -1
 
         print "Building configuration changes to send to component"
         for section in config.sections():
@@ -162,8 +162,8 @@ class ConfiguratorApp(Ice.Application):
                     groups = configurationService.getConfigurationGroups()
                     configurationService.removeConfigurationGroups(groups)
                 except:
-                    print "Configuration could not be wiped - Failed to contact component"
-                    return 0
+                    print >> sys.stderr, "Configuration could not be wiped - Failed to contact component"
+                    return -1
 
             print "Applying configuration"
 

commit 38dd03fdce2ff014ad6de91788439b71af0e5f24
Author: Joshua Colp <jcolp at digium.com>
Date:   Wed Mar 2 10:50:34 2011 -0400

    Don't require every option in a config file to be mapped.

diff --git a/Configurator.py b/Configurator.py
index 7737542..8bef119 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -49,7 +49,10 @@ class OptionMapper():
 
     def execute(self, group, section, option):
         """Map options to configuration items based on options set"""
-        object = self.options[option][0]
+        try:
+            object = self.options[option][0]
+        except:
+            return
         item = self.options[option][1]
         item_name = self.options[option][2]
         method = self.options[option][3]

commit eaafaf0a795eedeb446b612217f5970b49340dbc
Author: Joshua Colp <jcolp at digium.com>
Date:   Tue Mar 1 17:14:12 2011 -0400

    Use setattr to set the value of the variable on the object and not the variable holding where the object is.

diff --git a/Configurator.py b/Configurator.py
index 04061bf..7737542 100755
--- a/Configurator.py
+++ b/Configurator.py
@@ -43,19 +43,20 @@ class OptionMapper():
         """Generic class meant to perform option to item mapping"""
         self.options = { }
 
-    def map(self, option, item, item_name, method, default = None):
-        item = default
-        self.options[option] = [ item, item_name, method, default ]
+    def map(self, option, object, item, item_name, method, default = None):
+        setattr(object, item, default)
+        self.options[option] = [ object, item, item_name, method, default ]
 
     def execute(self, group, section, option):
         """Map options to configuration items based on options set"""
-        item = self.options[option][0]
-        item_name = self.options[option][1]
-        method = self.options[option][2]
-        default = self.options[option][3]
+        object = self.options[option][0]
+        item = self.options[option][1]
+        item_name = self.options[option][2]
+        method = self.options[option][3]
+        default = self.options[option][4]
 
         try:
-            item = method(section, option)
+            setattr(object, item, method(section, option))
 
         except ValueError:
             # This is not a fatal error since we just use the default value.
@@ -63,18 +64,18 @@ class OptionMapper():
                 print "The specified value for option '" + option + "' is not valid and no default value exists."
             else:
                 print "The specified value for option '" + option + "' is not valid. Using default value."
-                item = default
+                setattr(object, item, default)
 
         # This has the potential to overwrite an existing item but this is done on purpose so that
         # configuration options that all map to a single item can happily exist
         if item != None:
-            group.configurationItems[item_name] = item
+            group.configurationItems[item_name] = object
 
     def finish(self, group):
         """Finish mapping options by finding ones that should have a value but do not"""
         for option in self.options:
-            item = self.options[option][0]
-            default = self.options[option][3]
+            item = self.options[option][1]
+            default = self.options[option][4]
             if default == None:
                 if item == None:
                     print "Option '" + option + "' requires a value to be set and no default value exists."
@@ -126,7 +127,7 @@ class ConfiguratorApp(Ice.Application):
                 configFile = a
 
             elif o in ("-p", "--proxy"):
-                configurationService = AsteriskSCF.System.Configuration.V1.ConfigurationServicePrx.uncheckedCast(self.communicator().stringToProxy(a))
+                configurationService = AsteriskSCF.System.Configuration.V1.ConfigurationServicePrx.checkedCast(self.communicator().stringToProxy(a))
 
             elif o in ("-w", "--wipe"):
                 configurationWipe = True
diff --git a/ExampleConfigurator.py b/ExampleConfigurator.py
index bf53cdb..ac27850 100755
--- a/ExampleConfigurator.py
+++ b/ExampleConfigurator.py
@@ -20,12 +20,12 @@ class ExampleSectionVisitors(Configurator.SectionVisitors):
         mapper = Configurator.OptionMapper()
 
         # Enable is easy
-        mapper.map('enable',  AsteriskSCF.System.Configuration.Example.V1.EnableItem().enabled, 'enabled', config.getboolean, False)
+        mapper.map('enable',  AsteriskSCF.System.Configuration.Example.V1.EnableItem(), 'enabled', 'enabled', config.getboolean, False)
 
         # What will be the name and how many of them?
         item = AsteriskSCF.System.Configuration.Example.V1.InstanceInfoItem()
-        mapper.map('name', item.name, 'instance_info', config.get, None)
-        mapper.map('instances', item.num, 'instance_info', config.getint, 1)
+        mapper.map('name', item, 'name', 'instance_info', config.get, None)
+        mapper.map('instances', item, 'num', 'instance_info', config.getint, 1)
 
         # Map all the options to the corresponding items and stuff them in the group!
         for option in config.options(section):
@@ -42,8 +42,8 @@ class ExampleSectionVisitors(Configurator.SectionVisitors):
 
         # Create an option mapper, put our options in, and map them
         mapper = Configurator.OptionMapper()
-        mapper.map('ipv4', AsteriskSCF.System.Configuration.Example.V1.EnableItem().enabled, 'ipv4_enabled', config.getboolean, False)
-        mapper.map('ipv6', AsteriskSCF.System.Configuration.Example.V1.EnableItem().enabled, 'ipv6_enabled', config.getboolean, False)
+        mapper.map('ipv4', AsteriskSCF.System.Configuration.Example.V1.EnableItem(), 'enabled', 'ipv4_enabled', config.getboolean, False)
+        mapper.map('ipv6', AsteriskSCF.System.Configuration.Example.V1.EnableItem(), 'enabled', 'ipv6_enabled', config.getboolean, False)
         for option in config.options(section):
             mapper.execute(group, section, option)
 

commit 1e20913bf7364a4f91beadc7e94934472a55204a
Author: Joshua Colp <jcolp at digium.com>
Date:   Fri Feb 18 09:01:30 2011 -0400

    Add Configurator python module with example.

diff --git a/Configurator.py b/Configurator.py
new file mode 100755
index 0000000..04061bf
--- /dev/null
+++ b/Configurator.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python
+
+# Asterisk SCF Configurator Module
+
+import ConfigParser, os, Ice, getopt
+
+# Load and make the configuration interface available, we require it
+Ice.loadSlice('-I. --all ConfigurationIf.ice')
+import AsteriskSCF.System.Configuration.V1
+
+# Exception class used within the configurator application
+class ConfiguratorError(Exception):
+    def __init__(self, value):
+        self.value = value
+
+    def __str__(self):
+        return repr(self.value)
+
+# Common section visitor pattern implementation
+class SectionVisitors():
+    def __init__(self):
+        """Generic class meant to be inherited from for section visitors"""
+        self.groups = []
+
+    def visit(self, config, section):
+        """Execute the visit_ function corresponding to the section name"""
+        try:
+            method = getattr(self, 'visit_' + section)
+        except AttributeError:
+            self.visit_unsupported(config, section)
+        else:
+            method(config, section);
+
+    def visit_unsupported(self, config, section):
+        """Handle an unsupported configuration section"""
+        print "Unsupported configuration section " + section
+
+# Common option to item mapper implementation
+class OptionMapper():
+    options = { }
+
+    def __init(self):
+        """Generic class meant to perform option to item mapping"""
+        self.options = { }
+
+    def map(self, option, item, item_name, method, default = None):
+        item = default
+        self.options[option] = [ item, item_name, method, default ]
+
+    def execute(self, group, section, option):
+        """Map options to configuration items based on options set"""
+        item = self.options[option][0]
+        item_name = self.options[option][1]
+        method = self.options[option][2]
+        default = self.options[option][3]
+
+        try:
+            item = method(section, option)
+
+        except ValueError:
+            # This is not a fatal error since we just use the default value.
+            if default == None:
+                print "The specified value for option '" + option + "' is not valid and no default value exists."
+            else:
+                print "The specified value for option '" + option + "' is not valid. Using default value."
+                item = default
+
+        # This has the potential to overwrite an existing item but this is done on purpose so that
+        # configuration options that all map to a single item can happily exist
+        if item != None:
+            group.configurationItems[item_name] = item
+
+    def finish(self, group):
+        """Finish mapping options by finding ones that should have a value but do not"""
+        for option in self.options:
+            item = self.options[option][0]
+            default = self.options[option][3]
+            if default == None:
+                if item == None:
+                    print "Option '" + option + "' requires a value to be set and no default value exists."
+
+# Common configurator application logic
+class ConfiguratorApp(Ice.Application):
+    def __init__(self, defaultConfigFile, visitor, configurationService = None):
+        """Common configuration utility class"""
+
+        if defaultConfigFile == '':
+            raise ConfiguratorError('Configuration utility implementation issue - No default configuration filename specified.')
+
+        self.defaultConfigFile = defaultConfigFile
+        self.visitor = visitor
+        self.configurationService = configurationService
+
+    def usage(self):
+        """Print usage information for the configuration utility"""
+
+        print "Usage: " + self.appName() + " [--config=filename] [--proxy=stringified configuration service proxy] [--wipe]"
+        print "Push a configuration to a component."
+        print ""
+        print "Mandatory arguments to long options are mandatory for short options too."
+        print "-h, --help              display help information"
+        print "-c, --config=FILENAME   use specified configuration file instead of " + self.defaultConfigFile
+        print "-p, --proxy=PROXY       use specified proxy instead of locating component"
+        print "-w, --wipe              remove existing configuration before applying new one"
+
+    def run(self, args):
+        """Parse options, read configuration file, produce configuration data, and submit it"""
+
+        try:
+            opts, arguments = getopt.getopt(args[1:], "hc:p:w", ["help", "config=", "proxy=", "wipe"])
+        except getopt.GetoptError, err:
+            print str(err)
+            self.usage()
+            return 1
+
+        configFile = self.defaultConfigFile
+        configurationService = self.configurationService
+        configurationWipe = False
+
+        for o, a in opts:
+            if o in ("-h", "--help"):
+                self.usage()
+                return 1
+
+            elif o in ("-c", "--config"):
+                configFile = a
+
+            elif o in ("-p", "--proxy"):
+                configurationService = AsteriskSCF.System.Configuration.V1.ConfigurationServicePrx.uncheckedCast(self.communicator().stringToProxy(a))
+
+            elif o in ("-w", "--wipe"):
+                configurationWipe = True
+
+        if configurationService == None:
+            print "No configuration service to configure."
+            return 0
+
+        print "Reading configuration from file " + configFile
+        config = ConfigParser.ConfigParser()
+
+        # This purposely uses open and readfp so that the file is required to be present
+        try:
+            config.readfp(open(configFile))
+        except IOError:
+            print "Specified configuration file " + configFile + " could not be loaded."
+            return 0
+
+        print "Building configuration changes to send to component"
+        for section in config.sections():
+            self.visitor.visit(config, section)
+
+        if self.visitor.groups:
+            if configurationWipe == True:
+                print "Wiping existing configuration before applying changes"
+                # There is a race condition here where another component could modify the groups present, but if two
+                # components are altering the configuration we are best effort to begin with
+                try:
+                    groups = configurationService.getConfigurationGroups()
+                    configurationService.removeConfigurationGroups(groups)
+                except:
+                    print "Configuration could not be wiped - Failed to contact component"
+                    return 0
+
+            print "Applying configuration"
+
+            try:
+                configurationService.setConfiguration(self.visitor.groups)
+                print "Configuration applied"
+            except:
+                print "Configuration could not be applied - Failed to contact component"
+
+        else:
+            print "No configuration to apply"
+
+        return 0
diff --git a/Example.config b/Example.config
new file mode 100644
index 0000000..9ca996e
--- /dev/null
+++ b/Example.config
@@ -0,0 +1,9 @@
+[general]
+enable=yes
+instances=10
+
+[network]
+ipv6=never ever
+ipv4=yes
+
+[bob]
diff --git a/ExampleConfigurationIf.ice b/ExampleConfigurationIf.ice
new file mode 100644
index 0000000..422deba
--- /dev/null
+++ b/ExampleConfigurationIf.ice
@@ -0,0 +1,71 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+#include "ConfigurationIf.ice"
+
+module AsteriskSCF
+{
+
+module System
+{
+
+module Configuration
+{
+
+module Example
+{
+
+["suppress"]
+module V1
+{
+
+   /* General configuration group for items that do not belong in any specific group */
+   class GeneralGroup extends AsteriskSCF::System::Configuration::V1::ConfigurationGroup
+   {
+   };
+
+   /* Network configuration group for network specific items */
+   class NetworkGroup extends AsteriskSCF::System::Configuration::V1::ConfigurationGroup
+   {
+   };
+
+   /* Simple enable and disable item */
+   class EnableItem extends AsteriskSCF::System::Configuration::V1::ConfigurationItem
+   {
+      bool enabled;
+   };
+
+   /* Instance information item */
+   class InstanceInfoItem extends AsteriskSCF::System::Configuration::V1::ConfigurationItem
+   {
+      /* Name of the instances */
+      string name;
+
+      /* How many there should be */
+      int num;
+   };
+
+}; /* End of namespace V1 */
+
+}; /* End of namespace Example */
+
+}; /* End of namespace Configuration */
+
+}; /* End of namespace System */
+
+}; /* End of namespace AsteriskSCF */
diff --git a/ExampleConfigurator.py b/ExampleConfigurator.py
new file mode 100755
index 0000000..bf53cdb
--- /dev/null
+++ b/ExampleConfigurator.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+
+# Example configurator
+
+# Bring in the common configuration infrastructure
+import Ice, Configurator, sys
+
+# Load our component specific configuration definitions
+Ice.loadSlice('-I. --all ExampleConfigurationIf.ice')
+import AsteriskSCF.System.Configuration.Example.V1
+
+# Add our own visitor implementations for the sections we support
+class ExampleSectionVisitors(Configurator.SectionVisitors):
+    def visit_general(self, config, section):
+        # Create the general group where items from this section will go
+        group = AsteriskSCF.System.Configuration.Example.V1.GeneralGroup()
+        group.configurationItems = { }
+
+        # Create an option mapper and make it aware of the options and their mappings
+        mapper = Configurator.OptionMapper()
+
+        # Enable is easy
+        mapper.map('enable',  AsteriskSCF.System.Configuration.Example.V1.EnableItem().enabled, 'enabled', config.getboolean, False)
+
+        # What will be the name and how many of them?
+        item = AsteriskSCF.System.Configuration.Example.V1.InstanceInfoItem()
+        mapper.map('name', item.name, 'instance_info', config.get, None)
+        mapper.map('instances', item.num, 'instance_info', config.getint, 1)
+
+        # Map all the options to the corresponding items and stuff them in the group!
+        for option in config.options(section):
+            mapper.execute(group, section, option)
+        mapper.finish(group)
+
+        # Add the general group to the groups that will be pushed to the component
+        self.groups.append(group)
+
+    def visit_network(self, config, section):
+        # Create the network group where items from this section will go
+        group = AsteriskSCF.System.Configuration.Example.V1.NetworkGroup()
+        group.configurationItems = { }
+
+        # Create an option mapper, put our options in, and map them
+        mapper = Configurator.OptionMapper()
+        mapper.map('ipv4', AsteriskSCF.System.Configuration.Example.V1.EnableItem().enabled, 'ipv4_enabled', config.getboolean, False)
+        mapper.map('ipv6', AsteriskSCF.System.Configuration.Example.V1.EnableItem().enabled, 'ipv6_enabled', config.getboolean, False)
+        for option in config.options(section):
+            mapper.execute(group, section, option)
+
+        mapper.finish(group)
+
+        # Add the network group to the groups that will be pushed to the component
+        self.groups.append(group)
+
+    def visit_unsupported(self, config, section):
+        # If this function is not defined then the configurator will simply print an unsupported option message
+        print "Have unsupported option, should I create some sort of endpoint?"
+
+# Make a configurator application and let it run
+app = Configurator.ConfiguratorApp('Example.config', ExampleSectionVisitors())
+sys.exit(app.main(sys.argv))

-----------------------------------------------------------------------


-- 
asterisk-scf/integration/configurator.git



More information about the asterisk-scf-commits mailing list