Esempio n. 1
0
 def set_metadata(self, metadata):
     metadata = util.build_recursive(metadata)
     if 'Metadata' in metadata:
         metadata = metadata['Metadata']
     self['Metadata'] = util.dict_merge(self.get('Metadata', {}),
                                        metadata)
     self.dirty_children()
Esempio n. 2
0
 def set_metadata(self, metadata):
     metadata = util.build_recursive(metadata)
     if 'Metadata' in metadata:
         metadata = metadata['Metadata']
     self['Metadata'] = util.dict_merge(self.get('Metadata', {}), metadata)
     self.dirty_children()
Esempio n. 3
0
def load(file, sections=[], **instargs):
    """Create a sMAP instance based on the representation stored in a file.

The configuration file contains sections which refer to either
reporting instances, or paths in the sMAP heirarchy.  Any section
whose name starts with ``/`` is treated as a resource name; sections
starting with ``report`` are treated as reports.

The file must contain at least one section named ``/``, which must
contain a ``uuid`` key to set the root identifier for the source.

:param string file: filename of the configuration file
:param instargs: arguments passed to the :py:class:`~smap.core.SmapInstance` constructor.
:return smap.core.SmapInstance: the created instancev
:raise smap.loader.SmapLoadError: an error is encountered processing the file
:raise smap.core.SmapError: some other error is encountered validating the loaded object 
    """
    found = None
    for l in ['', os.getcwd(), sys.prefix]:
      path = os.path.join(l, file)
      if os.path.isfile(path):
        found = path
    if not found:
      raise Exception("Config file %s not found." % file)
    print "Loading config file:", found

    conf = configobj.ConfigObj(found, indent_type='  ')

    # if there's a server section, override the default server
    # configuration with that
    if 'server' in conf:
        smapconf.SERVER = util.dict_merge(smapconf.SERVER, 
                                          dict(((k.lower(), v) for (k, v) in 
                                                conf['server'].iteritems())))
    if 'logging' in conf:
        smapconf.LOGGING = util.dict_merge(smapconf.LOGGING, 
                                           dict(((k.lower(), v) for (k, v) in 
                                                 conf['logging'].iteritems())))

    # we need the root to have a uuid
    inst = core.SmapInstance(conf['/']['uuid'], **instargs)
    inst.loading = True
    reports = []

    for s in conf:
        print "Loading section", s
        if s.startswith('report'):
            resource = conf[s].get('ReportResource', '/+')
            format = conf[s].get('Format', 'json')
            max_age = conf[s].get('MaxAge', None)
            max_age = int(max_age) if max_age != None else None

            dest = [conf[s]['ReportDeliveryLocation']]
            for i in xrange(0, 10):
                if 'ReportDeliveryLocation%i' % i in conf[s]:
                    dest.append(conf[s]['ReportDeliveryLocation%i' % i])

            reportinst = {
                'ReportDeliveryLocation' : dest,
                'ReportResource' : resource,
                'Format': format,
                'uuid' : inst.uuid(s),
                'MaxAge' : max_age,
                }
            for o in ['MinPeriod', 'MaxPeriod']:
                if o in conf[s]:
                    reportinst[o] = conf[s][o]
            for o in ['ClientCertificateFile', 'ClientPrivateKeyFile', 'CAFile']:
                if o in conf[s]:
                    reportinst[i] = os.path.expanduser(conf[s][o])

            reports.append(reportinst)
            continue
                      
        elif not s.startswith('/'):
            # path sections must start with a '/'
            # other sections might be present and could be parsed by
            # other parts of the program
            print "Warning: skipping section", s, "since it does not begin with a '/'"
            continue
        elif len(sections) and not util.norm_path(s) in sections: 
            # skip all but the listed sections if we were asked to
            continue

        s = util.norm_path(s)

        # build the UUID for the item
        props = util.build_recursive(dict(conf[s].items()))
        id = None
        if 'uuid' in conf[s]:
            key = None
            id = uuid.UUID(conf[s]['uuid'])
        elif 'key' in conf[s]:
            key = conf[s]['key']
        else:
            # default to the path if 
            key = s
        if key:
            id = inst.uuid(key)
            # raise SmapLoadError("Every config file section must have a uuid or a key!")

        # create the timeseries or collection
        if (s == '/' or 
            conf[s].get("type", None) == 'Collection' or 
            inst.get_collection(s) != None):
            if s == '/':
                c = inst.get_collection('/')
            elif inst.get_collection(s) != None:
                # sometimes you will have collections created twice,
                # for instance if a driver creates it and then we want
                # to tag it with metadata
                c = inst.get_collection(s)
            else:
                c = core.Collection(s, inst)
                inst.add_collection(s, c)
        elif conf[s].get("type", "Timeseries") == "Timeseries":
            if inst.get_timeseries(s) != None:
                c = inst.get_timeseries(s)
            else:   
                try:
                    props['Properties']['UnitofMeasure']
                except KeyError:
                    raise SmapLoadError("A Timeseries must have at least "
                                        "the Properites/UnitofMeasure key")
                
                # the Timeseries uses defaults if the conf file doesn't
                # contain the right sections.
                c = core.Timeseries(id, props['Properties']['UnitofMeasure'],
                                    data_type=props['Properties'].get('ReadingType', 
                                                                      core.Timeseries.DEFAULTS['Properties/ReadingType']),
                                    timezone=props['Properties'].get('Timezone', 
                                                                     core.Timeseries.DEFAULTS['Properties/Timezone']),
                                    buffersz=int(props.get('BufferSize', core.Timeseries.DEFAULTS['BufferSize'])))
                inst.add_timeseries(s, c)
        else:
            if not id:
                raise SmapLoadError("A driver must have a key or uuid to generate a namespace")
            
            # load a new driver manager layer
            newdrv = driver.SmapDriver.get_driver(inst, conf[s]['type'], s, id)
            # create a collection and add it at the attachment point
            c = inst.get_collection(s)
            if not c:
                c = core.Collection(s, inst)
                inst.add_collection(s, c)
            
            # Add config file specified checkers for the driver
            check = checkers.get(inst, newdrv, conf[s])
            if check:
                inst.checkers.append(check)

            # get the driver to add its points
            newdrv.setup(conf[s])

        # Metadata and Description are shared between both Collections
        # and Timeseries
        if props.has_key('Metadata'):
            # the driver may have added metadata; however config file
            # metadata overrides it
            c['Metadata'] = util.dict_merge(c.get('Metadata', {}),
                                            props['Metadata'])
        if props.has_key('Description'):
            c['Description'] = props['Description']
        if key:
            setattr(c, 'key', key)

    # since the sections could come in any order, update the reporting
    # instance to make sure all the topics are set right.
    for reportinst in reports:
        if not inst.reports.update_report(reportinst):
            inst.reports.add_report(reportinst)
    inst.reports.update_subscriptions()
    inst.loading = False
    return inst
