Example #1
0
class AlarmManager(CompositeNode):
    implements(IAlarmManager)
    security = SecurityInformation.from_default()
    secured_by(security)

    def __init__(self, *args, **kw):
        super(AlarmManager, self).__init__(*args, **kw)
        self.dispatcher = Dispatcher('Alarm Manager')
        self.cloud = None
        self.max_raised = 5
        self.max_cleared = 5
        self.max_accepted = 5
        self.use_https = False
        self.remote_events = {}

    security.protect('add_alarm', 'Configure')

    def add_alarm(self, alarm):
        self.add_child(alarm)

    security.protect('remove_alarm', 'Configure')

    def remove_alarm(self, name):
        self.get_alarm(name).prune()

    def get_alarm(self, name):
        return self.get_child(name)

    def get_alarms(self):
        return self.children_nodes()

    def get_alarm_names(self):
        return self.children_names()

    def get_alarm_dictionary(self):
        return self.children

    def get_remote_events(self):
        return self.remote_events.values()

    def get_local_events(self):
        events = []
        alarms = self.get_alarms()
        eventlists = map(Alarm.get_events, alarms)
        map(events.extend, eventlists)
        return events

    def get_all_events(self):
        return self.get_local_events() + self.get_remote_events()

    def get_event_dictionary(self, order_by='state', source='all'):
        try:
            events = getattr(self, 'get_' + source + '_events')()
        except AttributeError:
            raise ValueError('"%s" invalid value for source.' % source)
        eventdict = {}
        if order_by == 'state':
            for event in events:
                eventdict.setdefault(event.state, []).append(event)
        elif order_by == 'GUID' or order_by == 'guid':
            for event in events:
                eventdict[event.GUID] = event
        else:
            raise ValueError('"%s" invalid value for order_by' % order_by)
        return eventdict

    def get_events_by_state(self, state, source='all'):
        eventdict = self.get_event_dictionary('state', source)
        return eventdict.get(state.upper(), [])

    def handle_event_resend(self, cloudevent):
        self.message('Received Event Resend event %s' % (cloudevent))
        self.send_alarm_events_to_portal(cloudevent.origin)

    def send_alarm_events_to_portal(self, target):
        count = 0
        for alarm in self.get_alarms():
            for event in alarm.get_events():
                self.cloud.send_event_to_portal(event, ['Alarm Manager'],
                                                target)
                count += 1
        self.message('Dispatched %s events because of Event Resend Request' %
                     count)
        return count

    def handle_cloud_event(self, cloudevent):
        event = cloudevent()

    def dispatch(self, event, *args, **kw):
        result = self.dispatcher.timed_dispatch(event, *args, **kw)
        if isinstance(event, StateEvent):
            alarmevent = event.get_alarm_event()
            if alarmevent.is_local():
                self.cloud.handle_local_event(alarmevent, ['Alarm Manager'])
            else:
                guid = alarmevent.GUID
                if not self.remote_events.has_key(guid):
                    self.remote_events[guid] = alarmevent
                if isinstance(event, AlarmEventClosed):
                    del (self.remote_events[guid])
        return result

    def handle_cloud_change(self, event):
        count = 0
        for alarm in self.get_alarms():
            for event in alarm.get_events():
                self.cloud.handle_local_event(event, ['Alarm Manager'])
                count += 1
        self.message('Dispatched %s events because Cloud Change.' % count)
        self.dispatch(event)
        return count

    def register_for_type(self, *args, **kw):
        return self.dispatcher.register_for_type(*args, **kw)

    def configure(self, config):
        set_attribute(self, 'use_https', self.use_https, config, as_boolean)
        set_attribute(self, 'max_raised', 5, config, int)
        set_attribute(self, 'max_cleared', 5, config, int)
        set_attribute(self, 'max_accepted', 5, config, int)
        return super(AlarmManager, self).configure(config)

    def configuration(self):
        config = super(AlarmManager, self).configuration()
        get_attribute(self, 'use_https', config, str)
        get_attribute(self, 'max_raised', config, str)
        get_attribute(self, 'max_cleared', config, str)
        get_attribute(self, 'max_accepted', config, str)
        return config

    def start(self):
        self.message('Alarm Manager starting.')
        server = self.nodespace.as_node('/services/network/http_server')
        if not server.is_enabled() or self.use_https:
            server = self.nodespace.as_node('/services/network/https_server')
        config = {
            'parent': server,
            'enabled': 1,
            'secured': True,
            'debug': self.debug
        }
        syndic_handler_config = config.copy()
        config_handler_config = config.copy()
        cloud_handler_config = config.copy()
        cloud_config_handler_config = config.copy()
        exporter_handler_config = config.copy()
        trigger_handler_config = config.copy()
        syndic_handler_config['name'] = 'Syndication Viewer'
        syndic_handler_config['path'] = '/syndication'
        config_handler_config['name'] = 'Alarm Configurator'
        config_handler_config['path'] = '/alarmconfig'
        cloud_handler_config['name'] = 'Cloud Handler'
        cloud_handler_config['path'] = '/cloud'
        cloud_config_handler_config['name'] = 'Cloud Configurator'
        cloud_config_handler_config['path'] = '/cloudconfig'
        exporter_handler_config['name'] = 'Exporter Configurator'
        exporter_handler_config['path'] = '/exportconfig'
        trigger_handler_config['name'] = 'Trigger Configurator'
        trigger_handler_config['path'] = '/triggerconfig'

        ##
        # Frist create and setup Cloud Manager so events produced by
        #   startup of configurators can be propogated properly.
        startlist = []
        from mpx.service.cloud.manager import CloudManager
        cloud_manager = self.nodespace.create_node(CloudManager)
        cloud_manager.configure({
            'name': 'Cloud Manager',
            'parent': '/services',
            'debug': self.debug
        })
        self.cloud = cloud_manager
        startlist.append(cloud_manager)

        from mpx.service.cloud import request_handler
        cloud_handler_config['manager'] = '/services/Cloud Manager'
        cloud_handler = self.nodespace.create_node(
            request_handler.CloudHandler)
        cloud_handler.configure(cloud_handler_config)
        del request_handler
        startlist.insert(0, cloud_handler)

        from mpx.service.cloud.xhtml.configuration import request_handler
        cloud_config_handler_config['manager'] = '/services/Cloud Manager'
        cloud_config_handler = self.nodespace.create_node(
            request_handler.CloudConfigurator)
        cloud_config_handler.configure(cloud_config_handler_config)
        del request_handler
        startlist.append(cloud_config_handler)

        for cloudservice in startlist:
            cloudservice.start()
        self.message(
            'Alarm Manager configured and started Cloud Manager, Handler, and Configurator.'
        )

        ##
        # Syndication Handler is idempotent and so can be started anytime.
        from mpx.service.alarms2.presentation.syndication.http import request_handler
        syndic_handler = request_handler.SyndicationViewer()
        syndic_handler.configure(syndic_handler_config)
        del request_handler
        syndic_handler.start()
        self.message(
            'Alarm Manager configured and started Syndication Handler.')

        ##
        # Startup Alarm Manager's configurator so that pickled Alarm Events may be
        #   recreated.
        from mpx.service.alarms2.presentation.xhtml.configuration import request_handler
        config_handler = self.nodespace.create_node(
            request_handler.AlarmConfigurator)
        config_handler.configure(config_handler_config)
        del request_handler
        config_handler.start()
        self.message('Alarm Manager created and started Alarm Configurator.')

        ##
        # Now that old Alarm Events have been recreated, configure and
        #   startup Exporters.
        from mpx.service.alarms2.export import exporter
        container = self.nodespace.create_node(exporter.ExporterContainer)
        container.configure({
            'name': 'Alarm Exporters',
            'parent': '/services',
            'debug': self.debug
        })
        export = self.nodespace.create_node(exporter.AlarmExporter)
        export.configure({
            'name': 'Alarm Logger',
            'parent': container,
            'debug': self.debug
        })
        formatter = self.nodespace.create_node(
            exporter.AlarmDictionaryFormatter)
        formatter.configure({
            'name': 'Log Formatter',
            'parent': export,
            'debug': self.debug
        })
        transporter = self.nodespace.create_node(exporter.LoggingTransporter)
        transporter.configure({
            'name': 'Alarm Logger',
            'log': '/services/logger/Alarm Log',
            'parent': export,
            'debug': self.debug
        })
        export.add_source(self, StateEvent)
        container.start()
        self.message('Created and started alarm exporters and logger.')

        from mpx.service.alarms2.export.xhtml.configuration import request_handler
        export_config_handler = self.nodespace.create_node(
            request_handler.ExportersConfigurator)
        export_config_handler.configure(exporter_handler_config)
        del request_handler
        export_config_handler.start()
        self.message(
            'Alarm Manager created and started Exporter Configurator.')

        self.cloud.add_listener(self.handle_cloud_event, 'Alarm Manager')
        self.cloud.add_listener(self.handle_event_resend, 'EventResend')
        from mpx.service.cloud.manager import FormationUpdated
        self.cloud.dispatcher.register_for_type(self.handle_cloud_change,
                                                FormationUpdated)
        self.message(
            'Alarm Manager added itself as listender for Cloud Events.')

        ##
        # With all supporting infrastructure started, start triggers which may
        #   immediately generate alarms.
        from mpx.service.alarms2.trigger import triggermanager
        trigger_manager = self.nodespace.create_node(
            triggermanager.TriggerManager)
        trigger_manager.configure({
            'name': 'Trigger Manager',
            'parent': '/services',
            'debug': self.debug
        })
        del triggermanager
        trigger_manager.start()
        self.message('Alarm Manager created and started Trigger Manager.')

        from mpx.service.alarms2.trigger.xhtml.configuration import request_handler
        trigger_config_handler = self.nodespace.create_node(
            request_handler.TriggersConfigurator)
        trigger_config_handler.configure(trigger_handler_config)
        del request_handler
        self.message('Alarm Manager created and started Trigger Configurator.')
        trigger_config_handler.start()
        try:
            store = as_node("/services/Event Store")
        except KeyError:
            msglog.inform("Alarm Manager creating Event Store.")
            from mpx.service.alarms2 import store
            estore = store.EventStore()
            estore.configure({"name": "Event Store", "parent": "/services"})
            estore.start()
            msglog.inform("Alarm Manager setup and started Event Store.")
        else:
            msglog.inform("Alarm Manager found existing Event Store.")
        super(AlarmManager, self).start()
        self.message('Alarm Manager startup complete.')

    def message(self, message, mtype=msglog.types.INFO):
        if (mtype != msglog.types.DB) or self.debug:
            msglog.log('broadway', mtype, message)
        return
