Change in python/osmo-python-tests[master]: Move Trap class back to separate files

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Max gerrit-no-reply at lists.osmocom.org
Tue Nov 27 19:54:22 UTC 2018


Max has submitted this change and it was merged. ( https://gerrit.osmocom.org/11952 )

Change subject: Move Trap class back to separate files
......................................................................

Move Trap class back to separate files

After further testing it turns out that Trap() have too many
implementation details which makes it cumbersome to be shared. Instead,
it's easier to make it into wrapper over shared functions.

Change-Id: I8a3c62bcdf4286f8127c5b6d8dee6d740aca23b9
---
M scripts/ctrl2cgi.py
M scripts/soap.py
2 files changed, 114 insertions(+), 15 deletions(-)

Approvals:
  Jenkins Builder: Verified
  Pau Espin Pedrol: Looks good to me, approved



diff --git a/scripts/ctrl2cgi.py b/scripts/ctrl2cgi.py
index 18cfdbe..843aeb9 100755
--- a/scripts/ctrl2cgi.py
+++ b/scripts/ctrl2cgi.py
@@ -22,14 +22,14 @@
  */
 """
 
-__version__ = "0.0.1" # bump this on every non-trivial change
+__version__ = "0.0.2" # bump this on every non-trivial change
 
 from twisted.internet import defer, reactor
 from osmopy.twisted_ipa import CTRL, IPAFactory, __version__ as twisted_ipa_version
 from osmopy.osmo_ipa import Ctrl
 from treq import post, collect
 from functools import partial
-from osmopy.trap_helper import Trap, reloader, debug_init
+from osmopy.trap_helper import reloader, debug_init, get_type, get_r, p_h, make_params
 from distutils.version import StrictVersion as V # FIXME: use NormalizedVersion from PEP-386 when available
 import argparse, datetime, signal, sys, os, logging, logging.handlers
 import hashlib
@@ -75,6 +75,61 @@
     #print('HASH: \nparams="%r"\ninput="%s" \nres="%s"' %(params, input, res))
     return res
 
+class Trap(CTRL):
+    """
+    TRAP handler (agnostic to factory's client object)
+    """
+    def ctrl_TRAP(self, data, op_id, v):
+        """
+        Parse CTRL TRAP and dispatch to appropriate handler after normalization
+        """
+        self.factory.log.debug('TRAP %s' % v)
+        t_type = get_type(v)
+        p = p_h(v)
+        method = getattr(self, 'handle_' + t_type.replace('-', ''), lambda *_: "Unhandled %s trap" % t_type)
+        method(p(1), p(3), p(5), p(7), get_r(v))
+
+    def ctrl_SET_REPLY(self, data, _, v):
+        """
+        Debug log for replies to our commands
+        """
+        self.factory.log.debug('SET REPLY %s' % v)
+
+    def ctrl_ERROR(self, data, op_id, v):
+        """
+        We want to know if smth went wrong
+        """
+        self.factory.log.debug('CTRL ERROR [%s] %s' % (op_id, v))
+
+    def connectionMade(self):
+        """
+        Logging wrapper, calling super() is necessary not to break reconnection logic
+        """
+        self.factory.log.info("Connected to CTRL@%s:%d" % (self.factory.host, self.factory.port))
+        super(CTRL, self).connectionMade()
+
+    @defer.inlineCallbacks
+    def handle_locationstate(self, net, bsc, bts, trx, data):
+        """
+        Handle location-state TRAP: parse trap content, build CGI Request and use treq's routines to post it while setting up async handlers
+        """
+        params = make_params(bsc, data)
+        self.factory.log.debug('location-state@%s.%s.%s.%s (%s) => %s' % (net, bsc, bts, trx, params['time_stamp'], data))
+        params['h'] = gen_hash(params, self.factory.secret_key)
+        d = post(self.factory.location, None, params=params)
+        d.addCallback(partial(handle_reply, self.transport.write, self.factory.log)) # treq's collect helper is handy to get all reply content at once using closure on ctx
+        d.addErrback(lambda e, bsc: self.factory.log.critical("HTTP POST error %s while trying to register BSC %s on %s" % (e, bsc, self.factory.location)), bsc) # handle HTTP errors
+        # Ensure that we run only limited number of requests in parallel:
+        yield self.factory.semaphore.acquire()
+        yield d # we end up here only if semaphore is available which means it's ok to fire the request without exceeding the limit
+        self.factory.semaphore.release()
+
+    def handle_notificationrejectionv1(self, net, bsc, bts, trx, data):
+        """
+        Handle notification-rejection-v1 TRAP: just an example to show how more message types can be handled
+        """
+        self.factory.log.debug('notification-rejection-v1 at bsc-id %s => %s' % (bsc, data))
+
 
 class TrapFactory(IPAFactory):
     """
@@ -100,12 +155,6 @@
         self.log.setLevel(level)
         self.log.debug("Using IPA %s, CGI server: %s" % (Ctrl.version, self.location))
 
-    def prepare_params(bsc, lon, lat, fix, tstamp, oper, admin, policy):
-        params = {'bsc_id': bsc, 'lon': lon, 'lat': lat, 'position_validity': fix, 'time_stamp': tstamp, 'oper_status': oper, 'admin_status': admin, 'policy_status': policy }
-        params['h'] = gen_hash(params, self.factory.secret_key)
-        d = post(self.factory.location, None, params=params)
-        d.addCallback(partial(handle_reply, self.transport.write, self.factory.log))
-        return d
 
 if __name__ == '__main__':
     p = argparse.ArgumentParser(description='Proxy between given GCI service and Osmocom CTRL protocol.')
diff --git a/scripts/soap.py b/scripts/soap.py
index 156157c..75acd89 100755
--- a/scripts/soap.py
+++ b/scripts/soap.py
@@ -30,7 +30,7 @@
 from treq import post, collect
 from suds.client import Client
 from functools import partial
-from osmopy.trap_helper import Trap, reloader, debug_init
+from osmopy.trap_helper import reloader, debug_init, get_type, get_r, p_h, make_params
 from distutils.version import StrictVersion as V # FIXME: use NormalizedVersion from PEP-386 when available
 import argparse, datetime, signal, sys, os, logging, logging.handlers
 
@@ -51,6 +51,62 @@
         f(m)
 
 
+class Trap(CTRL):
+    """
+    TRAP handler (agnostic to factory's client object)
+    """
+    def ctrl_TRAP(self, data, op_id, v):
+        """
+        Parse CTRL TRAP and dispatch to appropriate handler after normalization
+        """
+        self.factory.log.debug('TRAP %s' % v)
+        t_type = get_type(v)
+        p = p_h(v)
+        method = getattr(self, 'handle_' + t_type.replace('-', ''), lambda *_: "Unhandled %s trap" % t_type)
+        method(p(1), p(3), p(5), p(7), get_r(v))
+
+    def ctrl_SET_REPLY(self, data, _, v):
+        """
+        Debug log for replies to our commands
+        """
+        self.factory.log.debug('SET REPLY %s' % v)
+
+    def ctrl_ERROR(self, data, op_id, v):
+        """
+        We want to know if smth went wrong
+        """
+        self.factory.log.debug('CTRL ERROR [%s] %s' % (op_id, v))
+
+    def connectionMade(self):
+        """
+        Logging wrapper, calling super() is necessary not to break reconnection logic
+        """
+        self.factory.log.info("Connected to CTRL@%s:%d" % (self.factory.host, self.factory.port))
+        super(CTRL, self).connectionMade()
+
+    @defer.inlineCallbacks
+    def handle_locationstate(self, net, bsc, bts, trx, data):
+        """
+        Handle location-state TRAP: parse trap content, build SOAP context and use treq's routines to post it while setting up async handlers
+        """
+        params = make_params(bsc, data)
+        self.factory.log.debug('location-state@%s.%s.%s.%s (%s) => %s' % (net, bsc, bts, trx, params['time_stamp'], data))
+        ctx = self.factory.client.registerSiteLocation(bsc, float(params['lon']), float(params['lat']), params['position_validity'], params['time_stamp'], params['oper_status'], params['admin_status'], params['policy_status'])
+        d = post(self.factory.location, ctx.envelope)
+        d.addCallback(collect, partial(handle_reply, ctx.process_reply, self.transport.write, self.factory.log)) # treq's collect helper is handy to get all reply content at once using closure on ctx
+        d.addErrback(lambda e, bsc: self.factory.log.critical("HTTP POST error %s while trying to register BSC %s on %s" % (e, bsc, self.factory.location)), bsc) # handle HTTP errors
+        # Ensure that we run only limited number of requests in parallel:
+        yield self.factory.semaphore.acquire()
+        yield d # we end up here only if semaphore is available which means it's ok to fire the request without exceeding the limit
+        self.factory.semaphore.release()
+
+    def handle_notificationrejectionv1(self, net, bsc, bts, trx, data):
+        """
+        Handle notification-rejection-v1 TRAP: just an example to show how more message types can be handled
+        """
+        self.factory.log.debug('notification-rejection-v1 at bsc-id %s => %s' % (bsc, data))
+
+
 class TrapFactory(IPAFactory):
     """
     Store SOAP client object so TRAP handler can use it for requests
@@ -75,12 +131,6 @@
         self.log.setLevel(level)
         self.log.debug("Using IPA %s, SUDS client: %s" % (Ctrl.version, soap))
 
-    def prepare_params(bsc, lon, lat, fix, tstamp, oper, admin, policy):
-        ctx = self.factory.client.registerSiteLocation(bsc, float(lon), float(lat), fix, tstamp, oper, admin, policy)
-        d = post(self.factory.location, ctx.envelope)
-         # treq's collect helper is handy to get all reply content at once using closure on ctx:
-        d.addCallback(collect, partial(handle_reply, ctx.process_reply, self.transport.write, self.factory.log))
-        return d
 
 if __name__ == '__main__':
     p = argparse.ArgumentParser(description='Proxy between given SOAP service and Osmocom CTRL protocol.')

-- 
To view, visit https://gerrit.osmocom.org/11952
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: python/osmo-python-tests
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I8a3c62bcdf4286f8127c5b6d8dee6d740aca23b9
Gerrit-Change-Number: 11952
Gerrit-PatchSet: 2
Gerrit-Owner: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder (1000002)
Gerrit-Reviewer: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: Pau Espin Pedrol <pespin at sysmocom.de>
Gerrit-Reviewer: daniel <dwillmann at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20181127/b2ce0413/attachment.htm>


More information about the gerrit-log mailing list