Esempio n. 4
0
def load(file, sections=[], **instargs):
    """Create a sMAP instance based on the representation stored in a file.

The configuration file contains sections which refer to either
reporting instances, or paths in the sMAP heirarchy.  Any section
whose name starts with ``/`` is treated as a resource name; sections
starting with ``report`` are treated as reports.

The file must contain at least one section named ``/``, which must
contain a ``uuid`` key to set the root identifier for the source.

:param string file: filename of the configuration file
:param instargs: arguments passed to the :py:class:`~smap.core.SmapInstance` constructor.
:return smap.core.SmapInstance: the created instancev
:raise smap.loader.SmapLoadError: an error is encountered processing the file
:raise smap.core.SmapError: some other error is encountered validating the loaded object 
    """
    found = None
    for l in ['', os.getcwd(), sys.prefix]:
        path = os.path.join(l, file)
        if os.path.isfile(path):
            found = path
    if not found:
        raise Exception("Config file %s not found." % file)
    print "Loading config file:", found

    conf = configobj.ConfigObj(found, indent_type='  ')

    # if there's a server section, override the default server
    # configuration with that
    if 'server' in conf:
        smapconf.SERVER = util.dict_merge(
            smapconf.SERVER,
            dict(((k.lower(), v) for (k, v) in conf['server'].iteritems())))

    # we need the root to have a uuid
    inst = core.SmapInstance(conf['/']['uuid'], **instargs)
    inst.loading = True
    reports = []

    for s in conf:
        print "Loading section", s
        if s.startswith('report'):
            resource = conf[s].get('ReportResource', '/+')
            format = conf[s].get('Format', 'json')
            max_age = conf[s].get('MaxAge', None)
            max_age = int(max_age) if max_age != None else None

            dest = [conf[s]['ReportDeliveryLocation']]
            for i in xrange(0, 10):
                if 'ReportDeliveryLocation%i' % i in conf[s]:
                    dest.append(conf[s]['ReportDeliveryLocation%i' % i])

            reportinst = {
                'ReportDeliveryLocation': dest,
                'ReportResource': resource,
                'Format': format,
                'uuid': inst.uuid(s),
                'MaxAge': max_age,
            }
            for o in ['MinPeriod', 'MaxPeriod']:
                if o in conf[s]:
                    reportinst[o] = conf[s][o]
            for o in [
                    'ClientCertificateFile', 'ClientPrivateKeyFile', 'CAFile'
            ]:
                if o in conf[s]:
                    reportinst[i] = os.path.expanduser(conf[s][o])

            reports.append(reportinst)
            continue

        elif not s.startswith('/'):
            # path sections must start with a '/'
            # other sections might be present and could be parsed by
            # other parts of the program
            print "Warning: skipping section", s, "since it does not begin with a '/'"
            continue
        elif len(sections) and not util.norm_path(s) in sections:
            # skip all but the listed sections if we were asked to
            continue

        s = util.norm_path(s)

        # build the UUID for the item
        props = util.build_recursive(dict(conf[s].items()))
        id = None
        if 'uuid' in conf[s]:
            key = None
            id = uuid.UUID(conf[s]['uuid'])
        elif 'key' in conf[s]:
            key = conf[s]['key']
        else:
            # default to the path if
            key = s
        if key:
            id = inst.uuid(key)
            # raise SmapLoadError("Every config file section must have a uuid or a key!")

        # create the timeseries or collection
        if (s == '/' or conf[s].get("type", None) == 'Collection'
                or inst.get_collection(s) != None):
            if s == '/':
                c = inst.get_collection('/')
            elif inst.get_collection(s) != None:
                # sometimes you will have collections created twice,
                # for instance if a driver creates it and then we want
                # to tag it with metadata
                c = inst.get_collection(s)
            else:
                c = core.Collection(s, inst)
                inst.add_collection(s, c)
        elif conf[s].get("type", "Timeseries") == "Timeseries":
            if inst.get_timeseries(s) != None:
                c = inst.get_timeseries(s)
            else:
                try:
                    props['Properties']['UnitofMeasure']
                except KeyError:
                    raise SmapLoadError("A Timeseries must have at least "
                                        "the Properites/UnitofMeasure key")

                # the Timeseries uses defaults if the conf file doesn't
                # contain the right sections.
                c = core.Timeseries(
                    id,
                    props['Properties']['UnitofMeasure'],
                    data_type=props['Properties'].get(
                        'ReadingType',
                        core.Timeseries.DEFAULTS['Properties/ReadingType']),
                    timezone=props['Properties'].get(
                        'Timezone',
                        core.Timeseries.DEFAULTS['Properties/Timezone']),
                    buffersz=int(
                        props.get('BufferSize',
                                  core.Timeseries.DEFAULTS['BufferSize'])))
                inst.add_timeseries(s, c)
        else:
            if not id:
                raise SmapLoadError(
                    "A driver must have a key or uuid to generate a namespace")

            # load a new driver manager layer
            newdrv = driver.SmapDriver.get_driver(inst, conf[s]['type'], s, id)
            # create a collection and add it at the attachment point
            c = inst.get_collection(s)
            if not c:
                c = core.Collection(s, inst)
                inst.add_collection(s, c)

            # Add config file specified checkers for the driver
            check = checkers.get(inst, newdrv, conf[s])
            if check:
                inst.checkers.append(check)

            # get the driver to add its points
            newdrv.setup(conf[s])

        # Metadata and Description are shared between both Collections
        # and Timeseries
        if props.has_key('Metadata'):
            # the driver may have added metadata; however config file
            # metadata overrides it
            c['Metadata'] = util.dict_merge(c.get('Metadata', {}),
                                            props['Metadata'])
        if props.has_key('Description'):
            c['Description'] = props['Description']
        if key:
            setattr(c, 'key', key)

    # since the sections could come in any order, update the reporting
    # instance to make sure all the topics are set right.
    for reportinst in reports:
        if not inst.reports.update_report(reportinst):
            inst.reports.add_report(reportinst)
    inst.reports.update_subscriptions()
    inst.loading = False
    return inst