Example #2
0
class TriggerManager(CompositeNode):
    implements(ITriggerManager)
    security = SecurityInformation.from_default()
    secured_by(security)

    def __init__(self, *args):
        self.dispatcher = None
        self._queue = None
        self._stopflag = None
        self._thread = None
        CompositeNode.__init__(self, *args)

    security.protect('get_trigger', 'View')

    def get_triggers(self):
        return self.children_nodes()

    security.protect('get_trigger', 'View')

    def get_trigger(self, name):
        return self.get_child(name)

    security.protect('add_trigger', 'Configure')

    def add_trigger(self, trigger):
        return self.add_child(trigger)

    security.protect('remove_trigger', 'Configure')

    def remove_trigger(self, trigger):
        return self.prune_child(trigger)

    security.protect('get_trigger_names', 'View')

    def get_trigger_names(self):
        return self.children_names()

    security.protect('get_active', 'View')

    def get_active(self):
        children = self.children_nodes()
        active = map(Trigger.is_active, children)
        return [child for child in children if child.is_active()]

    security.protect('get_inactive', 'View')

    def get_inactive(self):
        children = self.children_nodes()
        active = map(Trigger.is_active, children)
        return [child for child in children if not child.is_active()]

    def start(self):
        if self._thread is not None:
            raise Exception('Cannot call start on started '
                            'Manager without stopping.')
        if self.dispatcher is None:
            self.dispatcher = Dispatcher(self.url)
        self.triggersub = self.dispatcher.register_for_type(
            self.handle_triggered, TriggerActivated)
        self.clearsub = self.dispatcher.register_for_type(
            self.handle_cleared, TriggerCleared)
        self._startmanager()
        return super(TriggerManager, self).start()

    def stop(self):
        if self.triggersub: self.dispatcher.unregister(self.triggersub)
        if self.clearsub: self.dispatcher.unregister(self.clearsub)
        self.triggersub = self.clearsub = None
        self._stopmanager()
        return super(TriggerManager, self).stop()

    def _add_child(self, child):
        pass

    def _rename_child(self, *args):
        pass

    def queue_trigger(self, trigger):
        self._queue.put(trigger)

    def is_running(self):
        return not not (self._thread and self._thread.isAlive())

    security.protect('handle_triggered', 'Override')

    def handle_triggered(self, event):
        trigger = event.get_trigger()
        targets = trigger.get_targets()
        arguments = event.get_arguments()
        for target in targets:
            target.trigger(*arguments)
        return len(targets)

    security.protect('handle_cleared', 'Override')

    def handle_cleared(self, event):
        trigger = event.get_trigger()
        targets = trigger.get_targets()
        arguments = event.get_arguments()
        for target in targets:
            target.clear(*arguments)
        return len(targets)

    def _startmanager(self):
        self._queue = queue = Queue()
        self._stopflag = stopflag = Flag()
        self._thread = thread = ImmortalThread(name=self.url,
                                               target=self._runmanager,
                                               args=(stopflag, queue))
        thread.start()

    def _stopmanager(self):
        stopflag, self._stopflag = self._stopflag, None
        thread, self._thread = self._thread, None
        if not thread: return
        thread.should_die()
        stopflag.set()
        thread.join()

    def _runmanager(self, stopflag, queue):
        while not stopflag.isSet():
            trigger = queue.get(1)
            if trigger is not NOTHING:
                trigger()
        else:
            msglog.log('broadway', msglog.types.INFO,
                       'Trigger Manager exiting run.')
            print 'Trigger Manager run exiting.'
        return
