async def poll(self, ip, timeout=10): ''' poll and cache result''' try: device_snmp = await asyncio.wait_for(self._poll(ip), timeout) except asyncio.TimeoutError: device_snmp = None if device_snmp is None: event = Event('runtime-failure', source='snmp', level='warning') event.add_data('ip', ip) event.notify() return # Try to find a cached device device_id = self.get_id_by_ip(ip) if not device_id and 'ports' in device_snmp: # Try to find cached device by mac for port in device_snmp['ports']: device_id = self.get_id_by_mac(port['mac']) if device_id: break if device_id: cached_device = self.get_device_by_id(device_id) else: device_id = self.get_new_device_id() cached_device = None device_snmp['local_id'] = device_id # Update cached device if needed if cached_device != device_snmp: if cached_device is None or self.switch_has_changed(cached_device, device_snmp): # notify if has changed. Only send relevant keys Dendrite.publish_single('snmp', { k:v for k, v in device_snmp.items() if k not in IGNORE_SWITCH_KEYS }) # cache the device, including dynamic fields like fw_mac with self.synapse.pipeline() as pipe: pipe.hset(self.DEVICE_SNMP_CACHE_PATH, device_id, device_snmp) pipe.hset(self.DEVICE_IP_SNMP_CACHE_PATH, ip, device_id) cached_macs = set() if cached_device: for port in cached_device['ports']: if port['mac']: cached_macs.add(port['mac']) device_macs = set() for port in device_snmp['ports']: if port['mac']: device_macs.add(port['mac']) for mac in cached_macs - device_macs: # macs not longer valid pipe.hdel(self.DEVICE_MAC_SNMP_CACHE_PATH, mac) for mac in device_macs - cached_macs: # new macs pipe.hset(self.DEVICE_MAC_SNMP_CACHE_PATH, mac, device_id) pipe.execute() return device_snmp
def test_get(self): dummy = str(uuid4()) self.dendrite.publish('test/get', dummy, retain=True) result = self.dendrite.get('test/get') self.assertEqual(result, dummy) Dendrite.publish_single('test/get', retain=True) time.sleep(1) with self.assertRaises(RequestTimeout): self.dendrite.get('test/get')
def test_get_from_cb(self): get_result = [] dummy = str(uuid4()) def cb(data): self.dendrite.publish('test/get', dummy, retain=True) get_result.append(self.dendrite.get('test/get')) return 'Test OK: ' + data service = 'test/fct' self.dendrite.provide('test/fct', cb) params = str(uuid4()) call_result = self.dendrite.call(service, params, timeout=5) self.assertEqual(call_result, 'Test OK: ' + params) self.assertEqual(get_result[0], dummy) Dendrite.publish_single('test/get', retain=True)
def notify(self): data = { 'type': self.type, 'source': self.source, 'level': self.level, 'timestamp': datetime.datetime.utcfromtimestamp(self.timestamp).strftime('%Y-%m-%dT%H:%M:%SZ'), 'data': self.data, } if self.dendrite is None: return Dendrite.publish_single(self.EVENT_TOPIC, data) else: return self.dendrite.publish(self.EVENT_TOPIC, data)