I now understand about the necessity to add the event early. I have overlooked that completely. Your advice got me thinking and it turns out on top of all things i was not setting up the listeners correctly. About the event raising, it seems i did not do as you suggested. I got a bit confused and for no reason i thought that registering the component on core also meant i had to raise the event from the core (later i found out that core.openflow was an instance of OF Nexus which was exactly the way you said i should avoid). I followed your advice properly, and now my component source its own events,. In retrospect, it was simpler than i thought and it works nicely as well.

Thank you again for all your efforts


On 10/11/2014 1:49 πμ, Murphy McCauley wrote:
You want to add the event to the _eventMixin_events set early. Very early. Like when your module loads, probably even before launch() gets called. This is because when someone does a listenTo() or addListeners() (which are pretty much equivalent except that the former is deprecated and not mentioned anywhere in the manual), it's via the _eventMixin_events that it knows which events to listen to. So if you haven't added the event to the set by then... the listener for it won't get set. As it is, you're adding it right before you are raising it, which pretty much ensures that nobody is listening.

(This may be another argument for using your own component to source your own events rather than trying to use core or the OpenFlow nexus or whatever.)

-- Murphy

On Nov 8, 2014, at 10:35 AM, Adam Pavlidis <adampavli...@gmail.com <mailto:adampavli...@gmail.com>> wrote:

I added the necessary arguments in the definition of the Event and it worked. Thank you very much!

About the way the events are raised, i am trying to find another solution that doesn't involve the use of of_01. I only used this approach because out of
the many solutions i tried, only this one worked.

I looked up a bit and i noticed that the GoingUp Event in core.py is
raised like this:"core.raiseEvent(GoingUp/*() */) "

So at first i thought that i found the mistake i made in my previous attempts
and did some tweaking in the _handle_PacketIn of the l2_learning module:

"core._eventMixin_events.add(CustomEvent)"
"core.raiseEvent(CustomEvent(event.connection, msg))"

Nothing happened. However if i delete the first command i get an error
saying what i expected, that i haven't add the CustomEvent to the event set.

Also if i add the command "core.raiseEvent(CustomEvent(msg))"
i get another error saying as expected that __init__() expects 3 arguments.
If i provide the arguments needed like i did before nothing happens.

The commands core.raiseEvent(CustomEvent) and/or core.raiseEvent(CustomEvent, msg) don't work without raising any errors. If i replace with core.raiseEvent(CustomEvent()) a TypeError is raised as i said above.

This is a skeleton of my component:

CustomModule.py:

class CustomModule (EventMixin):

  def __init__ (self):
    self.listenTo(core.openflow)
    log.debug("...Enabling Custom Module...")

  def _handle_CustomEvent (self, event):
    log.debug(‘Event was raised!!!’)

  def _handle_FlowRemoved (self, event):
    log.debug('Flow Removed from switch: %s', event.connection)
    self._eventMixin_events = set([SpamSpam,])
    self.raiseEvent(SpamSpam(event.connection, event.ofp))

def launch ():
  '''
  Starting the module
  '''
  core.registerNew(CustomModule)

I tried raising the event, when a flow is removed. Nothing happens this way either.

I don't know if am missing something obvious or if i should try anything else. In any case, thanks again for all your help so far, i really appreciate it.

On Thu, Nov 6, 2014 at 12:30 AM, Murphy McCauley <murphy.mccau...@gmail.com <mailto:murphy.mccau...@gmail.com>> wrote:


    On Nov 5, 2014, at 2:48 AM, Adam Pavlidis <adampavli...@gmail.com
    <mailto:adampavli...@gmail.com>> wrote:

    I also found it strange that i get no error message whatsoever.
    I was always running POX with --verbose plus log.level —DEBUG,
    and i did not use .raiseEventNoErrors() method.

    I haven't really given much thought on how i want the events to be
    raised, i experimented a little in order to find a way that works.

    Adding the CustomEvent, in the _eventMixin set of OpenFlowNexus and
    did the trick.

    In the end it doesn’t really matter for me which way the event
    is raised.
    I have a module, with 2 distinct functions.

     1. Flow removal that is called automatically
     2. Flow insertion that has to be manually called everywhere a
        new flow is added.

    I used the same logic as FlowRemoved, PacketIn e.t.c.
    events/handlers,
    so i added the following lines in of_01.py

        def handle_CUSTOM_EVENT (con, msg): #A
          e = con.ofnexus.raiseEvent(
        CustomEvent, con, msg)
          if e is None or e.halt != True:
        con.raiseEvent(CustomEvent, con, msg)


    and in order to call the above (e.g. l2_learning):

        of_01.handle_CUSTOM_EVENT(event.connection, msg)


    The above doesn't work unless i delete the arguments in
    handle_CUSTOM_EVENT().
    Traceback is:

          File "/home/mininet/pox/pox/lib/revent/revent.py", line
        234, in
        raiseEventNoErrors

            return self.raiseEvent(event, *args, **kw)

          File "/home/mininet/pox/pox/lib/revent/revent.py", line
        281, in raiseEvent

            rv = event._invoke(handler, *args, **kw)

          File "/home/mininet/pox/pox/lib/revent/revent.py", line
        159, in _invoke

            return handler(self, *args, **kw)

          File "/home/mininet/pox/pox/forwarding/l2_learning.py",
        line 182, in
        _handle_PacketIn

        of_01.handle_CUSTOM_EVENT(event.connection, msg)

          File "/home/mininet/pox/pox/openflow/of_01.py", line 68, in
        handle_CUSTOM_EVENT

            e = con.ofnexus.raiseEvent(CustomEvent, con, msg)

          File "/home/mininet/pox/pox/lib/revent/revent.py", line
        265, in raiseEvent

            event = eventType(*args, **kw)

        TypeError: __init__() takes exactly 1 argument (3 given)



    From what i understand raiseEvent method expects 1 argument but
    receives 3. I don't understand however why
    handle_PACKET_IN/FLOW_REMOVED
    get to .raiseEventNoErrors the exact same way, and no TypeError
    occurs.

    Not quite.  What it's actually talking about here is the
    constructor for the event class itself.  In your case, I am
    guessing your CustomEvent.__init__() just took self. You'll want
    to add additional parameters. As you say below, you want the
    match, so you'd pass that into your event object's constructor.

    Something to keep in mind:
    foo.raiseEvent(BarEvent, spam, eggs)
    .. is more or less the same as...
    new_event = BarEvent(spam, eggs)
    foo.raiseEvent(new_event)

    The latter is perhaps a bit easier to understand, though.

    Truth is i don't need the connection part, but is necessary for my
    module that the msg.match object representing the flow that is
    installed is
    passed to the handler.

        def _handle_CustomEvent(self, msg):


    I don’t know if what i did is conceptually correct or if there is a
    cleaner way (programming-wise). I just thought that using a separate
    module instead of hard-coding the actions i need executed was
    better,
    considering i will also be able to pass some arguments from the
    CLI to
    the module less painfully, e.g. misc.CustomModule
    --<server>_<hostname>.

    I would greatly appreciate your opinion on this.

    If there's no compelling reason, I think you shouldn't mess with