Example #3
0
class TriggerManager(CompositeNode):
    implements(ITriggerManager)
    security = SecurityInformation.from_default()
    secured_by(security)

    def __init__(self, *args):
        self.dispatcher = None
        self._queue = None
        self._stopflag = None
        self._thread = None
        CompositeNode.__init__(self, *args)
    security.protect('get_trigger', 'View')
    def get_triggers(self):
        return self.children_nodes()
    security.protect('get_trigger', 'View')
    def get_trigger(self, name):
        return self.get_child(name)
    security.protect('add_trigger', 'Configure')
    def add_trigger(self, trigger):
        return self.add_child(trigger)
    security.protect('remove_trigger', 'Configure')
    def remove_trigger(self, trigger):
        return self.prune_child(trigger)
    security.protect('get_trigger_names', 'View')
    def get_trigger_names(self):
        return self.children_names()
    security.protect('get_active', 'View')
    def get_active(self):
        children = self.children_nodes()
        active = map(Trigger.is_active, children)
        return [child for child in children if child.is_active()]
    security.protect('get_inactive', 'View')
    def get_inactive(self):
        children = self.children_nodes()
        active = map(Trigger.is_active, children)
        return [child for child in children if not child.is_active()]
    def start(self):
        if self._thread is not None:
            raise Exception('Cannot call start on started '
                            'Manager without stopping.')
        if self.dispatcher is None:
            self.dispatcher = Dispatcher(self.url)
        self.triggersub = self.dispatcher.register_for_type(
            self.handle_triggered, TriggerActivated)
        self.clearsub = self.dispatcher.register_for_type(
            self.handle_cleared, TriggerCleared)
        self._startmanager()
        return super(TriggerManager, self).start()
    def stop(self):
        if self.triggersub: self.dispatcher.unregister(self.triggersub)
        if self.clearsub: self.dispatcher.unregister(self.clearsub)
        self.triggersub = self.clearsub = None
        self._stopmanager()
        return super(TriggerManager, self).stop()
    def _add_child(self, child): pass
    def _rename_child(self, *args): pass
    def queue_trigger(self, trigger):
        self._queue.put(trigger)
    def is_running(self):
        return not not (self._thread and self._thread.isAlive())
    security.protect('handle_triggered', 'Override')
    def handle_triggered(self, event):
        trigger = event.get_trigger()
        targets = trigger.get_targets()
        arguments = event.get_arguments()
        for target in targets: target.trigger(*arguments)
        return len(targets)
    security.protect('handle_cleared', 'Override')
    def handle_cleared(self, event):
        trigger = event.get_trigger()
        targets = trigger.get_targets()
        arguments = event.get_arguments()
        for target in targets: target.clear(*arguments)
        return len(targets)
    def _startmanager(self):
        self._queue = queue = Queue()
        self._stopflag = stopflag = Flag()
        self._thread = thread = ImmortalThread(
            name=self.url, target=self._runmanager, args = (stopflag, queue))
        thread.start()
    def _stopmanager(self):
        stopflag, self._stopflag = self._stopflag, None
        thread, self._thread = self._thread, None
        if not thread: return
        thread.should_die()
        stopflag.set()
        thread.join()
    def _runmanager(self, stopflag, queue):
        while not stopflag.isSet():
            trigger = queue.get(1)
            if trigger is not NOTHING:
                trigger()
        else:
            msglog.log('broadway', msglog.types.INFO,
                       'Trigger Manager exiting run.')
            print 'Trigger Manager run exiting.'
        return
