PageRenderTime 18ms CodeModel.GetById 10ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/lib/python/indra/ipc/servicebuilder.py

https://bitbucket.org/lindenlab/viewer-beta/
Python | 134 lines | 124 code | 0 blank | 10 comment | 0 complexity | 0e7bb9bf4ccc64c846d26f8f5da1346f MD5 | raw file
  1"""\
  2@file servicebuilder.py
  3@author Phoenix
  4@brief Class which will generate service urls.
  5
  6$LicenseInfo:firstyear=2007&license=mit$
  7
  8Copyright (c) 2007-2009, Linden Research, Inc.
  9
 10Permission is hereby granted, free of charge, to any person obtaining a copy
 11of this software and associated documentation files (the "Software"), to deal
 12in the Software without restriction, including without limitation the rights
 13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 14copies of the Software, and to permit persons to whom the Software is
 15furnished to do so, subject to the following conditions:
 16
 17The above copyright notice and this permission notice shall be included in
 18all copies or substantial portions of the Software.
 19
 20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 26THE SOFTWARE.
 27$/LicenseInfo$
 28"""
 29
 30from indra.base import config
 31from indra.ipc import llsdhttp
 32from indra.ipc import russ
 33
 34# *NOTE: agent presence relies on this variable existing and being current, it is a huge hack
 35services_config = {}
 36try:
 37    services_config = llsdhttp.get(config.get('services-config'))
 38except:
 39    pass
 40
 41_g_builder = None
 42def _builder():
 43    global _g_builder
 44    if _g_builder is None:
 45        _g_builder = ServiceBuilder()
 46    return _g_builder
 47
 48def build(name, context={}, **kwargs):
 49    """ Convenience method for using a global, singleton, service builder.  Pass arguments either via a dict or via python keyword arguments, or both!
 50
 51    Example use:
 52     > context = {'channel':'Second Life Release', 'version':'1.18.2.0'}
 53     > servicebuilder.build('version-manager-version', context)
 54       'http://int.util.vaak.lindenlab.com/channel/Second%20Life%20Release/1.18.2.0'
 55     > servicebuilder.build('version-manager-version', channel='Second Life Release', version='1.18.2.0')
 56       'http://int.util.vaak.lindenlab.com/channel/Second%20Life%20Release/1.18.2.0'
 57     > servicebuilder.build('version-manager-version', context, version='1.18.1.2')
 58       'http://int.util.vaak.lindenlab.com/channel/Second%20Life%20Release/1.18.1.2'
 59    """
 60    global _g_builder
 61    if _g_builder is None:
 62        _g_builder = ServiceBuilder()
 63    return _g_builder.buildServiceURL(name, context, **kwargs)
 64
 65def build_path(name, context={}, **kwargs):
 66    context = context.copy()  # shouldn't modify the caller's dictionary
 67    context.update(kwargs)
 68    return _builder().buildPath(name, context)
 69
 70class ServiceBuilder(object):
 71    def __init__(self, services_definition = services_config):
 72        """\
 73        @brief
 74        @brief Create a ServiceBuilder.
 75        @param services_definition Complete services definition, services.xml.
 76        """
 77        # no need to keep a copy of the services section of the
 78        # complete services definition, but it doesn't hurt much.
 79        self.services = services_definition['services']
 80        self.builders = {}
 81        for service in self.services:
 82            service_builder = service.get('service-builder')
 83            if not service_builder:
 84                continue
 85            if isinstance(service_builder, dict):
 86                # We will be constructing several builders
 87                for name, builder in service_builder.iteritems():
 88                    full_builder_name = service['name'] + '-' + name
 89                    self.builders[full_builder_name] = builder
 90            else:
 91                self.builders[service['name']] = service_builder
 92
 93    def buildPath(self, name, context):
 94        """\
 95        @brief given the environment on construction, return a service path.
 96        @param name The name of the service.
 97        @param context A dict of name value lookups for the service.
 98        @returns Returns the 
 99        """
100        return russ.format(self.builders[name], context)
101
102    def buildServiceURL(self, name, context={}, **kwargs):
103        """\
104        @brief given the environment on construction, return a service URL.
105        @param name The name of the service.
106        @param context A dict of name value lookups for the service.
107        @param kwargs Any keyword arguments are treated as members of the
108            context, this allows you to be all 31337 by writing shit like:
109            servicebuilder.build('name', param=value)
110        @returns Returns the 
111        """
112        context = context.copy()  # shouldn't modify the caller's dictionary
113        context.update(kwargs)
114        base_url = config.get('services-base-url')
115        svc_path = russ.format(self.builders[name], context)
116        return base_url + svc_path
117
118
119def on_in(query_name, host_key, schema_key):
120    """\
121    @brief Constructs an on/in snippet (for running named queries)
122    from a schema name and two keys referencing values stored in
123    indra.xml.
124
125    @param query_name Name of the query.
126    @param host_key Logical name of destination host.  Will be
127        looked up in indra.xml.
128    @param schema_key Logical name of destination schema.  Will
129        be looked up in indra.xml.
130    """
131    return "on/config:%s/in/config:%s/%s" % (host_key.strip('/'),
132                                             schema_key.strip('/'),
133                                             query_name.lstrip('/'))
134