of_01/openflow at all. Keep your events within your own module. Have your component register itself on core, and raise your two
    new event types on your component instead of on the OpenFlowNexus
    or Connection.  Other components can listen there.

    Thanks for all your help so far,
    Adam Pavlidis

    On Tue, Nov 4, 2014 at 12:42 AM, Murphy McCauley
    <murphy.mccau...@gmail.com <mailto:murphy.mccau...@gmail.com>>
    wrote:

        I'm a bit surprised that you're getting no result at all as
        opposed to, say, exceptions in the POX log.  Have you tried
        turning logging to DEBUG level and reading through to make
sure there are no hints as to what might be going wrong? It's possible that raiseEventNoErrors() is masking the
        exceptions.  You might try at least temporarily replacing
        such calls with just plain raiseEvent().

        It looks like you want these events to be raised using the
        same sources as normal OpenFlow events.  Normally, sources
        need to be aware of the events they'll be raising.  In your
        case, these sources are the Connection (in of_01) and
        OpenFlowNexus (in openflow/__init__) classes.  Have you
        added your event to their set of _eventMixin_events?

        On Nov 3, 2014, at 2:15 AM, Adam Pavlidis
        <adampavli...@gmail.com <mailto:adampavli...@gmail.com>> wrote:

        > Hello,
        >
        > i am trying to implement a controller module that handles
        two types of Events:
        > the already existing FlowRemoved and another of my own
        creation
        > "CustomEvent" that i will execute in various circumstances.
        >
        > I have read the section on custom events contained in the
        POX manual
        > (
        
https://openflow.stanford.edu/display/ONL/POX+Wiki#POXWiki-TheEventSystem%3Apox.lib.revent
        > )
        > and have successfully executed the examples.
        >
        > I have looked up a bit how the POX raises events such as
        PacketIn.
        > I added the following lines of code in
        pox/pox/openflow/__init__.py
        >
        > class CustomEvent(Event):
        >  """
        >  Our own custom event
        >  """
        >  def __init__(self):
        >    Event.__init__(self)
        >
        > Then i added a handler for that event in an already
        existing controller module,
        >
        > def _handle_CustomEvent (self, event):
        >  log.debug('The Event was raised successfully')
        >
        > However when i manually raise the above event,
        > (e.g. during the handling of a PacketIn event in
        > forwarding.l2_learning) nothing happens.
        > I used both the method explained in the manual (creating a
        subclass of
        > EventMixin with _eventMixin_set=([CustomEvent], creating
        an instance
        > of that class and raising the event on that instance), and the
        > core.raiselater method.
        >
        > Important note: In the same module there is a handler for
        FlowRemoved
        > Events, that is notified without issues, when a flow is
        removed from the
        > switch, so i don't think there is a listener issue.
        >
        > In my efforts to find the problem i tried to experiment in
        > openflow/of_01.py and specifically in lines 85, 177 where
        FlowRemoved
        > and PacketIn events are raised from the Controller, i
        tried to force
        > raise my own
        > event when a PacketIn was supposed to be raised.
        >
        > def handle_PACKET_IN (con, msg): #A
        >  e = con.ofnexus.raiseEventNoErrors(CustomEvent, con, msg)
        >  if e is None or e.halt != True:
        > con.raiseEventNoErrors(CustomEvent, con, msg)
        >
        > Nothing happened either (apart from losing connectivity
        between the hosts).
        >
        > I would appreciate any help,
        > Adam Pavlidis






Reply via email to