Example #4
0
class AlarmManager(CompositeNode):
    implements(IAlarmManager)
    security = SecurityInformation.from_default()
    secured_by(security)

    def __init__(self,*args,**kw):
        super(AlarmManager, self).__init__(*args, **kw)
        self.dispatcher = Dispatcher('Alarm Manager')
        self.cloud = None
        self.max_raised = 5
        self.max_cleared = 5
        self.max_accepted = 5
        self.use_https = False
        self.remote_events = {}
    security.protect('add_alarm', 'Configure')
    def add_alarm(self, alarm):
        self.add_child(alarm)
    security.protect('remove_alarm', 'Configure')
    def remove_alarm(self, name):
        self.get_alarm(name).prune()
    def get_alarm(self, name):
        return self.get_child(name)
    def get_alarms(self):
        return self.children_nodes()
    def get_alarm_names(self):
        return self.children_names()
    def get_alarm_dictionary(self):
        return self.children
    def get_remote_events(self):
        return self.remote_events.values()
    def get_local_events(self):
        events = []
        alarms = self.get_alarms()
        eventlists = map(Alarm.get_events, alarms)
        map(events.extend, eventlists)
        return events
    def get_all_events(self):
        return self.get_local_events() + self.get_remote_events()
    def get_event_dictionary(self, order_by = 'state', source = 'all'):
        try: events = getattr(self, 'get_' + source + '_events')()
        except AttributeError:
            raise ValueError('"%s" invalid value for source.' % source)
        eventdict = {}
        if order_by == 'state':
            for event in events:
                eventdict.setdefault(event.state, []).append(event)
        elif order_by == 'GUID' or order_by == 'guid':
            for event in events:
                eventdict[event.GUID] = event
        else:
            raise ValueError('"%s" invalid value for order_by' % order_by)
        return eventdict
    def get_events_by_state(self, state, source = 'all'):
        eventdict = self.get_event_dictionary('state', source)
        return eventdict.get(state.upper(), [])
    def handle_event_resend(self, cloudevent):
        self.message('Received Event Resend event %s' %(cloudevent))
        self.send_alarm_events_to_portal(cloudevent.origin)

    def send_alarm_events_to_portal(self,target):
        count = 0
        for alarm in self.get_alarms():
            for event in alarm.get_events():
                self.cloud.send_event_to_portal(event,['Alarm Manager'],target)
                count += 1
        self.message( 'Dispatched %s events because of Event Resend Request' % count)
        return count

    def handle_cloud_event(self, cloudevent):
        event = cloudevent()
    def dispatch(self, event, *args, **kw):
        result = self.dispatcher.timed_dispatch(event, *args, **kw)
        if isinstance(event, StateEvent):
            alarmevent = event.get_alarm_event()
            if alarmevent.is_local():
                self.cloud.handle_local_event(alarmevent, ['Alarm Manager'])
            else:
                guid = alarmevent.GUID
                if not self.remote_events.has_key(guid):
                    self.remote_events[guid] = alarmevent
                if isinstance(event, AlarmEventClosed):
                    del(self.remote_events[guid])
        return result
    def handle_cloud_change(self, event):
        count = 0
        for alarm in self.get_alarms():
            for event in alarm.get_events():
                self.cloud.handle_local_event(event, ['Alarm Manager'])
                count += 1
        self.message( 'Dispatched %s events because Cloud Change.' % count)
        self.dispatch(event)
        return count
    def register_for_type(self, *args, **kw):
        return self.dispatcher.register_for_type(*args, **kw)
    def configure(self, config):
        set_attribute(self, 'use_https', self.use_https, config, as_boolean)
        set_attribute(self, 'max_raised', 5, config, int)
        set_attribute(self, 'max_cleared', 5, config, int)
        set_attribute(self, 'max_accepted', 5, config, int)        
        return super(AlarmManager, self).configure(config)
    def configuration(self):
        config = super(AlarmManager, self).configuration()
        get_attribute(self, 'use_https', config, str)
        get_attribute(self, 'max_raised', config, str)
        get_attribute(self, 'max_cleared', config, str)
        get_attribute(self, 'max_accepted', config, str)
        return config
    def start(self):
        self.message('Alarm Manager starting.')
        server = self.nodespace.as_node('/services/network/http_server')
        if not server.is_enabled() or self.use_https:
            server = self.nodespace.as_node('/services/network/https_server')
        config = {'parent': server, 'enabled': 1,
                  'secured': True, 'debug': self.debug}
        syndic_handler_config = config.copy()
        config_handler_config = config.copy()
        cloud_handler_config = config.copy()
        cloud_config_handler_config = config.copy()
        exporter_handler_config = config.copy()
        trigger_handler_config = config.copy()
        syndic_handler_config['name'] = 'Syndication Viewer'
        syndic_handler_config['path'] = '/syndication'
        config_handler_config['name'] = 'Alarm Configurator'
        config_handler_config['path'] = '/alarmconfig'
        cloud_handler_config['name'] = 'Cloud Handler'
        cloud_handler_config['path'] = '/cloud'
        cloud_config_handler_config['name'] = 'Cloud Configurator'
        cloud_config_handler_config['path'] = '/cloudconfig'
        exporter_handler_config['name'] = 'Exporter Configurator'
        exporter_handler_config['path'] = '/exportconfig'
        trigger_handler_config['name'] = 'Trigger Configurator'
        trigger_handler_config['path'] = '/triggerconfig'

        ##
        # Frist create and setup Cloud Manager so events produced by
        #   startup of configurators can be propogated properly.
        startlist = []
        from mpx.service.cloud.manager import CloudManager
        cloud_manager = self.nodespace.create_node(CloudManager)
        cloud_manager.configure({'name': 'Cloud Manager',
                                 'parent': '/services',
                                 'debug': self.debug})
        self.cloud = cloud_manager
        startlist.append(cloud_manager)

        from mpx.service.cloud import request_handler
        cloud_handler_config['manager'] = '/services/Cloud Manager'
        cloud_handler = self.nodespace.create_node(request_handler.CloudHandler)
        cloud_handler.configure(cloud_handler_config)
        del request_handler
        startlist.insert(0, cloud_handler)

        from mpx.service.cloud.xhtml.configuration import request_handler
        cloud_config_handler_config['manager'] = '/services/Cloud Manager'
        cloud_config_handler = self.nodespace.create_node(request_handler.CloudConfigurator)
        cloud_config_handler.configure(cloud_config_handler_config)
        del request_handler
        startlist.append(cloud_config_handler)

        for cloudservice in startlist:
            cloudservice.start()
        self.message('Alarm Manager configured and started Cloud Manager, Handler, and Configurator.')

        ##
        # Syndication Handler is idempotent and so can be started anytime.
        from mpx.service.alarms2.presentation.syndication.http import request_handler
        syndic_handler = request_handler.SyndicationViewer()
        syndic_handler.configure(syndic_handler_config)
        del request_handler
        syndic_handler.start()
        self.message('Alarm Manager configured and started Syndication Handler.')

        ##
        # Startup Alarm Manager's configurator so that pickled Alarm Events may be
        #   recreated.
        from mpx.service.alarms2.presentation.xhtml.configuration import request_handler
        config_handler = self.nodespace.create_node(request_handler.AlarmConfigurator)
        config_handler.configure(config_handler_config)
        del request_handler
        config_handler.start()
        self.message('Alarm Manager created and started Alarm Configurator.')

        ##
        # Now that old Alarm Events have been recreated, configure and
        #   startup Exporters.
        from mpx.service.alarms2.export import exporter
        container = self.nodespace.create_node(exporter.ExporterContainer)
        container.configure({'name': 'Alarm Exporters',
                             'parent': '/services',
                             'debug': self.debug})
        export = self.nodespace.create_node(exporter.AlarmExporter)
        export.configure({'name': 'Alarm Logger',
                          'parent': container,
                          'debug': self.debug})
        formatter = self.nodespace.create_node(exporter.AlarmDictionaryFormatter)
        formatter.configure({'name': 'Log Formatter',
                             'parent': export,
                             'debug': self.debug})
        transporter = self.nodespace.create_node(exporter.LoggingTransporter)
        transporter.configure({'name': 'Alarm Logger',
                               'log': '/services/logger/Alarm Log',
                               'parent': export,
                               'debug': self.debug})
        export.add_source(self, StateEvent)
        container.start()
        self.message('Created and started alarm exporters and logger.')

        from mpx.service.alarms2.export.xhtml.configuration import request_handler
        export_config_handler = self.nodespace.create_node(request_handler.ExportersConfigurator)
        export_config_handler.configure(exporter_handler_config)
        del request_handler
        export_config_handler.start()
        self.message('Alarm Manager created and started Exporter Configurator.')


        self.cloud.add_listener(self.handle_cloud_event, 'Alarm Manager')
        self.cloud.add_listener(self.handle_event_resend, 'EventResend')
        from mpx.service.cloud.manager import FormationUpdated
        self.cloud.dispatcher.register_for_type(
            self.handle_cloud_change, FormationUpdated)
        self.message('Alarm Manager added itself as listender for Cloud Events.')


        ##
        # With all supporting infrastructure started, start triggers which may
        #   immediately generate alarms.
        from mpx.service.alarms2.trigger import triggermanager
        trigger_manager = self.nodespace.create_node(triggermanager.TriggerManager)
        trigger_manager.configure({'name': 'Trigger Manager',
                                   'parent': '/services',
                                   'debug': self.debug})
        del triggermanager
        trigger_manager.start()
        self.message('Alarm Manager created and started Trigger Manager.')

        from mpx.service.alarms2.trigger.xhtml.configuration import request_handler
        trigger_config_handler = self.nodespace.create_node(request_handler.TriggersConfigurator)
        trigger_config_handler.configure(trigger_handler_config)
        del request_handler
        self.message('Alarm Manager created and started Trigger Configurator.')
        trigger_config_handler.start()
        try:
            store = as_node("/services/Event Store")
        except KeyError:
            msglog.inform("Alarm Manager creating Event Store.")
            from mpx.service.alarms2 import store
            estore = store.EventStore()
            estore.configure({"name": "Event Store", "parent": "/services"})
            estore.start()
            msglog.inform("Alarm Manager setup and started Event Store.")
        else:
            msglog.inform("Alarm Manager found existing Event Store.")
        super(AlarmManager, self).start()
        self.message('Alarm Manager startup complete.')

    def message(self, message, mtype = msglog.types.INFO):
        if (mtype != msglog.types.DB) or self.debug:
            msglog.log('broadway', mtype, message)
        return