Twisted support implemented

pull/45/head
elie 2009-07-31 19:55:03 +00:00
parent 55cc044afc
commit ac02c7feb4
9 changed files with 178 additions and 0 deletions

View File

@ -22,6 +22,7 @@ Ivan Zderadicka
Randy Couey
Brian Kyckelhahn
Mark M Evans
Filippo Giunchedi at Truelite Srl
Thanks to Python Software Foundation for granting financial support
for the project.

View File

@ -0,0 +1,26 @@
#
# Copyright (C) 2008 Truelite Srl <info@truelite.it>
# Author: Filippo Giunchedi <filippo@truelite.it>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2
# as published by the Free Software Foundation
#
# Description: twisted DatagramProtocol UDP transport
#
class AbstractTwistedTransport:
"""Base Twisted Transport, to be used with TwistedDispatcher"""
def __init__(self):
self._writeQ = []
# AbstractTwistedTransport API
def registerCbFun(self, cbFun):
self._cbFun = cbFun
def unregisterCbFun(self):
self._cbFun = None
def closeTransport(self):
self.unregisterCbFun()

View File

@ -0,0 +1,44 @@
"""Implements twisted-based generic DGRAM transport"""
from time import time
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
from pysnmp.carrier.twisted.base import AbstractTwistedTransport
from pysnmp.carrier import error
from pysnmp import debug
class DgramTwistedTransport(DatagramProtocol, AbstractTwistedTransport):
"""Base Twisted datagram Transport, to be used with TwistedDispatcher"""
# Twisted Datagram API
def datagramReceived(self, datagram, address):
if self._cbFun is None:
raise error.CarrierError('Unable to call cbFun')
else:
# Callback fun is called through callLater() in attempt
# to make Twisted timed calls work under high load.
reactor.callLater(0, self._cbFun, self, address, datagram)
def startProtocol(self):
debug.logger & debug.flagIO and debug.logger('startProtocol: invoked')
while self._writeQ:
outgoingMessage, transportAddress = self._writeQ.pop(0)
debug.logger & debug.flagIO and debug.logger('startProtocol: transportAddress %s outgoingMessage %s' % (transportAddress, repr(outgoingMessage)))
try:
self.transport.write(outgoingMessage, transportAddress)
except Exception, why:
raise error.CarrierError('Twisted exception: %s' % (why,))
def stopProtocol(self):
debug.logger & debug.flagIO and debug.logger('stopProtocol: invoked')
self.closeTransport()
def sendMessage(self, outgoingMessage, transportAddress):
debug.logger & debug.flagIO and debug.logger('startProtocol: %s transportAddress %s outgoingMessage %s' % ((self.transport is None and "queuing" or "sending"), transportAddress, repr(outgoingMessage)))
if self.transport is None:
self._writeQ.append((outgoingMessage, transportAddress))
else:
try:
self.transport.write(outgoingMessage, transportAddress)
except Exception, why:
raise error.CarrierError('Twisted exception: %s' % (why,))

View File

@ -0,0 +1,25 @@
"""Implements twisted-based UDP transport"""
from twisted.internet import reactor
from pysnmp.carrier.twisted.dgram.base import DgramTwistedTransport
from pysnmp.carrier import error
domainName = snmpUDPDomain = (1, 3, 6, 1, 6, 1, 1)
class UdpTwistedTransport(DgramTwistedTransport):
# AbstractTwistedTransport API
def openClientMode(self, iface=''):
try:
self._lport = reactor.listenUDP(0, self, iface)
except Exception, why:
raise error.CarrierError(why)
return self
def openServerMode(self, iface=None):
try:
self._lport = reactor.listenUDP(iface[1], self, iface[0])
except Exception, why:
raise error.CarrierError(why)
return self
UdpTransport = UdpTwistedTransport

View File

@ -0,0 +1,26 @@
"""Implements twisted-based UNIX domain socket transport"""
from twisted.internet import reactor
from pysnmp.carrier.twisted.dgram.base import DgramTwistedTransport
from pysnmp.carrier import error
domainName = snmpLocalDomain = (1, 3, 6, 1, 2, 1, 100, 1, 13)
class UnixTwistedTransport(DgramTwistedTransport):
# AbstractTwistedTransport API
def openClientMode(self, iface=''):
try:
self._lport = reactor.connectUNIXDatagram(iface, self)
except Exception, why:
raise error.CarrierError(why)
return self
def openServerMode(self, iface=None):
try:
self._lport = reactor.listenUNIXDatagram(iface, self)
except Exception, why:
raise error.CarrierError(why)
return self
UnixTransport = UnixTwistedTransport

View File

@ -0,0 +1,53 @@
#
# Copyright (C) 2008 Truelite Srl <info@truelite.it>
# Author: Filippo Giunchedi <filippo@truelite.it>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2
# as published by the Free Software Foundation
#
# Description: Transport dispatcher based on twisted.internet.reactor
#
from time import time
from twisted.internet import reactor, task
from pysnmp.carrier.base import AbstractTransportDispatcher
from pysnmp.carrier import error
class TwistedDispatcher(AbstractTransportDispatcher):
"""TransportDispatcher based on twisted.internet.reactor"""
def __init__(self, *args, **kwargs):
AbstractTransportDispatcher.__init__(self)
self.__transportCount = 0
self.timeout = kwargs.get('timeout', 1.0)
self.loopingcall = task.LoopingCall(self.handleTimeout)
def handleTimeout(self):
self.handleTimerTick(time())
def runDispatcher(self, timeout=0.0):
if not reactor.running:
try:
reactor.run()
except Exception, why:
raise error.CarrierError(why)
# jobstarted/jobfinished might be okay as-is
def registerTransport(self, tDomain, transport):
if not self.loopingcall.running and self.timeout > 0:
self.loopingcall.start(self.timeout, now = False)
AbstractTransportDispatcher.registerTransport(
self, tDomain, transport
)
self.__transportCount = self.__transportCount + 1
def unregisterTransport(self, tDomain):
t = AbstractTransportDispatcher.getTransport(self, tDomain)
if t is not None:
AbstractTransportDispatcher.unregisterTransport(self, tDomain)
t.closeTransport()
self.__transportCount = self.__transportCount - 1
# The last transport has been removed, stop the timeout
if self.__transportCount > 0 and self.loopingcall.running:
self.loopingcall.stop()

View File

@ -15,9 +15,12 @@ setup(name="pysnmp",
'pysnmp.v4.carrier',
'pysnmp.v4.carrier.asynsock',
'pysnmp.v4.carrier.asynsock.dgram',
'pysnmp.v4.carrier.twisted',
'pysnmp.v4.carrier.twisted.dgram',
'pysnmp.v4.entity',
'pysnmp.v4.entity.rfc3413',
'pysnmp.v4.entity.rfc3413.oneliner',
'pysnmp.v4.entity.rfc3413.twisted',
'pysnmp.v4.proto',
'pysnmp.v4.proto.mpmod',
'pysnmp.v4.proto.secmod',