def collect(self, config):
        log.debug("Collect for OpenStack AMQP (%s)" % config.id)

        # During the first collect run, we spin up the AMQP listener.  After
        # that, no active collecting is done in the collect() method.
        #
        # Instead, as each message arives over the AMQP listener, it goes through
        # processMessage(), and is placed into a cache where it can be processed
        # by the onSuccess method.

        queue_key = "%s_%s" % (self.queue_name, config.id)

        if queue_key not in amqp_client:
            # Spin up the AMQP queue listener

            zcml.load_config('configure.zcml', zope.component)
            zcml.load_config('configure.zcml',
                             Products.ZenMessaging.queuemessaging)

            self._amqpConnectionInfo = getUtility(IAMQPConnectionInfo)
            self._amqpConnectionInfo_collector = AMQPConfig(
                amqphost='localhost',
                amqpport=55672,
                amqpvhost=self._amqpConnectionInfo.vhost,
                amqpuser=self._amqpConnectionInfo.user,
                amqppassword=self._amqpConnectionInfo.password,
                amqpusessl=self._amqpConnectionInfo.usessl,
                amqpconnectionheartbeat=self._amqpConnectionInfo.
                amqpconnectionheartbeat)

            self._queueSchema = getUtility(IQueueSchema)

            amqp = AMQPFactory(self._amqpConnectionInfo, self._queueSchema)
            amqp_collector = AMQPFactory(self._amqpConnectionInfo_collector,
                                         self._queueSchema)
            queue = self._queueSchema.getQueue(
                self.queue_name, replacements={'device': config.id})
            log.debug(
                "Listening on queue: %s with binding to routing key %s" %
                (queue.name, queue.bindings[self.exchange_name].routing_key))
            yield amqp.listen(queue,
                              callback=partial(self._processMessage, amqp,
                                               config.id))
            yield amqp_collector.listen(queue,
                                        callback=partial(
                                            self._processMessage,
                                            amqp_collector, config.id))
            amqp_client[queue_key] = amqp
            amqp_client[queue_key + "_collector"] = amqp_collector

            # Give time for some of the existing messages to be processed during
            # this initial collection cycle
            yield sleep(10)

        data = self.new_data()
        defer.returnValue(data)
    def collect(self, config):
        log.debug("Collect for OpenStack AMQP (%s)" % config.id)

        # During the first collect run, we spin up the AMQP listener.  After
        # that, no active collecting is done in the collect() method.
        #
        # Instead, as each message arives over the AMQP listener, it goes through
        # processMessage(), and is placed into a cache where it can be processed
        # by the onSuccess method.
        if config.id not in amqp_client:
            # Spin up the AMQP queue listener

            zcml.load_config('configure.zcml', zope.component)
            zcml.load_config('configure.zcml', Products.ZenMessaging.queuemessaging)

            self._amqpConnectionInfo = getUtility(IAMQPConnectionInfo)
            self._queueSchema = getUtility(IQueueSchema)

            amqp = AMQPFactory(self._amqpConnectionInfo, self._queueSchema)
            queue = self._queueSchema.getQueue('$OpenStackInboundPerf', replacements={'device': config.id})
            log.debug("Listening on queue: %s with binding to routing key %s" % (queue.name, queue.bindings['$OpenStackInbound'].routing_key))
            yield amqp.listen(queue, callback=partial(self.processMessage, amqp, config.id))
            amqp_client[config.id] = amqp

            # Give time for some of the existing messages to be processed during
            # this initial collection cycle
            yield sleep(10)

        data = self.new_data()
        device_id = config.configId

        for ds in config.datasources:
            for entry in cache[device_id].get_perf(ds.params['resourceId'], ds.params['meter']):
                log.debug("perf %s/%s=%s @ %s" % (ds.params['resourceId'], ds.params['meter'], entry.value, entry.timestamp))
                data['values'][ds.component][ds.datasource] = (entry.value, entry.timestamp)

        if len(data['values']):
            data['events'].append({
                'device': config.id,
                'component': ds.component,
                'summary': 'OpenStack Ceilometer AMQP: successful collection',
                'severity': ZenEventClasses.Clear,
                'eventKey': 'openstackCeilometerAMQPCollection',
                'eventClassKey': 'PerfSuccess',
                })

        defer.returnValue(data)
    def collect(self, config):
        log.debug("Collect for OpenStack AMQP (%s)" % config.id)

        # During the first collect run, we spin up the AMQP listener.  After
        # that, no active collecting is done in the collect() method.
        #
        # Instead, as each message arives over the AMQP listener, it goes through
        # processMessage(), and is placed into a cache where it can be processed
        # by the onSuccess method.

        queue_key = "%s_%s" % (self.queue_name, config.id)

        if queue_key not in amqp_client:
            # Spin up the AMQP queue listener

            zcml.load_config('configure.zcml', zope.component)
            zcml.load_config('configure.zcml', Products.ZenMessaging.queuemessaging)

            self._amqpConnectionInfo = getUtility(IAMQPConnectionInfo)
            self._amqpConnectionInfo_collector = AMQPConfig(
                amqphost='localhost',
                amqpport=55672,
                amqpvhost=self._amqpConnectionInfo.vhost,
                amqpuser=self._amqpConnectionInfo.user,
                amqppassword=self._amqpConnectionInfo.password,
                amqpusessl=self._amqpConnectionInfo.usessl,
                amqpconnectionheartbeat=self._amqpConnectionInfo.amqpconnectionheartbeat)

            self._queueSchema = getUtility(IQueueSchema)

            amqp = AMQPFactory(self._amqpConnectionInfo, self._queueSchema)
            amqp_collector = AMQPFactory(self._amqpConnectionInfo_collector, self._queueSchema)
            queue = self._queueSchema.getQueue(self.queue_name, replacements={'device': config.id})
            log.debug("Listening on queue: %s with binding to routing key %s" % (queue.name, queue.bindings[self.exchange_name].routing_key))
            yield amqp.listen(queue, callback=partial(self._processMessage, amqp, config.id))
            yield amqp_collector.listen(queue, callback=partial(self._processMessage, amqp_collector, config.id))
            amqp_client[queue_key] = amqp
            amqp_client[queue_key + "_collector"] = amqp_collector

            # Give time for some of the existing messages to be processed during
            # this initial collection cycle
            yield sleep(10)

        data = self.new_data()
        defer.returnValue(data)
    def collect(self, config):
        log.debug("Collect for OpenStack AMQP Heartbeats (%s)" % config.id)

        service = yield self.getService('ZenPacks.zenoss.OpenStackInfrastructure.services.OpenStackService')
        expected_heartbeats = yield service.callRemote('expected_ceilometer_heartbeats', config.id)

        if not expected_heartbeats:
            return

        # During the first collect run, we spin up the AMQP listener.  After
        # that, no active collecting is done in the collect() method.
        #
        # Instead, as each message arrives over the AMQP listener, it goes through
        # processMessage(), and is placed into a list, per host, per process,
        # where it can be processed by the onSuccess method.
        if config.id not in amqp_client:
            # Spin up the AMQP queue listener

            zcml.load_config('configure.zcml', zope.component)
            zcml.load_config('configure.zcml', Products.ZenMessaging.queuemessaging)

            self._amqpConnectionInfo = getUtility(IAMQPConnectionInfo)
            self._queueSchema = getUtility(IQueueSchema)

            amqp = AMQPFactory(self._amqpConnectionInfo, self._queueSchema)
            queue = self._queueSchema.getQueue('$OpenStackInboundHeartbeat',
                                               replacements={'device': config.id})
            log.info("Listening on queue: %s with binding to routing key %s" % (queue.name, queue.bindings['$OpenStackInboundHeartbeats'].routing_key))
            yield amqp.listen(queue, callback=partial(self.processMessage, amqp))
            amqp_client[config.id] = amqp

            # Give time for some of the existing messages to be processed during
            # this initial collection cycle
            yield sleep(10)

        data = self.new_data()
        device_id = config.id

        for host in expected_heartbeats:
            hostname = host['hostnames'][0]
            possible_hostnames = host['hostnames']
            required_processes = host['processes']

            heartbeat_hostname = None
            for possible_hostname in possible_hostnames:
                if possible_hostname in last_heard_heartbeats:
                    heartbeat_hostname = possible_hostname
                    break

            process_heartbeats = {}

            if heartbeat_hostname is None:
                # We have not heard a heartbeat from this host under
                # any of its possible hostnames (short name, fqdn)
                #
                # So there won't be any process heartbeats, and we will
                # consider them all to be down.
                process_heartbeats = {}
            else:
                process_heartbeats = last_heard_heartbeats[heartbeat_hostname]

            for proc in required_processes:
                if proc not in process_heartbeats:
                    evt = {
                        'device': device_id,
                        'severity': ZenEventClasses.Warning,
                        'eventKey': hostname + '_' + proc,
                        'summary': "No heartbeats received from '%s' on %s.  Check the host and process status." % (proc, hostname),
                        'eventClassKey': 'openStackCeilometerHeartbeat',
                    }
                    log.error(pformat(evt))
                else:
                    # diff > MAX_TIME_LAPSE?
                    time_diff = time() - \
                        process_heartbeats[proc]['lastheard']

                    if time_diff > MAX_TIME_LAPSE:
                        evt = {
                            'device': device_id,
                            'severity': ZenEventClasses.Warning,
                            'eventKey': hostname + '_' + proc,
                            'summary': "No heartbeats received from '%s' on %s for more than %d seconds.  Check its status and restart it if necessary." % (proc, hostname, MAX_TIME_LAPSE),
                            'eventClassKey': 'openStackCeilometerHeartbeat',
                        }
                        log.error(pformat(evt))
                    else:
                        evt = {
                            'device': device_id,
                            'severity': ZenEventClasses.Clear,
                            'eventKey': hostname + '_' + proc,
                            'summary': "Process '%s' on %s is sending heartbeats normally." % (proc, hostname),
                            'eventClassKey': 'openStackCeilometerHeartbeat',
                        }

                data['events'].append(evt)

        if len(data['events']):
            data['events'].append({
                'device': device_id,
                'summary': 'OpenStack Ceilometer AMQP Heartbeat: successful collection',
                'severity': ZenEventClasses.Clear,
                'eventKey': 'openstackCeilometerAMQPHeartbeatCollection',
                'eventClassKey': 'EventsSuccess',
                })

        defer.returnValue(data)
    def collect(self, config):
        log.debug("Collect for OpenStack AMQP Events (%s)" % config.id)

        # During the first collect run, we spin up the AMQP listener.  After
        # that, no active collecting is done in the collect() method.
        #
        # Instead, as each message arives over the AMQP listener, it goes through
        # processMessage(), and is placed into a cache where it can be processed
        # by the onSuccess method.
        if config.id not in amqp_client:
            # Spin up the AMQP queue listener

            zcml.load_config('configure.zcml', zope.component)
            zcml.load_config('configure.zcml', Products.ZenMessaging.queuemessaging)

            self._amqpConnectionInfo = getUtility(IAMQPConnectionInfo)
            self._queueSchema = getUtility(IQueueSchema)

            amqp = AMQPFactory(self._amqpConnectionInfo, self._queueSchema)
            queue = self._queueSchema.getQueue('$OpenStackInboundEvent', replacements={'device': config.id})
            log.info("Listening on queue: %s with binding to routing key %s" % (queue.name, queue.bindings['$OpenStackInbound'].routing_key))
            yield amqp.listen(queue, callback=partial(self.processMessage, amqp, config.id))
            amqp_client[config.id] = amqp

            # Give time for some of the existing messages to be processed during
            # this initial collection cycle
            yield sleep(10)

        data = self.new_data()
        device_id = config.configId

        for entry in cache[device_id].get():
            c_event = entry.value

            evt = {
                'device': device_id,
                'severity': ZenEventClasses.Info,
                'eventKey': '',
                'summary': 'OpenStackInfrastructure: ' + c_event['event_type'],
                'eventClassKey': 'openstack|' + c_event['event_type'],
            }

            traits = {}
            for trait in c_event['traits']:
                # liberty: [[name, dtype, value] ...]
                # [[u'display_name', 1, u'demo-volume1-snap'], ...]
                traits[trait[0]] = trait[2]

            if 'priority' in traits:
                if traits['priority'] == 'WARN':
                    evt['severity'] = ZenEventClasses.Warning
                elif traits['priority'] == 'ERROR':
                    evt['severity'] = ZenEventClasses.Error

            evt['eventKey'] = c_event['message_id']

            for trait in traits:
                evt['trait_' + trait] = traits[trait]

            from pprint import pformat
            log.debug(pformat(evt))

            data['events'].append(evt)

        if len(data['events']):
            data['events'].append({
                'device': config.id,
                'summary': 'OpenStack Ceilometer AMQP: successful collection',
                'severity': ZenEventClasses.Clear,
                'eventKey': 'openstackCeilometerAMQPCollection',
                'eventClassKey': 'EventsSuccess',
                })

        defer.returnValue(data)
        results["resolved_hostnames"] = {}
        for hostname in sorted(hostnames):
            if isip(hostname):
                results["resolved_hostnames"][hostname] = hostname
                continue

            for i in range(1, 4):
                try:
                    host_ip = yield asyncIpLookup(hostname)
                    results["resolved_hostnames"][hostname] = host_ip
                    break
                except socket.gaierror, e:
                    # temporary dns issue- try again.
                    log.error("resolve %s: (attempt %d/3): %s" % (hostname, i, e))
                    yield sleep(2)
                except Exception, e:
                    log.error("resolve %s: %s" % (hostname, e))

        returnValue(results)

    def process(self, device, results, unused):
        tenants = []
        for tenant in results["tenants"]:
            if tenant["enabled"] is not True:
                continue

            tenants.append(
                ObjectMap(
                    modname="ZenPacks.zenoss.OpenStackInfrastructure.Tenant",
                    data=dict(